diff --git a/bar_series.go b/bar_series.go new file mode 100644 index 0000000..847fbe4 --- /dev/null +++ b/bar_series.go @@ -0,0 +1,59 @@ +// MIT License + +// Copyright (c) 2021 Tree Xie + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package charts + +import "github.com/wcharczuk/go-chart/v2" + +type BarSeries struct { + BaseSeries +} + +func (bs BarSeries) Render(r chart.Renderer, canvasBox chart.Box, xrange, yrange chart.Range, defaults chart.Style) { + if bs.Len() == 0 { + return + } + style := bs.Style.InheritFrom(defaults) + style.FillColor = style.StrokeColor + if !style.ShouldDrawStroke() { + return + } + + cb := canvasBox.Bottom + cl := canvasBox.Left + + for i := 0; i < bs.Len(); i++ { + vx, vy := bs.GetValues(i) + + x := cl + xrange.Translate(vx) + y := cb - yrange.Translate(vy) + + chart.Draw.Box(r, chart.Box{ + Left: x, + Top: y, + // TODO 计算宽度 + Right: x + 10, + Bottom: canvasBox.Bottom - 1, + }, style) + } + +} diff --git a/base_series.go b/base_series.go new file mode 100644 index 0000000..86e0659 --- /dev/null +++ b/base_series.go @@ -0,0 +1,121 @@ +// MIT License + +// Copyright (c) 2021 Tree Xie + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package charts + +import ( + "fmt" + + "github.com/wcharczuk/go-chart/v2" +) + +// Interface Assertions. +var ( + _ chart.Series = (*BaseSeries)(nil) + _ chart.FirstValuesProvider = (*BaseSeries)(nil) + _ chart.LastValuesProvider = (*BaseSeries)(nil) +) + +// BaseSeries represents a line on a chart. +type BaseSeries struct { + Name string + Style chart.Style + + YAxis chart.YAxisType + + XValueFormatter chart.ValueFormatter + YValueFormatter chart.ValueFormatter + + XValues []float64 + YValues []float64 +} + +// GetName returns the name of the time series. +func (cs BaseSeries) GetName() string { + return cs.Name +} + +// GetStyle returns the line style. +func (cs BaseSeries) GetStyle() chart.Style { + return cs.Style +} + +// Len returns the number of elements in the series. +func (cs BaseSeries) Len() int { + return len(cs.XValues) +} + +// GetValues gets the x,y values at a given index. +func (cs BaseSeries) GetValues(index int) (float64, float64) { + return cs.XValues[index], cs.YValues[index] +} + +// GetFirstValues gets the first x,y values. +func (cs BaseSeries) GetFirstValues() (float64, float64) { + return cs.XValues[0], cs.YValues[0] +} + +// GetLastValues gets the last x,y values. +func (cs BaseSeries) GetLastValues() (float64, float64) { + return cs.XValues[len(cs.XValues)-1], cs.YValues[len(cs.YValues)-1] +} + +// GetValueFormatters returns value formatter defaults for the series. +func (cs BaseSeries) GetValueFormatters() (x, y chart.ValueFormatter) { + if cs.XValueFormatter != nil { + x = cs.XValueFormatter + } else { + x = chart.FloatValueFormatter + } + if cs.YValueFormatter != nil { + y = cs.YValueFormatter + } else { + y = chart.FloatValueFormatter + } + return +} + +// GetYAxis returns which YAxis the series draws on. +func (cs BaseSeries) GetYAxis() chart.YAxisType { + return cs.YAxis +} + +// Render renders the series. +func (cs BaseSeries) Render(r chart.Renderer, canvasBox chart.Box, xrange, yrange chart.Range, defaults chart.Style) { + fmt.Println("should be override the function") +} + +// Validate validates the series. +func (cs BaseSeries) Validate() error { + if len(cs.XValues) == 0 { + return fmt.Errorf("continuous series; must have xvalues set") + } + + if len(cs.YValues) == 0 { + return fmt.Errorf("continuous series; must have yvalues set") + } + + if len(cs.XValues) != len(cs.YValues) { + return fmt.Errorf("continuous series; must have same length xvalues as yvalues") + } + return nil +} diff --git a/series.go b/series.go index c3c0385..bc05d06 100644 --- a/series.go +++ b/series.go @@ -37,6 +37,11 @@ type Series struct { const lineStrokeWidth = 2 const dotWith = 2 +const ( + SeriesBar = "bar" + SeriesLine = "line" +) + func getSeriesColor(theme string, index int) drawing.Color { // TODO if theme == ThemeDark { @@ -47,17 +52,30 @@ func getSeriesColor(theme string, index int) drawing.Color { func GetSeries(series []Series, theme string) []chart.Series { arr := make([]chart.Series, len(series)) for index, item := range series { + style := chart.Style{ + StrokeWidth: lineStrokeWidth, + StrokeColor: getSeriesColor(theme, index), + DotColor: getSeriesColor(theme, index), + DotWidth: dotWith, + } // TODO 判断类型 - arr[index] = chart.ContinuousSeries{ - Name: item.Name, - XValues: item.XValues, - Style: chart.Style{ - StrokeWidth: lineStrokeWidth, - StrokeColor: getSeriesColor(theme, index), - DotColor: getSeriesColor(theme, index), - DotWidth: dotWith, - }, - YValues: item.Data, + switch item.Type { + case SeriesBar: + arr[index] = BarSeries{ + BaseSeries: BaseSeries{ + Name: item.Name, + XValues: item.XValues, + Style: style, + YValues: item.Data, + }, + } + default: + arr[index] = chart.ContinuousSeries{ + Name: item.Name, + XValues: item.XValues, + Style: style, + YValues: item.Data, + } } } return arr