summaryrefslogtreecommitdiff
path: root/chart.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2020-05-22 16:53:46 +0800
committerGitHub <noreply@github.com>2020-05-22 16:53:46 +0800
commitec14de32f0c06f7a26b6b79578f666c0cc50b72c (patch)
treec6ebd61a7d9a7da5b993ffb82e4fb6c036e75d6a /chart.go
parentaa7eadbffe6ae2f9f86201bbaaa4c1d1e8829cae (diff)
parent2efc7107ff30dc7f1e1a798082616ee488f99489 (diff)
Merge branch 'master' into fix/cell_lock
Diffstat (limited to 'chart.go')
-rw-r--r--chart.go1688
1 files changed, 627 insertions, 1061 deletions
diff --git a/chart.go b/chart.go
index d669a47..8fa0b5d 100644
--- a/chart.go
+++ b/chart.go
@@ -1,159 +1,255 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excelâ„¢ 2007 and later. Support save file without losing original
-// charts of XLSX. This library needs Go version 1.8 or later.
+// charts of XLSX. This library needs Go version 1.10 or later.
package excelize
import (
"encoding/json"
"encoding/xml"
+ "errors"
+ "fmt"
"strconv"
"strings"
)
// This section defines the currently supported chart types.
const (
- Area = "area"
- AreaStacked = "areaStacked"
- AreaPercentStacked = "areaPercentStacked"
- Area3D = "area3D"
- Area3DStacked = "area3DStacked"
- Area3DPercentStacked = "area3DPercentStacked"
- Bar = "bar"
- BarStacked = "barStacked"
- BarPercentStacked = "barPercentStacked"
- Bar3DClustered = "bar3DClustered"
- Bar3DStacked = "bar3DStacked"
- Bar3DPercentStacked = "bar3DPercentStacked"
- Col = "col"
- ColStacked = "colStacked"
- ColPercentStacked = "colPercentStacked"
- Col3DClustered = "col3DClustered"
- Col3D = "col3D"
- Col3DStacked = "col3DStacked"
- Col3DPercentStacked = "col3DPercentStacked"
- Doughnut = "doughnut"
- Line = "line"
- Pie = "pie"
- Pie3D = "pie3D"
- Radar = "radar"
- Scatter = "scatter"
+ Area = "area"
+ AreaStacked = "areaStacked"
+ AreaPercentStacked = "areaPercentStacked"
+ Area3D = "area3D"
+ Area3DStacked = "area3DStacked"
+ Area3DPercentStacked = "area3DPercentStacked"
+ Bar = "bar"
+ BarStacked = "barStacked"
+ BarPercentStacked = "barPercentStacked"
+ Bar3DClustered = "bar3DClustered"
+ Bar3DStacked = "bar3DStacked"
+ Bar3DPercentStacked = "bar3DPercentStacked"
+ Bar3DConeClustered = "bar3DConeClustered"
+ Bar3DConeStacked = "bar3DConeStacked"
+ Bar3DConePercentStacked = "bar3DConePercentStacked"
+ Bar3DPyramidClustered = "bar3DPyramidClustered"
+ Bar3DPyramidStacked = "bar3DPyramidStacked"
+ Bar3DPyramidPercentStacked = "bar3DPyramidPercentStacked"
+ Bar3DCylinderClustered = "bar3DCylinderClustered"
+ Bar3DCylinderStacked = "bar3DCylinderStacked"
+ Bar3DCylinderPercentStacked = "bar3DCylinderPercentStacked"
+ Col = "col"
+ ColStacked = "colStacked"
+ ColPercentStacked = "colPercentStacked"
+ Col3D = "col3D"
+ Col3DClustered = "col3DClustered"
+ Col3DStacked = "col3DStacked"
+ Col3DPercentStacked = "col3DPercentStacked"
+ Col3DCone = "col3DCone"
+ Col3DConeClustered = "col3DConeClustered"
+ Col3DConeStacked = "col3DConeStacked"
+ Col3DConePercentStacked = "col3DConePercentStacked"
+ Col3DPyramid = "col3DPyramid"
+ Col3DPyramidClustered = "col3DPyramidClustered"
+ Col3DPyramidStacked = "col3DPyramidStacked"
+ Col3DPyramidPercentStacked = "col3DPyramidPercentStacked"
+ Col3DCylinder = "col3DCylinder"
+ Col3DCylinderClustered = "col3DCylinderClustered"
+ Col3DCylinderStacked = "col3DCylinderStacked"
+ Col3DCylinderPercentStacked = "col3DCylinderPercentStacked"
+ Doughnut = "doughnut"
+ Line = "line"
+ Pie = "pie"
+ Pie3D = "pie3D"
+ PieOfPieChart = "pieOfPie"
+ BarOfPieChart = "barOfPie"
+ Radar = "radar"
+ Scatter = "scatter"
+ Surface3D = "surface3D"
+ WireframeSurface3D = "wireframeSurface3D"
+ Contour = "contour"
+ WireframeContour = "wireframeContour"
+ Bubble = "bubble"
+ Bubble3D = "bubble3D"
)
// This section defines the default value of chart properties.
var (
chartView3DRotX = map[string]int{
- Area: 0,
- AreaStacked: 0,
- AreaPercentStacked: 0,
- Area3D: 15,
- Area3DStacked: 15,
- Area3DPercentStacked: 15,
- Bar: 0,
- BarStacked: 0,
- BarPercentStacked: 0,
- Bar3DClustered: 15,
- Bar3DStacked: 15,
- Bar3DPercentStacked: 15,
- Col: 0,
- ColStacked: 0,
- ColPercentStacked: 0,
- Col3DClustered: 15,
- Col3D: 15,
- Col3DStacked: 15,
- Col3DPercentStacked: 15,
- Doughnut: 0,
- Line: 0,
- Pie: 0,
- Pie3D: 30,
- Radar: 0,
- Scatter: 0,
+ Area: 0,
+ AreaStacked: 0,
+ AreaPercentStacked: 0,
+ Area3D: 15,
+ Area3DStacked: 15,
+ Area3DPercentStacked: 15,
+ Bar: 0,
+ BarStacked: 0,
+ BarPercentStacked: 0,
+ Bar3DClustered: 15,
+ Bar3DStacked: 15,
+ Bar3DPercentStacked: 15,
+ Bar3DConeClustered: 15,
+ Bar3DConeStacked: 15,
+ Bar3DConePercentStacked: 15,
+ Bar3DPyramidClustered: 15,
+ Bar3DPyramidStacked: 15,
+ Bar3DPyramidPercentStacked: 15,
+ Bar3DCylinderClustered: 15,
+ Bar3DCylinderStacked: 15,
+ Bar3DCylinderPercentStacked: 15,
+ Col: 0,
+ ColStacked: 0,
+ ColPercentStacked: 0,
+ Col3D: 15,
+ Col3DClustered: 15,
+ Col3DStacked: 15,
+ Col3DPercentStacked: 15,
+ Col3DCone: 15,
+ Col3DConeClustered: 15,
+ Col3DConeStacked: 15,
+ Col3DConePercentStacked: 15,
+ Col3DPyramid: 15,
+ Col3DPyramidClustered: 15,
+ Col3DPyramidStacked: 15,
+ Col3DPyramidPercentStacked: 15,
+ Col3DCylinder: 15,
+ Col3DCylinderClustered: 15,
+ Col3DCylinderStacked: 15,
+ Col3DCylinderPercentStacked: 15,
+ Doughnut: 0,
+ Line: 0,
+ Pie: 0,
+ Pie3D: 30,
+ PieOfPieChart: 0,
+ BarOfPieChart: 0,
+ Radar: 0,
+ Scatter: 0,
+ Surface3D: 15,
+ WireframeSurface3D: 15,
+ Contour: 90,
+ WireframeContour: 90,
}
chartView3DRotY = map[string]int{
- Area: 0,
- AreaStacked: 0,
- AreaPercentStacked: 0,
- Area3D: 20,
- Area3DStacked: 20,
- Area3DPercentStacked: 20,
- Bar: 0,
- BarStacked: 0,
- BarPercentStacked: 0,
- Bar3DClustered: 20,
- Bar3DStacked: 20,
- Bar3DPercentStacked: 20,
- Col: 0,
- ColStacked: 0,
- ColPercentStacked: 0,
- Col3DClustered: 20,
- Col3D: 20,
- Col3DStacked: 20,
- Col3DPercentStacked: 20,
- Doughnut: 0,
- Line: 0,
- Pie: 0,
- Pie3D: 0,
- Radar: 0,
- Scatter: 0,
- }
- chartView3DDepthPercent = map[string]int{
- Area: 100,
- AreaStacked: 100,
- AreaPercentStacked: 100,
- Area3D: 100,
- Area3DStacked: 100,
- Area3DPercentStacked: 100,
- Bar: 100,
- BarStacked: 100,
- BarPercentStacked: 100,
- Bar3DClustered: 100,
- Bar3DStacked: 100,
- Bar3DPercentStacked: 100,
- Col: 100,
- ColStacked: 100,
- ColPercentStacked: 100,
- Col3DClustered: 100,
- Col3D: 100,
- Col3DStacked: 100,
- Col3DPercentStacked: 100,
- Doughnut: 100,
- Line: 100,
- Pie: 100,
- Pie3D: 100,
- Radar: 100,
- Scatter: 100,
+ Area: 0,
+ AreaStacked: 0,
+ AreaPercentStacked: 0,
+ Area3D: 20,
+ Area3DStacked: 20,
+ Area3DPercentStacked: 20,
+ Bar: 0,
+ BarStacked: 0,
+ BarPercentStacked: 0,
+ Bar3DClustered: 20,
+ Bar3DStacked: 20,
+ Bar3DPercentStacked: 20,
+ Bar3DConeClustered: 20,
+ Bar3DConeStacked: 20,
+ Bar3DConePercentStacked: 20,
+ Bar3DPyramidClustered: 20,
+ Bar3DPyramidStacked: 20,
+ Bar3DPyramidPercentStacked: 20,
+ Bar3DCylinderClustered: 20,
+ Bar3DCylinderStacked: 20,
+ Bar3DCylinderPercentStacked: 20,
+ Col: 0,
+ ColStacked: 0,
+ ColPercentStacked: 0,
+ Col3D: 20,
+ Col3DClustered: 20,
+ Col3DStacked: 20,
+ Col3DPercentStacked: 20,
+ Col3DCone: 20,
+ Col3DConeClustered: 20,
+ Col3DConeStacked: 20,
+ Col3DConePercentStacked: 20,
+ Col3DPyramid: 20,
+ Col3DPyramidClustered: 20,
+ Col3DPyramidStacked: 20,
+ Col3DPyramidPercentStacked: 20,
+ Col3DCylinder: 20,
+ Col3DCylinderClustered: 20,
+ Col3DCylinderStacked: 20,
+ Col3DCylinderPercentStacked: 20,
+ Doughnut: 0,
+ Line: 0,
+ Pie: 0,
+ Pie3D: 0,
+ PieOfPieChart: 0,
+ BarOfPieChart: 0,
+ Radar: 0,
+ Scatter: 0,
+ Surface3D: 20,
+ WireframeSurface3D: 20,
+ Contour: 0,
+ WireframeContour: 0,
+ }
+ plotAreaChartOverlap = map[string]int{
+ BarStacked: 100,
+ BarPercentStacked: 100,
+ ColStacked: 100,
+ ColPercentStacked: 100,
+ }
+ chartView3DPerspective = map[string]int{
+ Contour: 0,
+ WireframeContour: 0,
}
chartView3DRAngAx = map[string]int{
- Area: 0,
- AreaStacked: 0,
- AreaPercentStacked: 0,
- Area3D: 1,
- Area3DStacked: 1,
- Area3DPercentStacked: 1,
- Bar: 0,
- BarStacked: 0,
- BarPercentStacked: 0,
- Bar3DClustered: 1,
- Bar3DStacked: 1,
- Bar3DPercentStacked: 1,
- Col: 0,
- ColStacked: 0,
- ColPercentStacked: 0,
- Col3DClustered: 1,
- Col3D: 1,
- Col3DStacked: 1,
- Col3DPercentStacked: 1,
- Doughnut: 0,
- Line: 0,
- Pie: 0,
- Pie3D: 0,
- Radar: 0,
- Scatter: 0,
+ Area: 0,
+ AreaStacked: 0,
+ AreaPercentStacked: 0,
+ Area3D: 1,
+ Area3DStacked: 1,
+ Area3DPercentStacked: 1,
+ Bar: 0,
+ BarStacked: 0,
+ BarPercentStacked: 0,
+ Bar3DClustered: 1,
+ Bar3DStacked: 1,
+ Bar3DPercentStacked: 1,
+ Bar3DConeClustered: 1,
+ Bar3DConeStacked: 1,
+ Bar3DConePercentStacked: 1,
+ Bar3DPyramidClustered: 1,
+ Bar3DPyramidStacked: 1,
+ Bar3DPyramidPercentStacked: 1,
+ Bar3DCylinderClustered: 1,
+ Bar3DCylinderStacked: 1,
+ Bar3DCylinderPercentStacked: 1,
+ Col: 0,
+ ColStacked: 0,
+ ColPercentStacked: 0,
+ Col3D: 1,
+ Col3DClustered: 1,
+ Col3DStacked: 1,
+ Col3DPercentStacked: 1,
+ Col3DCone: 1,
+ Col3DConeClustered: 1,
+ Col3DConeStacked: 1,
+ Col3DConePercentStacked: 1,
+ Col3DPyramid: 1,
+ Col3DPyramidClustered: 1,
+ Col3DPyramidStacked: 1,
+ Col3DPyramidPercentStacked: 1,
+ Col3DCylinder: 1,
+ Col3DCylinderClustered: 1,
+ Col3DCylinderStacked: 1,
+ Col3DCylinderPercentStacked: 1,
+ Doughnut: 0,
+ Line: 0,
+ Pie: 0,
+ Pie3D: 0,
+ PieOfPieChart: 0,
+ BarOfPieChart: 0,
+ Radar: 0,
+ Scatter: 0,
+ Surface3D: 0,
+ WireframeSurface3D: 0,
+ Contour: 0,
+ Bubble: 0,
+ Bubble3D: 0,
}
chartLegendPosition = map[string]string{
"bottom": "b",
@@ -163,96 +259,196 @@ var (
"top_right": "tr",
}
chartValAxNumFmtFormatCode = map[string]string{
- Area: "General",
- AreaStacked: "General",
- AreaPercentStacked: "0%",
- Area3D: "General",
- Area3DStacked: "General",
- Area3DPercentStacked: "0%",
- Bar: "General",
- BarStacked: "General",
- BarPercentStacked: "0%",
- Bar3DClustered: "General",
- Bar3DStacked: "General",
- Bar3DPercentStacked: "0%",
- Col: "General",
- ColStacked: "General",
- ColPercentStacked: "0%",
- Col3DClustered: "General",
- Col3D: "General",
- Col3DStacked: "General",
- Col3DPercentStacked: "0%",
- Doughnut: "General",
- Line: "General",
- Pie: "General",
- Pie3D: "General",
- Radar: "General",
- Scatter: "General",
+ Area: "General",
+ AreaStacked: "General",
+ AreaPercentStacked: "0%",
+ Area3D: "General",
+ Area3DStacked: "General",
+ Area3DPercentStacked: "0%",
+ Bar: "General",
+ BarStacked: "General",
+ BarPercentStacked: "0%",
+ Bar3DClustered: "General",
+ Bar3DStacked: "General",
+ Bar3DPercentStacked: "0%",
+ Bar3DConeClustered: "General",
+ Bar3DConeStacked: "General",
+ Bar3DConePercentStacked: "0%",
+ Bar3DPyramidClustered: "General",
+ Bar3DPyramidStacked: "General",
+ Bar3DPyramidPercentStacked: "0%",
+ Bar3DCylinderClustered: "General",
+ Bar3DCylinderStacked: "General",
+ Bar3DCylinderPercentStacked: "0%",
+ Col: "General",
+ ColStacked: "General",
+ ColPercentStacked: "0%",
+ Col3D: "General",
+ Col3DClustered: "General",
+ Col3DStacked: "General",
+ Col3DPercentStacked: "0%",
+ Col3DCone: "General",
+ Col3DConeClustered: "General",
+ Col3DConeStacked: "General",
+ Col3DConePercentStacked: "0%",
+ Col3DPyramid: "General",
+ Col3DPyramidClustered: "General",
+ Col3DPyramidStacked: "General",
+ Col3DPyramidPercentStacked: "0%",
+ Col3DCylinder: "General",
+ Col3DCylinderClustered: "General",
+ Col3DCylinderStacked: "General",
+ Col3DCylinderPercentStacked: "0%",
+ Doughnut: "General",
+ Line: "General",
+ Pie: "General",
+ Pie3D: "General",
+ PieOfPieChart: "General",
+ BarOfPieChart: "General",
+ Radar: "General",
+ Scatter: "General",
+ Surface3D: "General",
+ WireframeSurface3D: "General",
+ Contour: "General",
+ WireframeContour: "General",
+ Bubble: "General",
+ Bubble3D: "General",
}
chartValAxCrossBetween = map[string]string{
- Area: "midCat",
- AreaStacked: "midCat",
- AreaPercentStacked: "midCat",
- Area3D: "midCat",
- Area3DStacked: "midCat",
- Area3DPercentStacked: "midCat",
- Bar: "between",
- BarStacked: "between",
- BarPercentStacked: "between",
- Bar3DClustered: "between",
- Bar3DStacked: "between",
- Bar3DPercentStacked: "between",
- Col: "between",
- ColStacked: "between",
- ColPercentStacked: "between",
- Col3DClustered: "between",
- Col3D: "between",
- Col3DStacked: "between",
- Col3DPercentStacked: "between",
- Doughnut: "between",
- Line: "between",
- Pie: "between",
- Pie3D: "between",
- Radar: "between",
- Scatter: "between",
+ Area: "midCat",
+ AreaStacked: "midCat",
+ AreaPercentStacked: "midCat",
+ Area3D: "midCat",
+ Area3DStacked: "midCat",
+ Area3DPercentStacked: "midCat",
+ Bar: "between",
+ BarStacked: "between",
+ BarPercentStacked: "between",
+ Bar3DClustered: "between",
+ Bar3DStacked: "between",
+ Bar3DPercentStacked: "between",
+ Bar3DConeClustered: "between",
+ Bar3DConeStacked: "between",
+ Bar3DConePercentStacked: "between",
+ Bar3DPyramidClustered: "between",
+ Bar3DPyramidStacked: "between",
+ Bar3DPyramidPercentStacked: "between",
+ Bar3DCylinderClustered: "between",
+ Bar3DCylinderStacked: "between",
+ Bar3DCylinderPercentStacked: "between",
+ Col: "between",
+ ColStacked: "between",
+ ColPercentStacked: "between",
+ Col3D: "between",
+ Col3DClustered: "between",
+ Col3DStacked: "between",
+ Col3DPercentStacked: "between",
+ Col3DCone: "between",
+ Col3DConeClustered: "between",
+ Col3DConeStacked: "between",
+ Col3DConePercentStacked: "between",
+ Col3DPyramid: "between",
+ Col3DPyramidClustered: "between",
+ Col3DPyramidStacked: "between",
+ Col3DPyramidPercentStacked: "between",
+ Col3DCylinder: "between",
+ Col3DCylinderClustered: "between",
+ Col3DCylinderStacked: "between",
+ Col3DCylinderPercentStacked: "between",
+ Doughnut: "between",
+ Line: "between",
+ Pie: "between",
+ Pie3D: "between",
+ PieOfPieChart: "between",
+ BarOfPieChart: "between",
+ Radar: "between",
+ Scatter: "between",
+ Surface3D: "midCat",
+ WireframeSurface3D: "midCat",
+ Contour: "midCat",
+ WireframeContour: "midCat",
+ Bubble: "midCat",
+ Bubble3D: "midCat",
}
plotAreaChartGrouping = map[string]string{
- Area: "standard",
- AreaStacked: "stacked",
- AreaPercentStacked: "percentStacked",
- Area3D: "standard",
- Area3DStacked: "stacked",
- Area3DPercentStacked: "percentStacked",
- Bar: "clustered",
- BarStacked: "stacked",
- BarPercentStacked: "percentStacked",
- Bar3DClustered: "clustered",
- Bar3DStacked: "stacked",
- Bar3DPercentStacked: "percentStacked",
- Col: "clustered",
- ColStacked: "stacked",
- ColPercentStacked: "percentStacked",
- Col3DClustered: "clustered",
- Col3D: "standard",
- Col3DStacked: "stacked",
- Col3DPercentStacked: "percentStacked",
- Line: "standard",
+ Area: "standard",
+ AreaStacked: "stacked",
+ AreaPercentStacked: "percentStacked",
+ Area3D: "standard",
+ Area3DStacked: "stacked",
+ Area3DPercentStacked: "percentStacked",
+ Bar: "clustered",
+ BarStacked: "stacked",
+ BarPercentStacked: "percentStacked",
+ Bar3DClustered: "clustered",
+ Bar3DStacked: "stacked",
+ Bar3DPercentStacked: "percentStacked",
+ Bar3DConeClustered: "clustered",
+ Bar3DConeStacked: "stacked",
+ Bar3DConePercentStacked: "percentStacked",
+ Bar3DPyramidClustered: "clustered",
+ Bar3DPyramidStacked: "stacked",
+ Bar3DPyramidPercentStacked: "percentStacked",
+ Bar3DCylinderClustered: "clustered",
+ Bar3DCylinderStacked: "stacked",
+ Bar3DCylinderPercentStacked: "percentStacked",
+ Col: "clustered",
+ ColStacked: "stacked",
+ ColPercentStacked: "percentStacked",
+ Col3D: "standard",
+ Col3DClustered: "clustered",
+ Col3DStacked: "stacked",
+ Col3DPercentStacked: "percentStacked",
+ Col3DCone: "standard",
+ Col3DConeClustered: "clustered",
+ Col3DConeStacked: "stacked",
+ Col3DConePercentStacked: "percentStacked",
+ Col3DPyramid: "standard",
+ Col3DPyramidClustered: "clustered",
+ Col3DPyramidStacked: "stacked",
+ Col3DPyramidPercentStacked: "percentStacked",
+ Col3DCylinder: "standard",
+ Col3DCylinderClustered: "clustered",
+ Col3DCylinderStacked: "stacked",
+ Col3DCylinderPercentStacked: "percentStacked",
+ Line: "standard",
}
plotAreaChartBarDir = map[string]string{
- Bar: "bar",
- BarStacked: "bar",
- BarPercentStacked: "bar",
- Bar3DClustered: "bar",
- Bar3DStacked: "bar",
- Bar3DPercentStacked: "bar",
- Col: "col",
- ColStacked: "col",
- ColPercentStacked: "col",
- Col3DClustered: "col",
- Col3D: "col",
- Col3DStacked: "col",
- Col3DPercentStacked: "col",
- Line: "standard",
+ Bar: "bar",
+ BarStacked: "bar",
+ BarPercentStacked: "bar",
+ Bar3DClustered: "bar",
+ Bar3DStacked: "bar",
+ Bar3DPercentStacked: "bar",
+ Bar3DConeClustered: "bar",
+ Bar3DConeStacked: "bar",
+ Bar3DConePercentStacked: "bar",
+ Bar3DPyramidClustered: "bar",
+ Bar3DPyramidStacked: "bar",
+ Bar3DPyramidPercentStacked: "bar",
+ Bar3DCylinderClustered: "bar",
+ Bar3DCylinderStacked: "bar",
+ Bar3DCylinderPercentStacked: "bar",
+ Col: "col",
+ ColStacked: "col",
+ ColPercentStacked: "col",
+ Col3D: "col",
+ Col3DClustered: "col",
+ Col3DStacked: "col",
+ Col3DPercentStacked: "col",
+ Col3DCone: "col",
+ Col3DConeStacked: "col",
+ Col3DConeClustered: "col",
+ Col3DConePercentStacked: "col",
+ Col3DPyramid: "col",
+ Col3DPyramidClustered: "col",
+ Col3DPyramidStacked: "col",
+ Col3DPyramidPercentStacked: "col",
+ Col3DCylinder: "col",
+ Col3DCylinderClustered: "col",
+ Col3DCylinderStacked: "col",
+ Col3DCylinderPercentStacked: "col",
+ Line: "standard",
}
orientation = map[bool]string{
true: "maxMin",
@@ -266,6 +462,10 @@ var (
true: "r",
false: "l",
}
+ valTickLblPos = map[string]string{
+ Contour: "none",
+ WireframeContour: "none",
+ }
)
// parseFormatChartSet provides a function to parse the format settings of the
@@ -301,7 +501,7 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
// AddChart provides the method to add chart in a sheet by given chart format
// set (such as offset, scale, aspect ratio setting and print settings) and
// properties set. For example, create 3D clustered column chart with data
-// Sheet1!$A$29:$D$32:
+// Sheet1!$E$1:$L$15:
//
// package main
//
@@ -321,47 +521,74 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
// for k, v := range values {
// f.SetCellValue("Sheet1", k, v)
// }
-// err := f.AddChart("Sheet1", "E1", `{"type":"col3DClustered","dimension":{"width":640,"height":480},"series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit 3D Clustered Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","x_axis":{"reverse_order":true},"y_axis":{"maximum":7.5,"minimum":0.5}}`)
-// if err != nil {
+// if err := f.AddChart("Sheet1", "E1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","x_axis":{"reverse_order":true},"y_axis":{"maximum":7.5,"minimum":0.5}}`); err != nil {
// fmt.Println(err)
// return
// }
// // Save xlsx file by the given path.
-// err = xlsx.SaveAs("./Book1.xlsx")
-// if err != nil {
+// if err := f.SaveAs("Book1.xlsx"); err != nil {
// fmt.Println(err)
// }
// }
//
// The following shows the type of chart supported by excelize:
//
-// Type | Chart
-// ----------------------+------------------------------
-// area | 2D area chart
-// areaStacked | 2D stacked area chart
-// areaPercentStacked | 2D 100% stacked area chart
-// area3D | 3D area chart
-// area3DStacked | 3D stacked area chart
-// area3DPercentStacked | 3D 100% stacked area chart
-// bar | 2D clustered bar chart
-// barStacked | 2D stacked bar chart
-// barPercentStacked | 2D 100% stacked bar chart
-// bar3DClustered | 3D clustered bar chart
-// bar3DStacked | 3D stacked bar chart
-// bar3DPercentStacked | 3D 100% stacked bar chart
-// col | 2D clustered column chart
-// colStacked | 2D stacked column chart
-// colPercentStacked | 2D 100% stacked column chart
-// col3DClustered | 3D clustered column chart
-// col3D | 3D column chart
-// col3DStacked | 3D stacked column chart
-// col3DPercentStacked | 3D 100% stacked column chart
-// doughnut | doughnut chart
-// line | line chart
-// pie | pie chart
-// pie3D | 3D pie chart
-// radar | radar chart
-// scatter | scatter chart
+// Type | Chart
+// -----------------------------+------------------------------
+// area | 2D area chart
+// areaStacked | 2D stacked area chart
+// areaPercentStacked | 2D 100% stacked area chart
+// area3D | 3D area chart
+// area3DStacked | 3D stacked area chart
+// area3DPercentStacked | 3D 100% stacked area chart
+// bar | 2D clustered bar chart
+// barStacked | 2D stacked bar chart
+// barPercentStacked | 2D 100% stacked bar chart
+// bar3DClustered | 3D clustered bar chart
+// bar3DStacked | 3D stacked bar chart
+// bar3DPercentStacked | 3D 100% stacked bar chart
+// bar3DConeClustered | 3D cone clustered bar chart
+// bar3DConeStacked | 3D cone stacked bar chart
+// bar3DConePercentStacked | 3D cone percent bar chart
+// bar3DPyramidClustered | 3D pyramid clustered bar chart
+// bar3DPyramidStacked | 3D pyramid stacked bar chart
+// bar3DPyramidPercentStacked | 3D pyramid percent stacked bar chart
+// bar3DCylinderClustered | 3D cylinder clustered bar chart
+// bar3DCylinderStacked | 3D cylinder stacked bar chart
+// bar3DCylinderPercentStacked | 3D cylinder percent stacked bar chart
+// col | 2D clustered column chart
+// colStacked | 2D stacked column chart
+// colPercentStacked | 2D 100% stacked column chart
+// col3DClustered | 3D clustered column chart
+// col3D | 3D column chart
+// col3DStacked | 3D stacked column chart
+// col3DPercentStacked | 3D 100% stacked column chart
+// col3DCone | 3D cone column chart
+// col3DConeClustered | 3D cone clustered column chart
+// col3DConeStacked | 3D cone stacked column chart
+// col3DConePercentStacked | 3D cone percent stacked column chart
+// col3DPyramid | 3D pyramid column chart
+// col3DPyramidClustered | 3D pyramid clustered column chart
+// col3DPyramidStacked | 3D pyramid stacked column chart
+// col3DPyramidPercentStacked | 3D pyramid percent stacked column chart
+// col3DCylinder | 3D cylinder column chart
+// col3DCylinderClustered | 3D cylinder clustered column chart
+// col3DCylinderStacked | 3D cylinder stacked column chart
+// col3DCylinderPercentStacked | 3D cylinder percent stacked column chart
+// doughnut | doughnut chart
+// line | line chart
+// pie | pie chart
+// pie3D | 3D pie chart
+// pieOfPie | pie of pie chart
+// barOfPie | bar of pie chart
+// radar | radar chart
+// scatter | scatter chart
+// surface3D | 3D surface chart
+// wireframeSurface3D | 3D wireframe surface chart
+// contour | contour chart
+// wireframeContour | wireframe contour chart
+// bubble | bubble chart
+// bubble3D | 3D bubble chart
//
// In Excel a chart series is a collection of information that defines which data is plotted such as values, axis labels and formatting.
//
@@ -370,6 +597,7 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
// name
// categories
// values
+// line
//
// name: Set the name for the series. The name is displayed in the chart legend and in the formula bar. The name property is optional and if it isn't supplied it will default to Series 1..n. The name can also be a formula such as Sheet1!$A$1
//
@@ -377,6 +605,8 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
//
// values: This is the most important property of a series and is the only mandatory option for every chart object. This option links the chart with the worksheet data that it displays.
//
+// line: This sets the line format of the line chart. The line property is optional and if it isn't supplied it will default style. The options that can be set is width. The range of width is 0.25pt - 999pt. If the value of width is outside the range, the default width of the line is 2pt.
+//
// Set properties of the chart legend. The options that can be set are:
//
// position
@@ -433,12 +663,32 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
//
// show_val: Specifies that the value shall be shown in a data label. The show_val property is optional. The default value is false.
//
-// Set the primary horizontal and vertical axis options by x_axis and y_axis. The properties that can be set are:
+// Set the primary horizontal and vertical axis options by x_axis and y_axis. The properties of x_axis that can be set are:
//
+// major_grid_lines
+// minor_grid_lines
+// tick_label_skip
// reverse_order
// maximum
// minimum
//
+// The properties of y_axis that can be set are:
+//
+// major_grid_lines
+// minor_grid_lines
+// major_unit
+// reverse_order
+// maximum
+// minimum
+//
+// major_grid_lines: Specifies major gridlines.
+//
+// minor_grid_lines: Specifies minor gridlines.
+//
+// major_unit: Specifies the distance between major ticks. Shall contain a positive floating-point number. The major_unit property is optional. The default value is auto.
+//
+// tick_label_skip: Specifies how many tick labels to skip between label that is drawn. The tick_label_skip property is optional. The default value is auto.
+//
// reverse_order: Specifies that the categories or values on reverse order (orientation of the chart). The reverse_order property is optional. The default value is false.
//
// maximum: Specifies that the fixed maximum, 0 is auto. The maximum property is optional. The default value is auto.
@@ -447,13 +697,45 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
//
// Set chart size by dimension property. The dimension property is optional. The default width is 480, and height is 290.
//
-func (f *File) AddChart(sheet, cell, format string) error {
- formatSet, err := parseFormatChartSet(format)
+// combo: Specifies the create a chart that combines two or more chart types
+// in a single chart. For example, create a clustered column - line chart with
+// data Sheet1!$E$1:$L$15:
+//
+// package main
+//
+// import (
+// "fmt"
+//
+// "github.com/360EntSecGroup-Skylar/excelize"
+// )
+//
+// func main() {
+// categories := map[string]string{"A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"}
+// values := map[string]int{"B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8}
+// f := excelize.NewFile()
+// for k, v := range categories {
+// f.SetCellValue("Sheet1", k, v)
+// }
+// for k, v := range values {
+// f.SetCellValue("Sheet1", k, v)
+// }
+// if err := f.AddChart("Sheet1", "E1", `{"type":"col","series":[{"name":"Sheet1!$A$2","categories":"","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Clustered Column - Line Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true}}`, `{"type":"line","series":[{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true}}`); err != nil {
+// fmt.Println(err)
+// return
+// }
+// // Save xlsx file by the given path.
+// if err := f.SaveAs("Book1.xlsx"); err != nil {
+// fmt.Println(err)
+// }
+// }
+//
+func (f *File) AddChart(sheet, cell, format string, combo ...string) error {
+ // Read sheet data.
+ xlsx, err := f.workSheetReader(sheet)
if err != nil {
return err
}
- // Read sheet data.
- xlsx, err := f.workSheetReader(sheet)
+ formatSet, comboCharts, err := f.getFormatChart(format, combo)
if err != nil {
return err
}
@@ -462,846 +744,130 @@ func (f *File) AddChart(sheet, cell, format string) error {
chartID := f.countCharts() + 1
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
drawingID, drawingXML = f.prepareDrawing(xlsx, drawingID, sheet, drawingXML)
- drawingRID := f.addDrawingRelationships(drawingID, SourceRelationshipChart, "../charts/chart"+strconv.Itoa(chartID)+".xml", "")
+ drawingRels := "xl/drawings/_rels/drawing" + strconv.Itoa(drawingID) + ".xml.rels"
+ drawingRID := f.addRels(drawingRels, SourceRelationshipChart, "../charts/chart"+strconv.Itoa(chartID)+".xml", "")
err = f.addDrawingChart(sheet, drawingXML, cell, formatSet.Dimension.Width, formatSet.Dimension.Height, drawingRID, &formatSet.Format)
if err != nil {
return err
}
- f.addChart(formatSet)
+ f.addChart(formatSet, comboCharts)
f.addContentTypePart(chartID, "chart")
f.addContentTypePart(drawingID, "drawings")
return err
}
-// countCharts provides a function to get chart files count storage in the
-// folder xl/charts.
-func (f *File) countCharts() int {
- count := 0
- for k := range f.XLSX {
- if strings.Contains(k, "xl/charts/chart") {
- count++
- }
- }
- return count
-}
-
-// prepareDrawing provides a function to prepare drawing ID and XML by given
-// drawingID, worksheet name and default drawingXML.
-func (f *File) prepareDrawing(xlsx *xlsxWorksheet, drawingID int, sheet, drawingXML string) (int, string) {
- sheetRelationshipsDrawingXML := "../drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
- if xlsx.Drawing != nil {
- // The worksheet already has a picture or chart relationships, use the relationships drawing ../drawings/drawing%d.xml.
- sheetRelationshipsDrawingXML = f.getSheetRelationshipsTargetByID(sheet, xlsx.Drawing.RID)
- drawingID, _ = strconv.Atoi(strings.TrimSuffix(strings.TrimPrefix(sheetRelationshipsDrawingXML, "../drawings/drawing"), ".xml"))
- drawingXML = strings.Replace(sheetRelationshipsDrawingXML, "..", "xl", -1)
- } else {
- // Add first picture for given sheet.
- rID := f.addSheetRelationships(sheet, SourceRelationshipDrawingML, sheetRelationshipsDrawingXML, "")
- f.addSheetDrawing(sheet, rID)
- }
- return drawingID, drawingXML
-}
-
-// addChart provides a function to create chart as xl/charts/chart%d.xml by
-// given format sets.
-func (f *File) addChart(formatSet *formatChart) {
- count := f.countCharts()
- xlsxChartSpace := xlsxChartSpace{
- XMLNSc: NameSpaceDrawingMLChart,
- XMLNSa: NameSpaceDrawingML,
- XMLNSr: SourceRelationship,
- XMLNSc16r2: SourceRelationshipChart201506,
- Date1904: &attrValBool{Val: false},
- Lang: &attrValString{Val: "en-US"},
- RoundedCorners: &attrValBool{Val: false},
- Chart: cChart{
- Title: &cTitle{
- Tx: cTx{
- Rich: &cRich{
- P: aP{
- PPr: &aPPr{
- DefRPr: aRPr{
- Kern: 1200,
- Strike: "noStrike",
- U: "none",
- Sz: 1400,
- SolidFill: &aSolidFill{
- SchemeClr: &aSchemeClr{
- Val: "tx1",
- LumMod: &attrValInt{
- Val: 65000,
- },
- LumOff: &attrValInt{
- Val: 35000,
- },
- },
- },
- Ea: &aEa{
- Typeface: "+mn-ea",
- },
- Cs: &aCs{
- Typeface: "+mn-cs",
- },
- Latin: &aLatin{
- Typeface: "+mn-lt",
- },
- },
- },
- R: &aR{
- RPr: aRPr{
- Lang: "en-US",
- AltLang: "en-US",
- },
- T: formatSet.Title.Name,
- },
- },
- },
- },
- TxPr: cTxPr{
- P: aP{
- PPr: &aPPr{
- DefRPr: aRPr{
- Kern: 1200,
- U: "none",
- Sz: 14000,
- Strike: "noStrike",
- },
- },
- EndParaRPr: &aEndParaRPr{
- Lang: "en-US",
- },
- },
- },
- },
- View3D: &cView3D{
- RotX: &attrValInt{Val: chartView3DRotX[formatSet.Type]},
- RotY: &attrValInt{Val: chartView3DRotY[formatSet.Type]},
- DepthPercent: &attrValInt{Val: chartView3DDepthPercent[formatSet.Type]},
- RAngAx: &attrValInt{Val: chartView3DRAngAx[formatSet.Type]},
- },
- Floor: &cThicknessSpPr{
- Thickness: &attrValInt{Val: 0},
- },
- SideWall: &cThicknessSpPr{
- Thickness: &attrValInt{Val: 0},
- },
- BackWall: &cThicknessSpPr{
- Thickness: &attrValInt{Val: 0},
- },
- PlotArea: &cPlotArea{},
- Legend: &cLegend{
- LegendPos: &attrValString{Val: chartLegendPosition[formatSet.Legend.Position]},
- Overlay: &attrValBool{Val: false},
- },
-
- PlotVisOnly: &attrValBool{Val: false},
- DispBlanksAs: &attrValString{Val: formatSet.ShowBlanksAs},
- ShowDLblsOverMax: &attrValBool{Val: false},
- },
- SpPr: &cSpPr{
- SolidFill: &aSolidFill{
- SchemeClr: &aSchemeClr{Val: "bg1"},
- },
- Ln: &aLn{
- W: 9525,
- Cap: "flat",
- Cmpd: "sng",
- Algn: "ctr",
- SolidFill: &aSolidFill{
- SchemeClr: &aSchemeClr{Val: "tx1",
- LumMod: &attrValInt{
- Val: 15000,
- },
- LumOff: &attrValInt{
- Val: 85000,
- },
- },
- },
- },
- },
- PrintSettings: &cPrintSettings{
- PageMargins: &cPageMargins{
- B: 0.75,
- L: 0.7,
- R: 0.7,
- T: 0.7,
- Header: 0.3,
- Footer: 0.3,
- },
- },
- }
- plotAreaFunc := map[string]func(*formatChart) *cPlotArea{
- Area: f.drawBaseChart,
- AreaStacked: f.drawBaseChart,
- AreaPercentStacked: f.drawBaseChart,
- Area3D: f.drawBaseChart,
- Area3DStacked: f.drawBaseChart,
- Area3DPercentStacked: f.drawBaseChart,
- Bar: f.drawBaseChart,
- BarStacked: f.drawBaseChart,
- BarPercentStacked: f.drawBaseChart,
- Bar3DClustered: f.drawBaseChart,
- Bar3DStacked: f.drawBaseChart,
- Bar3DPercentStacked: f.drawBaseChart,
- Col: f.drawBaseChart,
- ColStacked: f.drawBaseChart,
- ColPercentStacked: f.drawBaseChart,
- Col3DClustered: f.drawBaseChart,
- Col3D: f.drawBaseChart,
- Col3DStacked: f.drawBaseChart,
- Col3DPercentStacked: f.drawBaseChart,
- Doughnut: f.drawDoughnutChart,
- Line: f.drawLineChart,
- Pie3D: f.drawPie3DChart,
- Pie: f.drawPieChart,
- Radar: f.drawRadarChart,
- Scatter: f.drawScatterChart,
- }
- xlsxChartSpace.Chart.PlotArea = plotAreaFunc[formatSet.Type](formatSet)
-
- chart, _ := xml.Marshal(xlsxChartSpace)
- media := "xl/charts/chart" + strconv.Itoa(count+1) + ".xml"
- f.saveFileList(media, chart)
-}
-
-// drawBaseChart provides a function to draw the c:plotArea element for bar,
-// and column series charts by given format sets.
-func (f *File) drawBaseChart(formatSet *formatChart) *cPlotArea {
- c := cCharts{
- BarDir: &attrValString{
- Val: "col",
- },
- Grouping: &attrValString{
- Val: "clustered",
- },
- VaryColors: &attrValBool{
- Val: true,
- },
- Ser: f.drawChartSeries(formatSet),
- DLbls: f.drawChartDLbls(formatSet),
- AxID: []*attrValInt{
- {Val: 754001152},
- {Val: 753999904},
- },
- }
- var ok bool
- c.BarDir.Val, ok = plotAreaChartBarDir[formatSet.Type]
- if !ok {
- c.BarDir = nil
- }
- c.Grouping.Val = plotAreaChartGrouping[formatSet.Type]
- if formatSet.Type == "colStacked" || formatSet.Type == "barStacked" || formatSet.Type == "barPercentStacked" || formatSet.Type == "colPercentStacked" || formatSet.Type == "areaPercentStacked" {
- c.Overlap = &attrValInt{Val: 100}
- }
- catAx := f.drawPlotAreaCatAx(formatSet)
- valAx := f.drawPlotAreaValAx(formatSet)
- charts := map[string]*cPlotArea{
- "area": {
- AreaChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "areaStacked": {
- AreaChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "areaPercentStacked": {
- AreaChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "area3D": {
- Area3DChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "area3DStacked": {
- Area3DChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "area3DPercentStacked": {
- Area3DChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "bar": {
- BarChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "barStacked": {
- BarChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "barPercentStacked": {
- BarChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "bar3DClustered": {
- Bar3DChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "bar3DStacked": {
- Bar3DChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "bar3DPercentStacked": {
- Bar3DChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "col": {
- BarChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "colStacked": {
- BarChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "colPercentStacked": {
- BarChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "col3DClustered": {
- Bar3DChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "col3D": {
- Bar3DChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "col3DStacked": {
- Bar3DChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- "col3DPercentStacked": {
- Bar3DChart: &c,
- CatAx: catAx,
- ValAx: valAx,
- },
- }
- return charts[formatSet.Type]
-}
-
-// drawDoughnutChart provides a function to draw the c:plotArea element for
-// doughnut chart by given format sets.
-func (f *File) drawDoughnutChart(formatSet *formatChart) *cPlotArea {
- return &cPlotArea{
- DoughnutChart: &cCharts{
- VaryColors: &attrValBool{
- Val: true,
- },
- Ser: f.drawChartSeries(formatSet),
- HoleSize: &attrValInt{Val: 75},
- },
- }
-}
-
-// drawLineChart provides a function to draw the c:plotArea element for line
-// chart by given format sets.
-func (f *File) drawLineChart(formatSet *formatChart) *cPlotArea {
- return &cPlotArea{
- LineChart: &cCharts{
- Grouping: &attrValString{
- Val: plotAreaChartGrouping[formatSet.Type],
- },
- VaryColors: &attrValBool{
- Val: false,
- },
- Ser: f.drawChartSeries(formatSet),
- DLbls: f.drawChartDLbls(formatSet),
- Smooth: &attrValBool{
- Val: false,
- },
- AxID: []*attrValInt{
- {Val: 754001152},
- {Val: 753999904},
- },
- },
- CatAx: f.drawPlotAreaCatAx(formatSet),
- ValAx: f.drawPlotAreaValAx(formatSet),
+// AddChartSheet provides the method to create a chartsheet by given chart
+// format set (such as offset, scale, aspect ratio setting and print settings)
+// and properties set. In Excel a chartsheet is a worksheet that only contains
+// a chart.
+func (f *File) AddChartSheet(sheet, format string, combo ...string) error {
+ // Check if the worksheet already exists
+ if f.GetSheetIndex(sheet) != -1 {
+ return errors.New("the same name worksheet already exists")
}
-}
-
-// drawPieChart provides a function to draw the c:plotArea element for pie
-// chart by given format sets.
-func (f *File) drawPieChart(formatSet *formatChart) *cPlotArea {
- return &cPlotArea{
- PieChart: &cCharts{
- VaryColors: &attrValBool{
- Val: true,
- },
- Ser: f.drawChartSeries(formatSet),
- },
- }
-}
-
-// drawPie3DChart provides a function to draw the c:plotArea element for 3D
-// pie chart by given format sets.
-func (f *File) drawPie3DChart(formatSet *formatChart) *cPlotArea {
- return &cPlotArea{
- Pie3DChart: &cCharts{
- VaryColors: &attrValBool{
- Val: true,
- },
- Ser: f.drawChartSeries(formatSet),
- },
- }
-}
-
-// drawRadarChart provides a function to draw the c:plotArea element for radar
-// chart by given format sets.
-func (f *File) drawRadarChart(formatSet *formatChart) *cPlotArea {
- return &cPlotArea{
- RadarChart: &cCharts{
- RadarStyle: &attrValString{
- Val: "marker",
- },
- VaryColors: &attrValBool{
- Val: false,
- },
- Ser: f.drawChartSeries(formatSet),
- DLbls: f.drawChartDLbls(formatSet),
- AxID: []*attrValInt{
- {Val: 754001152},
- {Val: 753999904},
- },
- },
- CatAx: f.drawPlotAreaCatAx(formatSet),
- ValAx: f.drawPlotAreaValAx(formatSet),
- }
-}
-
-// drawScatterChart provides a function to draw the c:plotArea element for
-// scatter chart by given format sets.
-func (f *File) drawScatterChart(formatSet *formatChart) *cPlotArea {
- return &cPlotArea{
- ScatterChart: &cCharts{
- ScatterStyle: &attrValString{
- Val: "smoothMarker", // line,lineMarker,marker,none,smooth,smoothMarker
- },
- VaryColors: &attrValBool{
- Val: false,
- },
- Ser: f.drawChartSeries(formatSet),
- DLbls: f.drawChartDLbls(formatSet),
- AxID: []*attrValInt{
- {Val: 754001152},
- {Val: 753999904},
- },
- },
- CatAx: f.drawPlotAreaCatAx(formatSet),
- ValAx: f.drawPlotAreaValAx(formatSet),
- }
-}
-
-// drawChartSeries provides a function to draw the c:ser element by given
-// format sets.
-func (f *File) drawChartSeries(formatSet *formatChart) *[]cSer {
- ser := []cSer{}
- for k := range formatSet.Series {
- ser = append(ser, cSer{
- IDx: &attrValInt{Val: k},
- Order: &attrValInt{Val: k},
- Tx: &cTx{
- StrRef: &cStrRef{
- F: formatSet.Series[k].Name,
- },
- },
- SpPr: f.drawChartSeriesSpPr(k, formatSet),
- Marker: f.drawChartSeriesMarker(k, formatSet),
- DPt: f.drawChartSeriesDPt(k, formatSet),
- DLbls: f.drawChartSeriesDLbls(formatSet),
- Cat: f.drawChartSeriesCat(formatSet.Series[k], formatSet),
- Val: f.drawChartSeriesVal(formatSet.Series[k], formatSet),
- XVal: f.drawChartSeriesXVal(formatSet.Series[k], formatSet),
- YVal: f.drawChartSeriesYVal(formatSet.Series[k], formatSet),
- })
- }
- return &ser
-}
-
-// drawChartSeriesSpPr provides a function to draw the c:spPr element by given
-// format sets.
-func (f *File) drawChartSeriesSpPr(i int, formatSet *formatChart) *cSpPr {
- spPrScatter := &cSpPr{
- Ln: &aLn{
- W: 25400,
- NoFill: " ",
- },
- }
- spPrLine := &cSpPr{
- Ln: &aLn{
- W: 25400,
- Cap: "rnd", // rnd, sq, flat
- SolidFill: &aSolidFill{
- SchemeClr: &aSchemeClr{Val: "accent" + strconv.Itoa(i+1)},
- },
- },
- }
- chartSeriesSpPr := map[string]*cSpPr{Area: nil, AreaStacked: nil, AreaPercentStacked: nil, Area3D: nil, Area3DStacked: nil, Area3DPercentStacked: nil, Bar: nil, BarStacked: nil, BarPercentStacked: nil, Bar3DClustered: nil, Bar3DStacked: nil, Bar3DPercentStacked: nil, Col: nil, ColStacked: nil, ColPercentStacked: nil, Col3DClustered: nil, Col3D: nil, Col3DStacked: nil, Col3DPercentStacked: nil, Doughnut: nil, Line: spPrLine, Pie: nil, Pie3D: nil, Radar: nil, Scatter: spPrScatter}
- return chartSeriesSpPr[formatSet.Type]
-}
-
-// drawChartSeriesDPt provides a function to draw the c:dPt element by given
-// data index and format sets.
-func (f *File) drawChartSeriesDPt(i int, formatSet *formatChart) []*cDPt {
- dpt := []*cDPt{{
- IDx: &attrValInt{Val: i},
- Bubble3D: &attrValBool{Val: false},
- SpPr: &cSpPr{
- SolidFill: &aSolidFill{
- SchemeClr: &aSchemeClr{Val: "accent" + strconv.Itoa(i+1)},
- },
- Ln: &aLn{
- W: 25400,
- Cap: "rnd",
- SolidFill: &aSolidFill{
- SchemeClr: &aSchemeClr{Val: "lt" + strconv.Itoa(i+1)},
- },
- },
- Sp3D: &aSp3D{
- ContourW: 25400,
- ContourClr: &aContourClr{
- SchemeClr: &aSchemeClr{Val: "lt" + strconv.Itoa(i+1)},
- },
- },
- },
- }}
- chartSeriesDPt := map[string][]*cDPt{Area: nil, AreaStacked: nil, AreaPercentStacked: nil, Area3D: nil, Area3DStacked: nil, Area3DPercentStacked: nil, Bar: nil, BarStacked: nil, BarPercentStacked: nil, Bar3DClustered: nil, Bar3DStacked: nil, Bar3DPercentStacked: nil, Col: nil, ColStacked: nil, ColPercentStacked: nil, Col3DClustered: nil, Col3D: nil, Col3DStacked: nil, Col3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: dpt, Pie3D: dpt, Radar: nil, Scatter: nil}
- return chartSeriesDPt[formatSet.Type]
-}
-
-// drawChartSeriesCat provides a function to draw the c:cat element by given
-// chart series and format sets.
-func (f *File) drawChartSeriesCat(v formatChartSeries, formatSet *formatChart) *cCat {
- cat := &cCat{
- StrRef: &cStrRef{
- F: v.Categories,
- },
- }
- chartSeriesCat := map[string]*cCat{Area: cat, AreaStacked: cat, AreaPercentStacked: cat, Area3D: cat, Area3DStacked: cat, Area3DPercentStacked: cat, Bar: cat, BarStacked: cat, BarPercentStacked: cat, Bar3DClustered: cat, Bar3DStacked: cat, Bar3DPercentStacked: cat, Col: cat, ColStacked: cat, ColPercentStacked: cat, Col3DClustered: cat, Col3D: cat, Col3DStacked: cat, Col3DPercentStacked: cat, Doughnut: cat, Line: cat, Pie: cat, Pie3D: cat, Radar: cat, Scatter: nil}
- return chartSeriesCat[formatSet.Type]
-}
-
-// drawChartSeriesVal provides a function to draw the c:val element by given
-// chart series and format sets.
-func (f *File) drawChartSeriesVal(v formatChartSeries, formatSet *formatChart) *cVal {
- val := &cVal{
- NumRef: &cNumRef{
- F: v.Values,
- },
- }
- chartSeriesVal := map[string]*cVal{Area: val, AreaStacked: val, AreaPercentStacked: val, Area3D: val, Area3DStacked: val, Area3DPercentStacked: val, Bar: val, BarStacked: val, BarPercentStacked: val, Bar3DClustered: val, Bar3DStacked: val, Bar3DPercentStacked: val, Col: val, ColStacked: val, ColPercentStacked: val, Col3DClustered: val, Col3D: val, Col3DStacked: val, Col3DPercentStacked: val, Doughnut: val, Line: val, Pie: val, Pie3D: val, Radar: val, Scatter: nil}
- return chartSeriesVal[formatSet.Type]
-}
-
-// drawChartSeriesMarker provides a function to draw the c:marker element by
-// given data index and format sets.
-func (f *File) drawChartSeriesMarker(i int, formatSet *formatChart) *cMarker {
- marker := &cMarker{
- Symbol: &attrValString{Val: "circle"},
- Size: &attrValInt{Val: 5},
- SpPr: &cSpPr{
- SolidFill: &aSolidFill{
- SchemeClr: &aSchemeClr{
- Val: "accent" + strconv.Itoa(i+1),
- },
- },
- Ln: &aLn{
- W: 9252,
- SolidFill: &aSolidFill{
- SchemeClr: &aSchemeClr{
- Val: "accent" + strconv.Itoa(i+1),
- },
- },
- },
- },
- }
- chartSeriesMarker := map[string]*cMarker{Area: nil, AreaStacked: nil, AreaPercentStacked: nil, Area3D: nil, Area3DStacked: nil, Area3DPercentStacked: nil, Bar: nil, BarStacked: nil, BarPercentStacked: nil, Bar3DClustered: nil, Bar3DStacked: nil, Bar3DPercentStacked: nil, Col: nil, ColStacked: nil, ColPercentStacked: nil, Col3DClustered: nil, Col3D: nil, Col3DStacked: nil, Col3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: marker}
- return chartSeriesMarker[formatSet.Type]
-}
-
-// drawChartSeriesXVal provides a function to draw the c:xVal element by given
-// chart series and format sets.
-func (f *File) drawChartSeriesXVal(v formatChartSeries, formatSet *formatChart) *cCat {
- cat := &cCat{
- StrRef: &cStrRef{
- F: v.Categories,
- },
+ formatSet, comboCharts, err := f.getFormatChart(format, combo)
+ if err != nil {
+ return err
}
- chartSeriesXVal := map[string]*cCat{Area: nil, AreaStacked: nil, AreaPercentStacked: nil, Area3D: nil, Area3DStacked: nil, Area3DPercentStacked: nil, Bar: nil, BarStacked: nil, BarPercentStacked: nil, Bar3DClustered: nil, Bar3DStacked: nil, Bar3DPercentStacked: nil, Col: nil, ColStacked: nil, ColPercentStacked: nil, Col3DClustered: nil, Col3D: nil, Col3DStacked: nil, Col3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: cat}
- return chartSeriesXVal[formatSet.Type]
-}
-
-// drawChartSeriesYVal provides a function to draw the c:yVal element by given
-// chart series and format sets.
-func (f *File) drawChartSeriesYVal(v formatChartSeries, formatSet *formatChart) *cVal {
- val := &cVal{
- NumRef: &cNumRef{
- F: v.Values,
+ cs := xlsxChartsheet{
+ SheetViews: []*xlsxChartsheetViews{{
+ SheetView: []*xlsxChartsheetView{{ZoomScaleAttr: 100, ZoomToFitAttr: true}}},
},
}
- chartSeriesYVal := map[string]*cVal{Area: nil, AreaStacked: nil, AreaPercentStacked: nil, Area3D: nil, Area3DStacked: nil, Area3DPercentStacked: nil, Bar: nil, BarStacked: nil, BarPercentStacked: nil, Bar3DClustered: nil, Bar3DStacked: nil, Bar3DPercentStacked: nil, Col: nil, ColStacked: nil, ColPercentStacked: nil, Col3DClustered: nil, Col3D: nil, Col3DStacked: nil, Col3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: val}
- return chartSeriesYVal[formatSet.Type]
-}
-
-// drawChartDLbls provides a function to draw the c:dLbls element by given
-// format sets.
-func (f *File) drawChartDLbls(formatSet *formatChart) *cDLbls {
- return &cDLbls{
- ShowLegendKey: &attrValBool{Val: formatSet.Legend.ShowLegendKey},
- ShowVal: &attrValBool{Val: formatSet.Plotarea.ShowVal},
- ShowCatName: &attrValBool{Val: formatSet.Plotarea.ShowCatName},
- ShowSerName: &attrValBool{Val: formatSet.Plotarea.ShowSerName},
- ShowBubbleSize: &attrValBool{Val: formatSet.Plotarea.ShowBubbleSize},
- ShowPercent: &attrValBool{Val: formatSet.Plotarea.ShowPercent},
- ShowLeaderLines: &attrValBool{Val: formatSet.Plotarea.ShowLeaderLines},
+ f.SheetCount++
+ wb := f.workbookReader()
+ sheetID := 0
+ for _, v := range wb.Sheets.Sheet {
+ if v.SheetID > sheetID {
+ sheetID = v.SheetID
+ }
}
+ sheetID++
+ path := "xl/chartsheets/sheet" + strconv.Itoa(sheetID) + ".xml"
+ f.sheetMap[trimSheetName(sheet)] = path
+ f.Sheet[path] = nil
+ drawingID := f.countDrawings() + 1
+ chartID := f.countCharts() + 1
+ drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
+ f.prepareChartSheetDrawing(&cs, drawingID, sheet)
+ drawingRels := "xl/drawings/_rels/drawing" + strconv.Itoa(drawingID) + ".xml.rels"
+ drawingRID := f.addRels(drawingRels, SourceRelationshipChart, "../charts/chart"+strconv.Itoa(chartID)+".xml", "")
+ f.addSheetDrawingChart(drawingXML, drawingRID, &formatSet.Format)
+ f.addChart(formatSet, comboCharts)
+ f.addContentTypePart(chartID, "chart")
+ f.addContentTypePart(sheetID, "chartsheet")
+ f.addContentTypePart(drawingID, "drawings")
+ // Update xl/_rels/workbook.xml.rels
+ rID := f.addRels("xl/_rels/workbook.xml.rels", SourceRelationshipChartsheet, fmt.Sprintf("chartsheets/sheet%d.xml", sheetID), "")
+ // Update xl/workbook.xml
+ f.setWorkbook(sheet, sheetID, rID)
+ chartsheet, _ := xml.Marshal(cs)
+ f.saveFileList(path, replaceRelationshipsBytes(replaceRelationshipsNameSpaceBytes(chartsheet)))
+ return err
}
-// drawChartSeriesDLbls provides a function to draw the c:dLbls element by
-// given format sets.
-func (f *File) drawChartSeriesDLbls(formatSet *formatChart) *cDLbls {
- dLbls := f.drawChartDLbls(formatSet)
- chartSeriesDLbls := map[string]*cDLbls{Area: dLbls, AreaStacked: dLbls, AreaPercentStacked: dLbls, Area3D: dLbls, Area3DStacked: dLbls, Area3DPercentStacked: dLbls, Bar: dLbls, BarStacked: dLbls, BarPercentStacked: dLbls, Bar3DClustered: dLbls, Bar3DStacked: dLbls, Bar3DPercentStacked: dLbls, Col: dLbls, ColStacked: dLbls, ColPercentStacked: dLbls, Col3DClustered: dLbls, Col3D: dLbls, Col3DStacked: dLbls, Col3DPercentStacked: dLbls, Doughnut: dLbls, Line: dLbls, Pie: dLbls, Pie3D: dLbls, Radar: dLbls, Scatter: nil}
- return chartSeriesDLbls[formatSet.Type]
-}
-
-// drawPlotAreaCatAx provides a function to draw the c:catAx element.
-func (f *File) drawPlotAreaCatAx(formatSet *formatChart) []*cAxs {
- min := &attrValFloat{Val: formatSet.XAxis.Minimum}
- max := &attrValFloat{Val: formatSet.XAxis.Maximum}
- if formatSet.XAxis.Minimum == 0 {
- min = nil
+// getFormatChart provides a function to check format set of the chart and
+// create chart format.
+func (f *File) getFormatChart(format string, combo []string) (*formatChart, []*formatChart, error) {
+ comboCharts := []*formatChart{}
+ formatSet, err := parseFormatChartSet(format)
+ if err != nil {
+ return formatSet, comboCharts, err
}
- if formatSet.XAxis.Maximum == 0 {
- max = nil
+ for _, comboFormat := range combo {
+ comboChart, err := parseFormatChartSet(comboFormat)
+ if err != nil {
+ return formatSet, comboCharts, err
+ }
+ if _, ok := chartValAxNumFmtFormatCode[comboChart.Type]; !ok {
+ return formatSet, comboCharts, errors.New("unsupported chart type " + comboChart.Type)
+ }
+ comboCharts = append(comboCharts, comboChart)
}
- return []*cAxs{
- {
- AxID: &attrValInt{Val: 754001152},
- Scaling: &cScaling{
- Orientation: &attrValString{Val: orientation[formatSet.XAxis.ReverseOrder]},
- Max: max,
- Min: min,
- },
- Delete: &attrValBool{Val: false},
- AxPos: &attrValString{Val: catAxPos[formatSet.XAxis.ReverseOrder]},
- NumFmt: &cNumFmt{
- FormatCode: "General",
- SourceLinked: true,
- },
- MajorTickMark: &attrValString{Val: "none"},
- MinorTickMark: &attrValString{Val: "none"},
- TickLblPos: &attrValString{Val: "nextTo"},
- SpPr: f.drawPlotAreaSpPr(),
- TxPr: f.drawPlotAreaTxPr(),
- CrossAx: &attrValInt{Val: 753999904},
- Crosses: &attrValString{Val: "autoZero"},
- Auto: &attrValBool{Val: true},
- LblAlgn: &attrValString{Val: "ctr"},
- LblOffset: &attrValInt{Val: 100},
- NoMultiLvlLbl: &attrValBool{Val: false},
- },
+ if _, ok := chartValAxNumFmtFormatCode[formatSet.Type]; !ok {
+ return formatSet, comboCharts, errors.New("unsupported chart type " + formatSet.Type)
}
+ return formatSet, comboCharts, err
}
-// drawPlotAreaValAx provides a function to draw the c:valAx element.
-func (f *File) drawPlotAreaValAx(formatSet *formatChart) []*cAxs {
- min := &attrValFloat{Val: formatSet.YAxis.Minimum}
- max := &attrValFloat{Val: formatSet.YAxis.Maximum}
- if formatSet.YAxis.Minimum == 0 {
- min = nil
- }
- if formatSet.YAxis.Maximum == 0 {
- max = nil
- }
- return []*cAxs{
- {
- AxID: &attrValInt{Val: 753999904},
- Scaling: &cScaling{
- Orientation: &attrValString{Val: orientation[formatSet.YAxis.ReverseOrder]},
- Max: max,
- Min: min,
- },
- Delete: &attrValBool{Val: false},
- AxPos: &attrValString{Val: valAxPos[formatSet.YAxis.ReverseOrder]},
- NumFmt: &cNumFmt{
- FormatCode: chartValAxNumFmtFormatCode[formatSet.Type],
- SourceLinked: true,
- },
- MajorTickMark: &attrValString{Val: "none"},
- MinorTickMark: &attrValString{Val: "none"},
- TickLblPos: &attrValString{Val: "nextTo"},
- SpPr: f.drawPlotAreaSpPr(),
- TxPr: f.drawPlotAreaTxPr(),
- CrossAx: &attrValInt{Val: 754001152},
- Crosses: &attrValString{Val: "autoZero"},
- CrossBetween: &attrValString{Val: chartValAxCrossBetween[formatSet.Type]},
- },
+// DeleteChart provides a function to delete chart in XLSX by given worksheet
+// and cell name.
+func (f *File) DeleteChart(sheet, cell string) (err error) {
+ col, row, err := CellNameToCoordinates(cell)
+ if err != nil {
+ return
}
-}
-
-// drawPlotAreaSpPr provides a function to draw the c:spPr element.
-func (f *File) drawPlotAreaSpPr() *cSpPr {
- return &cSpPr{
- Ln: &aLn{
- W: 9525,
- Cap: "flat",
- Cmpd: "sng",
- Algn: "ctr",
- SolidFill: &aSolidFill{
- SchemeClr: &aSchemeClr{
- Val: "tx1",
- LumMod: &attrValInt{Val: 15000},
- LumOff: &attrValInt{Val: 85000},
- },
- },
- },
+ col--
+ row--
+ ws, err := f.workSheetReader(sheet)
+ if err != nil {
+ return
}
-}
-
-// drawPlotAreaTxPr provides a function to draw the c:txPr element.
-func (f *File) drawPlotAreaTxPr() *cTxPr {
- return &cTxPr{
- BodyPr: aBodyPr{
- Rot: -60000000,
- SpcFirstLastPara: true,
- VertOverflow: "ellipsis",
- Vert: "horz",
- Wrap: "square",
- Anchor: "ctr",
- AnchorCtr: true,
- },
- P: aP{
- PPr: &aPPr{
- DefRPr: aRPr{
- Sz: 900,
- B: false,
- I: false,
- U: "none",
- Strike: "noStrike",
- Kern: 1200,
- Baseline: 0,
- SolidFill: &aSolidFill{
- SchemeClr: &aSchemeClr{
- Val: "tx1",
- LumMod: &attrValInt{Val: 15000},
- LumOff: &attrValInt{Val: 85000},
- },
- },
- Latin: &aLatin{Typeface: "+mn-lt"},
- Ea: &aEa{Typeface: "+mn-ea"},
- Cs: &aCs{Typeface: "+mn-cs"},
- },
- },
- EndParaRPr: &aEndParaRPr{Lang: "en-US"},
- },
+ if ws.Drawing == nil {
+ return
}
+ drawingXML := strings.Replace(f.getSheetRelationshipsTargetByID(sheet, ws.Drawing.RID), "..", "xl", -1)
+ return f.deleteDrawing(col, row, drawingXML, "Chart")
}
-// drawingParser provides a function to parse drawingXML. In order to solve
-// the problem that the label structure is changed after serialization and
-// deserialization, two different structures: decodeWsDr and encodeWsDr are
-// defined.
-func (f *File) drawingParser(path string) (*xlsxWsDr, int) {
- cNvPrID := 1
- if f.Drawings[path] == nil {
- content := xlsxWsDr{}
- content.A = NameSpaceDrawingML
- content.Xdr = NameSpaceDrawingMLSpreadSheet
- _, ok := f.XLSX[path]
- if ok { // Append Model
- decodeWsDr := decodeWsDr{}
- _ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(path)), &decodeWsDr)
- content.R = decodeWsDr.R
- cNvPrID = len(decodeWsDr.OneCellAnchor) + len(decodeWsDr.TwoCellAnchor) + 1
- for _, v := range decodeWsDr.OneCellAnchor {
- content.OneCellAnchor = append(content.OneCellAnchor, &xdrCellAnchor{
- EditAs: v.EditAs,
- GraphicFrame: v.Content,
- })
- }
- for _, v := range decodeWsDr.TwoCellAnchor {
- content.TwoCellAnchor = append(content.TwoCellAnchor, &xdrCellAnchor{
- EditAs: v.EditAs,
- GraphicFrame: v.Content,
- })
- }
+// countCharts provides a function to get chart files count storage in the
+// folder xl/charts.
+func (f *File) countCharts() int {
+ count := 0
+ for k := range f.XLSX {
+ if strings.Contains(k, "xl/charts/chart") {
+ count++
}
- f.Drawings[path] = &content
}
- return f.Drawings[path], cNvPrID
+ return count
}
-// addDrawingChart provides a function to add chart graphic frame by given
-// sheet, drawingXML, cell, width, height, relationship index and format sets.
-func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rID int, formatSet *formatPicture) error {
- col, row, err := CellNameToCoordinates(cell)
- if err != nil {
- return err
- }
- colIdx := col - 1
- rowIdx := row - 1
-
- width = int(float64(width) * formatSet.XScale)
- height = int(float64(height) * formatSet.YScale)
- colStart, rowStart, _, _, colEnd, rowEnd, x2, y2 :=
- f.positionObjectPixels(sheet, colIdx, rowIdx, formatSet.OffsetX, formatSet.OffsetY, width, height)
- content, cNvPrID := f.drawingParser(drawingXML)
- twoCellAnchor := xdrCellAnchor{}
- twoCellAnchor.EditAs = formatSet.Positioning
- from := xlsxFrom{}
- from.Col = colStart
- from.ColOff = formatSet.OffsetX * EMU
- from.Row = rowStart
- from.RowOff = formatSet.OffsetY * EMU
- to := xlsxTo{}
- to.Col = colEnd
- to.ColOff = x2 * EMU
- to.Row = rowEnd
- to.RowOff = y2 * EMU
- twoCellAnchor.From = &from
- twoCellAnchor.To = &to
-
- graphicFrame := xlsxGraphicFrame{
- NvGraphicFramePr: xlsxNvGraphicFramePr{
- CNvPr: &xlsxCNvPr{
- ID: f.countCharts() + f.countMedia() + 1,
- Name: "Chart " + strconv.Itoa(cNvPrID),
- },
- },
- Graphic: &xlsxGraphic{
- GraphicData: &xlsxGraphicData{
- URI: NameSpaceDrawingMLChart,
- Chart: &xlsxChart{
- C: NameSpaceDrawingMLChart,
- R: SourceRelationship,
- RID: "rId" + strconv.Itoa(rID),
- },
- },
- },
- }
- graphic, _ := xml.Marshal(graphicFrame)
- twoCellAnchor.GraphicFrame = string(graphic)
- twoCellAnchor.ClientData = &xdrClientData{
- FLocksWithSheet: formatSet.FLocksWithSheet,
- FPrintsWithSheet: formatSet.FPrintsWithSheet,
+// ptToEMUs provides a function to convert pt to EMUs, 1 pt = 12700 EMUs. The
+// range of pt is 0.25pt - 999pt. If the value of pt is outside the range, the
+// default EMUs will be returned.
+func (f *File) ptToEMUs(pt float64) int {
+ if 0.25 > pt || pt > 999 {
+ return 25400
}
- content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor)
- f.Drawings[drawingXML] = content
- return err
+ return int(12700 * pt)
}