2017-09-03 16:47:46 -05:00
|
|
|
// Copyright 2017 Baliance. All rights reserved.
|
|
|
|
//
|
|
|
|
// Use of this source code is governed by the terms of the Affero GNU General
|
|
|
|
// Public License version 3.0 as published by the Free Software Foundation and
|
|
|
|
// appearing in the file LICENSE included in the packaging of this file. A
|
|
|
|
// commercial license can be purchased by contacting sales@baliance.com.
|
|
|
|
|
2017-09-04 15:32:59 -05:00
|
|
|
package chart
|
2017-09-03 16:47:46 -05:00
|
|
|
|
2017-09-04 10:50:29 -05:00
|
|
|
import (
|
|
|
|
"math/rand"
|
|
|
|
|
|
|
|
"baliance.com/gooxml"
|
|
|
|
"baliance.com/gooxml/color"
|
|
|
|
"baliance.com/gooxml/drawing"
|
|
|
|
|
|
|
|
dml "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml"
|
|
|
|
crt "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml/2006/chart"
|
|
|
|
)
|
2017-09-03 16:47:46 -05:00
|
|
|
|
2017-09-04 15:32:59 -05:00
|
|
|
// Chart is a generic chart.
|
2017-09-03 16:47:46 -05:00
|
|
|
type Chart struct {
|
|
|
|
x *crt.ChartSpace
|
|
|
|
}
|
|
|
|
|
2017-09-04 15:32:59 -05:00
|
|
|
func MakeChart(x *crt.ChartSpace) Chart {
|
|
|
|
return Chart{x}
|
|
|
|
}
|
|
|
|
|
2017-09-03 16:47:46 -05:00
|
|
|
// X returns the inner wrapped XML type.
|
|
|
|
func (c Chart) X() *crt.ChartSpace {
|
|
|
|
return c.x
|
|
|
|
}
|
|
|
|
|
2017-09-04 15:32:59 -05:00
|
|
|
// AddLineChart adds a new line chart to a chart.
|
2017-09-03 16:47:46 -05:00
|
|
|
func (c Chart) AddLineChart() LineChart {
|
|
|
|
chc := crt.NewCT_PlotAreaChoice()
|
|
|
|
c.x.Chart.PlotArea.Choice = append(c.x.Chart.PlotArea.Choice, chc)
|
|
|
|
chc.LineChart = crt.NewCT_LineChart()
|
|
|
|
chc.LineChart.Grouping = crt.NewCT_Grouping()
|
|
|
|
chc.LineChart.Grouping.ValAttr = crt.ST_GroupingStandard
|
2017-09-04 16:01:26 -05:00
|
|
|
return LineChart{x: chc.LineChart}
|
2017-09-03 16:47:46 -05:00
|
|
|
}
|
2017-09-04 10:50:29 -05:00
|
|
|
|
2017-09-06 16:52:39 -04:00
|
|
|
func setup3DChart(c *crt.CT_Chart) {
|
|
|
|
c.View3D = crt.NewCT_View3D()
|
|
|
|
c.View3D.RotX = crt.NewCT_RotX()
|
|
|
|
c.View3D.RotX.ValAttr = gooxml.Int8(15)
|
|
|
|
c.View3D.RotY = crt.NewCT_RotY()
|
|
|
|
c.View3D.RotY.ValAttr = gooxml.Uint16(20)
|
|
|
|
c.View3D.RAngAx = crt.NewCT_Boolean()
|
|
|
|
c.View3D.RAngAx.ValAttr = gooxml.Bool(false)
|
|
|
|
|
|
|
|
c.Floor = crt.NewCT_Surface()
|
|
|
|
c.Floor.Thickness = crt.NewCT_Thickness()
|
|
|
|
c.Floor.Thickness.ValAttr.Uint32 = gooxml.Uint32(0)
|
|
|
|
|
|
|
|
c.SideWall = crt.NewCT_Surface()
|
|
|
|
c.SideWall.Thickness = crt.NewCT_Thickness()
|
|
|
|
c.SideWall.Thickness.ValAttr.Uint32 = gooxml.Uint32(0)
|
|
|
|
|
|
|
|
c.BackWall = crt.NewCT_Surface()
|
|
|
|
c.BackWall.Thickness = crt.NewCT_Thickness()
|
|
|
|
c.BackWall.Thickness.ValAttr.Uint32 = gooxml.Uint32(0)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddLine3DChart adds a new 3D line chart to a chart.
|
2017-09-05 20:20:00 -04:00
|
|
|
func (c Chart) AddLine3DChart() Line3DChart {
|
2017-09-06 16:52:39 -04:00
|
|
|
setup3DChart(c.x.Chart)
|
2017-09-05 20:20:00 -04:00
|
|
|
chc := crt.NewCT_PlotAreaChoice()
|
|
|
|
c.x.Chart.PlotArea.Choice = append(c.x.Chart.PlotArea.Choice, chc)
|
|
|
|
chc.Line3DChart = crt.NewCT_Line3DChart()
|
|
|
|
chc.Line3DChart.Grouping = crt.NewCT_Grouping()
|
|
|
|
chc.Line3DChart.Grouping.ValAttr = crt.ST_GroupingStandard
|
|
|
|
return Line3DChart{x: chc.Line3DChart}
|
|
|
|
}
|
|
|
|
|
2017-09-04 15:32:59 -05:00
|
|
|
// AddBarChart adds a new bar chart to a chart.
|
|
|
|
func (c Chart) AddBarChart() BarChart {
|
|
|
|
chc := crt.NewCT_PlotAreaChoice()
|
|
|
|
c.x.Chart.PlotArea.Choice = append(c.x.Chart.PlotArea.Choice, chc)
|
|
|
|
chc.BarChart = crt.NewCT_BarChart()
|
|
|
|
chc.BarChart.Grouping = crt.NewCT_BarGrouping()
|
|
|
|
chc.BarChart.Grouping.ValAttr = crt.ST_BarGroupingStandard
|
|
|
|
|
2017-09-04 16:01:26 -05:00
|
|
|
b := BarChart{x: chc.BarChart}
|
|
|
|
b.InitializeDefaults()
|
|
|
|
return b
|
2017-09-04 15:32:59 -05:00
|
|
|
}
|
|
|
|
|
2017-09-06 16:52:39 -04:00
|
|
|
// AddBar3DChart adds a new 3D bar chart to a chart.
|
|
|
|
func (c Chart) AddBar3DChart() Bar3DChart {
|
|
|
|
setup3DChart(c.x.Chart)
|
|
|
|
chc := crt.NewCT_PlotAreaChoice()
|
|
|
|
c.x.Chart.PlotArea.Choice = append(c.x.Chart.PlotArea.Choice, chc)
|
|
|
|
chc.Bar3DChart = crt.NewCT_Bar3DChart()
|
|
|
|
chc.Bar3DChart.Grouping = crt.NewCT_BarGrouping()
|
|
|
|
chc.Bar3DChart.Grouping.ValAttr = crt.ST_BarGroupingStandard
|
|
|
|
|
|
|
|
b := Bar3DChart{x: chc.Bar3DChart}
|
|
|
|
b.InitializeDefaults()
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
2017-09-06 17:02:21 -04:00
|
|
|
// AddAreaChart adds a new area chart to a chart.
|
|
|
|
func (c Chart) AddAreaChart() AreaChart {
|
|
|
|
chc := crt.NewCT_PlotAreaChoice()
|
|
|
|
c.x.Chart.PlotArea.Choice = append(c.x.Chart.PlotArea.Choice, chc)
|
|
|
|
chc.AreaChart = crt.NewCT_AreaChart()
|
|
|
|
|
|
|
|
b := AreaChart{x: chc.AreaChart}
|
|
|
|
b.InitializeDefaults()
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
2017-09-06 17:04:42 -04:00
|
|
|
// AddArea3DChart adds a new area chart to a chart.
|
|
|
|
func (c Chart) AddArea3DChart() Area3DChart {
|
|
|
|
setup3DChart(c.x.Chart)
|
|
|
|
chc := crt.NewCT_PlotAreaChoice()
|
|
|
|
c.x.Chart.PlotArea.Choice = append(c.x.Chart.PlotArea.Choice, chc)
|
|
|
|
chc.Area3DChart = crt.NewCT_Area3DChart()
|
|
|
|
|
|
|
|
b := Area3DChart{x: chc.Area3DChart}
|
|
|
|
b.InitializeDefaults()
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
2017-09-06 17:24:30 -04:00
|
|
|
// AddRadarChart adds a new radar chart to a chart.
|
|
|
|
func (c Chart) AddRadarChart() RadarChart {
|
|
|
|
chc := crt.NewCT_PlotAreaChoice()
|
|
|
|
c.x.Chart.PlotArea.Choice = append(c.x.Chart.PlotArea.Choice, chc)
|
|
|
|
chc.RadarChart = crt.NewCT_RadarChart()
|
|
|
|
|
|
|
|
b := RadarChart{x: chc.RadarChart}
|
|
|
|
b.InitializeDefaults()
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
2017-09-06 17:33:34 -04:00
|
|
|
// AddPieChart adds a new pie chart to a chart.
|
|
|
|
func (c Chart) AddPieChart() PieChart {
|
|
|
|
chc := crt.NewCT_PlotAreaChoice()
|
|
|
|
c.x.Chart.PlotArea.Choice = append(c.x.Chart.PlotArea.Choice, chc)
|
|
|
|
chc.PieChart = crt.NewCT_PieChart()
|
|
|
|
|
|
|
|
b := PieChart{x: chc.PieChart}
|
|
|
|
b.InitializeDefaults()
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
2017-09-06 17:36:49 -04:00
|
|
|
// AddPie3DChart adds a new pie chart to a chart.
|
|
|
|
func (c Chart) AddPie3DChart() Pie3DChart {
|
|
|
|
setup3DChart(c.x.Chart)
|
|
|
|
chc := crt.NewCT_PlotAreaChoice()
|
|
|
|
c.x.Chart.PlotArea.Choice = append(c.x.Chart.PlotArea.Choice, chc)
|
|
|
|
chc.Pie3DChart = crt.NewCT_Pie3DChart()
|
|
|
|
|
|
|
|
b := Pie3DChart{x: chc.Pie3DChart}
|
|
|
|
b.InitializeDefaults()
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
2017-09-05 07:56:59 -05:00
|
|
|
// Properties returns the chart's shape properties.
|
2017-09-04 10:50:29 -05:00
|
|
|
func (c Chart) Properties() drawing.ShapeProperties {
|
|
|
|
if c.x.SpPr == nil {
|
|
|
|
c.x.SpPr = dml.NewCT_ShapeProperties()
|
|
|
|
}
|
|
|
|
return drawing.MakeShapeProperties(c.x.SpPr)
|
|
|
|
}
|
|
|
|
|
2017-09-05 07:56:59 -05:00
|
|
|
// SetDisplayBlanksAs controls how missing values are displayed.
|
2017-09-04 10:50:29 -05:00
|
|
|
func (c Chart) SetDisplayBlanksAs(v crt.ST_DispBlanksAs) {
|
|
|
|
c.x.Chart.DispBlanksAs = crt.NewCT_DispBlanksAs()
|
|
|
|
c.x.Chart.DispBlanksAs.ValAttr = v
|
|
|
|
}
|
|
|
|
|
2017-09-05 07:56:59 -05:00
|
|
|
// AddValueAxis adds a value axis to the chart.
|
2017-09-04 15:32:59 -05:00
|
|
|
func (c Chart) AddValueAxis() ValueAxis {
|
2017-09-04 10:50:29 -05:00
|
|
|
va := crt.NewCT_ValAx()
|
|
|
|
if c.x.Chart.PlotArea.CChoice == nil {
|
|
|
|
c.x.Chart.PlotArea.CChoice = crt.NewCT_PlotAreaChoice1()
|
|
|
|
}
|
|
|
|
va.AxId = crt.NewCT_UnsignedInt()
|
|
|
|
va.AxId.ValAttr = 0x7FFFFFFF & rand.Uint32()
|
|
|
|
c.x.Chart.PlotArea.CChoice.ValAx = append(c.x.Chart.PlotArea.CChoice.ValAx, va)
|
|
|
|
|
|
|
|
va.Delete = crt.NewCT_Boolean()
|
|
|
|
va.Delete.ValAttr = gooxml.Bool(false)
|
|
|
|
|
|
|
|
va.Scaling = crt.NewCT_Scaling()
|
|
|
|
va.Scaling.Orientation = crt.NewCT_Orientation()
|
|
|
|
va.Scaling.Orientation.ValAttr = crt.ST_OrientationMinMax
|
|
|
|
|
|
|
|
va.Choice = &crt.EG_AxSharedChoice{}
|
|
|
|
va.Choice.Crosses = crt.NewCT_Crosses()
|
|
|
|
va.Choice.Crosses.ValAttr = crt.ST_CrossesAutoZero
|
|
|
|
|
|
|
|
va.CrossBetween = crt.NewCT_CrossBetween()
|
|
|
|
va.CrossBetween.ValAttr = crt.ST_CrossBetweenMidCat
|
|
|
|
|
2017-09-04 15:32:59 -05:00
|
|
|
vax := MakeValueAxis(va)
|
2017-09-04 10:50:29 -05:00
|
|
|
vax.MajorGridLines().Properties().LineProperties().SetSolidFill(color.LightGray)
|
|
|
|
vax.SetMajorTickMark(crt.ST_TickMarkOut)
|
|
|
|
vax.SetMinorTickMark(crt.ST_TickMarkIn)
|
|
|
|
vax.SetTickLabelPosition(crt.ST_TickLblPosNextTo)
|
|
|
|
vax.Properties().LineProperties().SetSolidFill(color.Black)
|
|
|
|
|
|
|
|
vax.SetPosition(crt.ST_AxPosL)
|
|
|
|
return vax
|
|
|
|
}
|
|
|
|
|
2017-09-05 07:56:59 -05:00
|
|
|
// AddCategoryAxis adds a category axis.
|
2017-09-04 15:32:59 -05:00
|
|
|
func (c Chart) AddCategoryAxis() CategoryAxis {
|
2017-09-04 10:50:29 -05:00
|
|
|
ca := crt.NewCT_CatAx()
|
|
|
|
if c.x.Chart.PlotArea.CChoice == nil {
|
|
|
|
c.x.Chart.PlotArea.CChoice = crt.NewCT_PlotAreaChoice1()
|
|
|
|
}
|
|
|
|
|
|
|
|
ca.AxId = crt.NewCT_UnsignedInt()
|
|
|
|
ca.AxId.ValAttr = 0x7FFFFFFF & rand.Uint32()
|
|
|
|
c.x.Chart.PlotArea.CChoice.CatAx = append(c.x.Chart.PlotArea.CChoice.CatAx, ca)
|
|
|
|
|
|
|
|
ca.Auto = crt.NewCT_Boolean()
|
|
|
|
ca.Auto.ValAttr = gooxml.Bool(true)
|
|
|
|
|
|
|
|
ca.Delete = crt.NewCT_Boolean()
|
|
|
|
ca.Delete.ValAttr = gooxml.Bool(false)
|
|
|
|
|
2017-09-04 15:32:59 -05:00
|
|
|
cax := MakeCategoryAxis(ca)
|
2017-09-04 10:50:29 -05:00
|
|
|
cax.InitializeDefaults()
|
|
|
|
|
|
|
|
return cax
|
|
|
|
}
|
|
|
|
|
2017-09-05 20:20:00 -04:00
|
|
|
func (c Chart) AddSeriesAxis() SeriesAxis {
|
|
|
|
sa := crt.NewCT_SerAx()
|
|
|
|
if c.x.Chart.PlotArea.CChoice == nil {
|
|
|
|
c.x.Chart.PlotArea.CChoice = crt.NewCT_PlotAreaChoice1()
|
|
|
|
}
|
|
|
|
|
|
|
|
sa.AxId = crt.NewCT_UnsignedInt()
|
|
|
|
sa.AxId.ValAttr = 0x7FFFFFFF & rand.Uint32()
|
|
|
|
c.x.Chart.PlotArea.CChoice.SerAx = append(c.x.Chart.PlotArea.CChoice.SerAx, sa)
|
|
|
|
|
|
|
|
sa.Delete = crt.NewCT_Boolean()
|
|
|
|
sa.Delete.ValAttr = gooxml.Bool(false)
|
|
|
|
|
|
|
|
sax := MakeSeriesAxis(sa)
|
|
|
|
sax.InitializeDefaults()
|
|
|
|
|
|
|
|
return sax
|
|
|
|
}
|
|
|
|
|
2017-09-04 10:50:29 -05:00
|
|
|
// RemoveLegend removes the legend if the chart has one.
|
|
|
|
func (c Chart) RemoveLegend() {
|
|
|
|
c.x.Chart.Legend = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddLegend adds a legend to a chart, replacing any existing legend.
|
2017-09-04 15:32:59 -05:00
|
|
|
func (c Chart) AddLegend() Legend {
|
2017-09-04 10:50:29 -05:00
|
|
|
c.x.Chart.Legend = crt.NewCT_Legend()
|
2017-09-04 15:32:59 -05:00
|
|
|
leg := MakeLegend(c.x.Chart.Legend)
|
2017-09-04 10:50:29 -05:00
|
|
|
leg.InitializeDefaults()
|
|
|
|
return leg
|
|
|
|
}
|
|
|
|
|
2017-09-05 07:56:59 -05:00
|
|
|
// RemoveTitle removes any existing title from the chart.
|
2017-09-04 10:50:29 -05:00
|
|
|
func (c Chart) RemoveTitle() {
|
|
|
|
c.x.Chart.Title = nil
|
|
|
|
c.x.Chart.AutoTitleDeleted = crt.NewCT_Boolean()
|
|
|
|
c.x.Chart.AutoTitleDeleted.ValAttr = gooxml.Bool(true)
|
|
|
|
}
|
|
|
|
|
2017-09-05 07:56:59 -05:00
|
|
|
// AddTitle sets a new title on the chart.
|
2017-09-04 15:32:59 -05:00
|
|
|
func (c Chart) AddTitle() Title {
|
2017-09-04 10:50:29 -05:00
|
|
|
c.x.Chart.Title = crt.NewCT_Title()
|
|
|
|
c.x.Chart.Title.Overlay = crt.NewCT_Boolean()
|
|
|
|
c.x.Chart.Title.Overlay.ValAttr = gooxml.Bool(false)
|
|
|
|
|
|
|
|
c.x.Chart.AutoTitleDeleted = crt.NewCT_Boolean()
|
|
|
|
c.x.Chart.AutoTitleDeleted.ValAttr = gooxml.Bool(false)
|
|
|
|
|
2017-09-04 15:32:59 -05:00
|
|
|
title := MakeTitle(c.x.Chart.Title)
|
2017-09-04 10:50:29 -05:00
|
|
|
title.InitializeDefaults()
|
|
|
|
return title
|
|
|
|
}
|