mirror of
https://github.com/unidoc/unioffice.git
synced 2025-04-25 13:48:53 +08:00
chart, drawing: start adding chart & drawing support
- Created chart, drawing packages for the chart/drawing stuff common between document type - Need to go back and clean up any drawing related document types after
This commit is contained in:
parent
dc920417d0
commit
0dae44f002
24
chart/axisdatasource.go
Normal file
24
chart/axisdatasource.go
Normal file
@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
package chart
|
||||
|
||||
import crt "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml/2006/chart"
|
||||
|
||||
type AxisDataSource struct {
|
||||
x *crt.CT_AxDataSource
|
||||
}
|
||||
|
||||
func MakeAxisDataSource(x *crt.CT_AxDataSource) AxisDataSource {
|
||||
return AxisDataSource{x}
|
||||
}
|
||||
|
||||
func (a AxisDataSource) SetReference(s string) {
|
||||
a.x.Choice = crt.NewCT_AxDataSourceChoice()
|
||||
a.x.Choice.StrRef = crt.NewCT_StrRef()
|
||||
a.x.Choice.StrRef.F = s
|
||||
}
|
61
chart/datalabels.go
Normal file
61
chart/datalabels.go
Normal file
@ -0,0 +1,61 @@
|
||||
// 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.
|
||||
|
||||
package chart
|
||||
|
||||
import (
|
||||
"baliance.com/gooxml"
|
||||
crt "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml/2006/chart"
|
||||
)
|
||||
|
||||
type DataLabels struct {
|
||||
x *crt.CT_DLbls
|
||||
}
|
||||
|
||||
func MakeDataLabels(x *crt.CT_DLbls) DataLabels {
|
||||
return DataLabels{x}
|
||||
}
|
||||
func (d DataLabels) ensureChoice() {
|
||||
if d.x.Choice == nil {
|
||||
d.x.Choice = crt.NewCT_DLblsChoice()
|
||||
}
|
||||
}
|
||||
func (d DataLabels) SetShowLegendKey(b bool) {
|
||||
d.ensureChoice()
|
||||
d.x.Choice.ShowLegendKey = crt.NewCT_Boolean()
|
||||
d.x.Choice.ShowLegendKey.ValAttr = gooxml.Bool(b)
|
||||
}
|
||||
|
||||
func (d DataLabels) SetShowValue(b bool) {
|
||||
d.ensureChoice()
|
||||
d.x.Choice.ShowVal = crt.NewCT_Boolean()
|
||||
d.x.Choice.ShowVal.ValAttr = gooxml.Bool(b)
|
||||
}
|
||||
|
||||
func (d DataLabels) SetShowCategoryName(b bool) {
|
||||
d.ensureChoice()
|
||||
d.x.Choice.ShowCatName = crt.NewCT_Boolean()
|
||||
d.x.Choice.ShowCatName.ValAttr = gooxml.Bool(b)
|
||||
}
|
||||
|
||||
func (d DataLabels) SetShowSeriesName(b bool) {
|
||||
d.ensureChoice()
|
||||
d.x.Choice.ShowSerName = crt.NewCT_Boolean()
|
||||
d.x.Choice.ShowSerName.ValAttr = gooxml.Bool(b)
|
||||
}
|
||||
|
||||
func (d DataLabels) SetShowPercent(b bool) {
|
||||
d.ensureChoice()
|
||||
d.x.Choice.ShowPercent = crt.NewCT_Boolean()
|
||||
d.x.Choice.ShowPercent.ValAttr = gooxml.Bool(b)
|
||||
}
|
||||
|
||||
func (d DataLabels) SetShowLeaderLines(b bool) {
|
||||
d.ensureChoice()
|
||||
d.x.Choice.ShowLeaderLines = crt.NewCT_Boolean()
|
||||
d.x.Choice.ShowLeaderLines.ValAttr = gooxml.Bool(b)
|
||||
}
|
47
chart/marker.go
Normal file
47
chart/marker.go
Normal file
@ -0,0 +1,47 @@
|
||||
// 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.
|
||||
|
||||
package chart
|
||||
|
||||
import (
|
||||
"baliance.com/gooxml/drawing"
|
||||
|
||||
dml "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml"
|
||||
crt "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml/2006/chart"
|
||||
)
|
||||
|
||||
type Marker struct {
|
||||
x *crt.CT_Marker
|
||||
}
|
||||
|
||||
func MakeMarker(x *crt.CT_Marker) Marker {
|
||||
return Marker{x}
|
||||
}
|
||||
|
||||
// X returns the inner wrapped XML type.
|
||||
func (m Marker) X() *crt.CT_Marker {
|
||||
return m.x
|
||||
}
|
||||
|
||||
func (m Marker) SetSymbol(s crt.ST_MarkerStyle) {
|
||||
if s == crt.ST_MarkerStyleUnset {
|
||||
m.x.Symbol = nil
|
||||
} else {
|
||||
m.x.Symbol = crt.NewCT_MarkerStyle()
|
||||
m.x.Symbol.ValAttr = s
|
||||
}
|
||||
}
|
||||
func (m Marker) SetSize(sz uint8) {
|
||||
m.x.Size = crt.NewCT_MarkerSize()
|
||||
m.x.Size.ValAttr = &sz
|
||||
}
|
||||
func (m Marker) Properties() drawing.ShapeProperties {
|
||||
if m.x.SpPr == nil {
|
||||
m.x.SpPr = dml.NewCT_ShapeProperties()
|
||||
}
|
||||
return drawing.MakeShapeProperties(m.x.SpPr)
|
||||
}
|
66
drawing/lineproperties.go
Normal file
66
drawing/lineproperties.go
Normal file
@ -0,0 +1,66 @@
|
||||
// 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.
|
||||
|
||||
package drawing
|
||||
|
||||
import (
|
||||
"baliance.com/gooxml"
|
||||
"baliance.com/gooxml/color"
|
||||
"baliance.com/gooxml/measurement"
|
||||
dml "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml"
|
||||
)
|
||||
|
||||
type LineProperties struct {
|
||||
x *dml.CT_LineProperties
|
||||
}
|
||||
|
||||
// X returns the inner wrapped XML type.
|
||||
func (l LineProperties) X() *dml.CT_LineProperties {
|
||||
return l.x
|
||||
}
|
||||
|
||||
// SetWidth sets the line width, MS products treat zero as the minimum width
|
||||
// that can be displayed.
|
||||
func (l LineProperties) SetWidth(w measurement.Distance) {
|
||||
// TODO: check these units, can't find documentation on them but this seems
|
||||
// to be the right range
|
||||
l.x.WAttr = gooxml.Int32(int32(w / measurement.EMU))
|
||||
}
|
||||
|
||||
func (l LineProperties) SetSolidFill(c color.Color) {
|
||||
l.x.NoFill = nil
|
||||
l.x.GradFill = nil
|
||||
l.x.PattFill = nil
|
||||
l.x.SolidFill = dml.NewCT_SolidColorFillProperties()
|
||||
l.x.SolidFill.SrgbClr = dml.NewCT_SRgbColor()
|
||||
l.x.SolidFill.SrgbClr.ValAttr = *c.AsRGBAString()
|
||||
}
|
||||
|
||||
// LineJoin is the type of line join
|
||||
type LineJoin byte
|
||||
|
||||
// LineJoin types
|
||||
const (
|
||||
LineJoinRound LineJoin = iota
|
||||
LineJoinBevel
|
||||
LineJoinMiter
|
||||
)
|
||||
|
||||
// SetJoin sets the line join style.
|
||||
func (l LineProperties) SetJoin(e LineJoin) {
|
||||
l.x.Round = nil
|
||||
l.x.Miter = nil
|
||||
l.x.Bevel = nil
|
||||
switch e {
|
||||
case LineJoinRound:
|
||||
l.x.Round = dml.NewCT_LineJoinRound()
|
||||
case LineJoinBevel:
|
||||
l.x.Bevel = dml.NewCT_LineJoinBevel()
|
||||
case LineJoinMiter:
|
||||
l.x.Miter = dml.NewCT_LineJoinMiterProperties()
|
||||
}
|
||||
}
|
40
drawing/shapeproperties.go
Normal file
40
drawing/shapeproperties.go
Normal file
@ -0,0 +1,40 @@
|
||||
// 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.
|
||||
|
||||
package drawing
|
||||
|
||||
import (
|
||||
"baliance.com/gooxml/color"
|
||||
|
||||
dml "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml"
|
||||
)
|
||||
|
||||
type ShapeProperties struct {
|
||||
x *dml.CT_ShapeProperties
|
||||
}
|
||||
|
||||
func MakeShapeProperties(x *dml.CT_ShapeProperties) ShapeProperties {
|
||||
return ShapeProperties{x}
|
||||
}
|
||||
|
||||
// X returns the inner wrapped XML type.
|
||||
func (s ShapeProperties) X() *dml.CT_ShapeProperties {
|
||||
return s.x
|
||||
}
|
||||
|
||||
func (s ShapeProperties) SetSolidFill(c color.Color) {
|
||||
s.x.SolidFill = dml.NewCT_SolidColorFillProperties()
|
||||
s.x.SolidFill.SrgbClr = dml.NewCT_SRgbColor()
|
||||
s.x.SolidFill.SrgbClr.ValAttr = *c.AsRGBAString()
|
||||
}
|
||||
|
||||
func (s ShapeProperties) LineProperties() LineProperties {
|
||||
if s.x.Ln == nil {
|
||||
s.x.Ln = dml.NewCT_LineProperties()
|
||||
}
|
||||
return LineProperties{s.x.Ln}
|
||||
}
|
@ -39,7 +39,7 @@ func RelativeFilename(dt DocType, typ string, index int) string {
|
||||
case StylesType:
|
||||
return "styles.xml"
|
||||
case ChartType:
|
||||
return fmt.Sprintf("charts/chart%d.xml", index)
|
||||
return fmt.Sprintf("../charts/chart%d.xml", index)
|
||||
case DrawingType:
|
||||
return fmt.Sprintf("drawings/drawing%d.xml", index)
|
||||
|
||||
|
28
spreadsheet/chart.go
Normal file
28
spreadsheet/chart.go
Normal file
@ -0,0 +1,28 @@
|
||||
// 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.
|
||||
|
||||
package spreadsheet
|
||||
|
||||
import crt "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml/2006/chart"
|
||||
|
||||
type Chart struct {
|
||||
x *crt.ChartSpace
|
||||
}
|
||||
|
||||
// X returns the inner wrapped XML type.
|
||||
func (c Chart) X() *crt.ChartSpace {
|
||||
return c.x
|
||||
}
|
||||
|
||||
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
|
||||
return LineChart{chc.LineChart}
|
||||
}
|
54
spreadsheet/drawing.go
Normal file
54
spreadsheet/drawing.go
Normal file
@ -0,0 +1,54 @@
|
||||
// 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.
|
||||
|
||||
package spreadsheet
|
||||
|
||||
import (
|
||||
"baliance.com/gooxml"
|
||||
dml "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml"
|
||||
c "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml/2006/chart"
|
||||
crt "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml/2006/chart"
|
||||
sd "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
|
||||
)
|
||||
|
||||
type Drawing struct {
|
||||
wb *Workbook
|
||||
x *sd.WsDr
|
||||
}
|
||||
|
||||
// X returns the inner wrapped XML type.
|
||||
func (d Drawing) X() *sd.WsDr {
|
||||
return d.x
|
||||
}
|
||||
|
||||
func (d Drawing) AddChart() Chart {
|
||||
chart := crt.NewChartSpace()
|
||||
d.wb.charts = append(d.wb.charts, chart)
|
||||
|
||||
var chartID string
|
||||
// add relationship from drawing to the chart
|
||||
for i, dr := range d.wb.drawings {
|
||||
if dr == d.x {
|
||||
fn := gooxml.RelativeFilename(gooxml.DocTypeSpreadsheet, gooxml.ChartType, len(d.wb.charts))
|
||||
rel := d.wb.drawingRels[i].AddRelationship(fn, gooxml.ChartType)
|
||||
chartID = rel.ID()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// maybe use a one cell anchor?
|
||||
tca := sd.NewCT_TwoCellAnchor()
|
||||
d.x.EG_Anchor = []*sd.EG_Anchor{&sd.EG_Anchor{TwoCellAnchor: tca}}
|
||||
tca.Choice = &sd.EG_ObjectChoicesChoice{}
|
||||
tca.Choice.GraphicFrame = sd.NewCT_GraphicalObjectFrame()
|
||||
tca.Choice.GraphicFrame.Graphic = dml.NewGraphic()
|
||||
tca.Choice.GraphicFrame.Graphic.GraphicData.UriAttr = "http://schemas.openxmlformats.org/drawingml/2006/chart"
|
||||
c := c.NewChart()
|
||||
c.IdAttr = chartID
|
||||
tca.Choice.GraphicFrame.Graphic.GraphicData.Any = []gooxml.Any{c}
|
||||
return Chart{chart}
|
||||
}
|
36
spreadsheet/linechart.go
Normal file
36
spreadsheet/linechart.go
Normal file
@ -0,0 +1,36 @@
|
||||
// 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.
|
||||
|
||||
package spreadsheet
|
||||
|
||||
import (
|
||||
"baliance.com/gooxml/color"
|
||||
"baliance.com/gooxml/drawing"
|
||||
"baliance.com/gooxml/measurement"
|
||||
crt "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml/2006/chart"
|
||||
)
|
||||
|
||||
type LineChart struct {
|
||||
x *crt.CT_LineChart
|
||||
}
|
||||
|
||||
// X returns the inner wrapped XML type.
|
||||
func (c LineChart) X() *crt.CT_LineChart {
|
||||
return c.x
|
||||
}
|
||||
|
||||
func (c LineChart) AddSeries() LineChartSeries {
|
||||
ser := crt.NewCT_LineSer()
|
||||
c.x.Ser = append(c.x.Ser, ser)
|
||||
ser.Idx.ValAttr = uint32(len(c.x.Ser))
|
||||
ser.Order.ValAttr = uint32(len(c.x.Ser))
|
||||
ls := LineChartSeries{ser}
|
||||
ls.Properties().LineProperties().SetWidth(2 * measurement.Point)
|
||||
ls.Properties().LineProperties().SetSolidFill(color.Green)
|
||||
ls.Properties().LineProperties().SetJoin(drawing.LineJoinRound)
|
||||
return ls
|
||||
}
|
81
spreadsheet/linechartseries.go
Normal file
81
spreadsheet/linechartseries.go
Normal file
@ -0,0 +1,81 @@
|
||||
// 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.
|
||||
|
||||
package spreadsheet
|
||||
|
||||
import (
|
||||
"baliance.com/gooxml/chart"
|
||||
"baliance.com/gooxml/drawing"
|
||||
dml "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml"
|
||||
crt "baliance.com/gooxml/schema/schemas.openxmlformats.org/drawingml/2006/chart"
|
||||
)
|
||||
|
||||
type LineChartSeries struct {
|
||||
x *crt.CT_LineSer
|
||||
}
|
||||
|
||||
// X returns the inner wrapped XML type.
|
||||
func (c LineChartSeries) X() *crt.CT_LineSer {
|
||||
return c.x
|
||||
}
|
||||
|
||||
// Index returns the index of the series
|
||||
func (c LineChartSeries) Index() uint32 {
|
||||
return c.x.Idx.ValAttr
|
||||
}
|
||||
|
||||
// SetIndex sets the index of the series
|
||||
func (c LineChartSeries) SetIndex(idx uint32) {
|
||||
c.x.Idx.ValAttr = idx
|
||||
}
|
||||
|
||||
// Order returns the order of the series
|
||||
func (c LineChartSeries) Order() uint32 {
|
||||
return c.x.Order.ValAttr
|
||||
}
|
||||
|
||||
// SetOrder sets the order of the series
|
||||
func (c LineChartSeries) SetOrder(idx uint32) {
|
||||
c.x.Order.ValAttr = idx
|
||||
}
|
||||
|
||||
// SetText sets the series text
|
||||
func (c LineChartSeries) SetText(s string) {
|
||||
c.x.Tx = crt.NewCT_SerTx()
|
||||
c.x.Tx.Choice.V = &s
|
||||
}
|
||||
|
||||
// Properties returns the line chart series shape properties.
|
||||
func (c LineChartSeries) Properties() drawing.ShapeProperties {
|
||||
if c.x.SpPr == nil {
|
||||
c.x.SpPr = dml.NewCT_ShapeProperties()
|
||||
}
|
||||
return drawing.MakeShapeProperties(c.x.SpPr)
|
||||
}
|
||||
|
||||
// Marker returns the marker properties.
|
||||
func (c LineChartSeries) Marker() chart.Marker {
|
||||
if c.x.Marker == nil {
|
||||
c.x.Marker = crt.NewCT_Marker()
|
||||
}
|
||||
return chart.MakeMarker(c.x.Marker)
|
||||
}
|
||||
|
||||
// Labels returns the data label properties.
|
||||
func (c LineChartSeries) Labels() chart.DataLabels {
|
||||
if c.x.DLbls == nil {
|
||||
c.x.DLbls = crt.NewCT_DLbls()
|
||||
}
|
||||
return chart.MakeDataLabels(c.x.DLbls)
|
||||
}
|
||||
|
||||
func (c LineChartSeries) Axis() chart.AxisDataSource {
|
||||
if c.x.Cat == nil {
|
||||
c.x.Cat = crt.NewCT_AxDataSource()
|
||||
}
|
||||
return chart.MakeAxisDataSource(c.x.Cat)
|
||||
}
|
@ -295,3 +295,12 @@ func (wb *Workbook) onNewRelationship(decMap *zippkg.DecodeMap, target, typ stri
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wb *Workbook) AddDrawing() Drawing {
|
||||
drawing := sd.NewWsDr()
|
||||
wb.drawings = append(wb.drawings, drawing)
|
||||
fn := gooxml.AbsoluteFilename(gooxml.DocTypeSpreadsheet, gooxml.DrawingType, len(wb.drawings))
|
||||
wb.ContentTypes.AddOverride(fn, gooxml.DrawingType)
|
||||
wb.drawingRels = append(wb.drawingRels, common.NewRelationships())
|
||||
return Drawing{wb, drawing}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user