diff --git a/draw.go b/draw.go index e188079..0fc744c 100644 --- a/draw.go +++ b/draw.go @@ -47,12 +47,26 @@ func (d draw) LineSeries(r Renderer, canvasBox Box, xrange, yrange Range, style if style.ShouldDrawStroke() { style.GetStrokeOptions().WriteDrawingOptionsToRenderer(r) + vxprev := 0.0 + if vs.Len() > 0 { + vxprev, _ = vs.GetValues( 1 ) // make sure vxprev starts at the beginning + } + maxspan := style.GetStrokeMaxSpanGap() r.MoveTo(x0, y0) for i := 1; i < vs.Len(); i++ { vx, vy = vs.GetValues(i) x = cl + xrange.Translate(vx) - y = cb - yrange.Translate(vy) - r.LineTo(x, y) + y = cb - yrange.Translate(vy) + df := vxprev - vx + if df < 0 { + df *= -1 // make it work, regardless of direction ox X-axis + } + if df <= maxspan { // span the gap i.e. connect the two points + r.LineTo(x, y) + } else { // do not span the gap + r.MoveTo(x, y) + } + vxprev = vx } r.Stroke() } diff --git a/examples/custom_styles/main.go b/examples/custom_styles/main.go index 08889ea..93abf51 100644 --- a/examples/custom_styles/main.go +++ b/examples/custom_styles/main.go @@ -25,9 +25,10 @@ func main() { Style: chart.Style{ StrokeColor: drawing.ColorRed, // will supercede defaults FillColor: drawing.ColorRed.WithAlpha(64), // will supercede defaults + StrokeMaxSpanGap: 2, // do not span gaps more than 2.0 wide }, - XValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0}, - YValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0}, + XValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0, 8.0, 10.0}, + YValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0, 8.0, 10.0}, }, }, } diff --git a/examples/custom_styles/output.png b/examples/custom_styles/output.png index 981745d..34b6ef3 100644 Binary files a/examples/custom_styles/output.png and b/examples/custom_styles/output.png differ diff --git a/style.go b/style.go index c601d6d..d604a8f 100644 --- a/style.go +++ b/style.go @@ -51,6 +51,7 @@ type Style struct { StrokeWidth float64 StrokeColor drawing.Color StrokeDashArray []float64 + StrokeMaxSpanGap float64 // in xvalue unit, nano second for timeseries DotColor drawing.Color DotWidth float64 @@ -122,6 +123,12 @@ func (s Style) String() string { output = append(output, "\"stroke_color\": null") } + if s.StrokeMaxSpanGap >= 0 { + output = append(output, fmt.Sprintf("\"stroke_maxspangap\": %.02f", s.StrokeMaxSpanGap)) + } else { + output = append(output, "\"stroke_maxspangap\": null") + } + if len(s.StrokeDashArray) > 0 { var elements []string for _, v := range s.StrokeDashArray { @@ -194,6 +201,11 @@ func (s Style) GetStrokeColor(defaults ...drawing.Color) drawing.Color { return s.StrokeColor } +// GetStrokeMaxSpanGap returns the max span gap, smaller or equal gaps are connected, larger ones are not. +func (s Style) GetStrokeMaxSpanGap() float64 { + return s.StrokeMaxSpanGap +} + // GetFillColor returns the fill color. func (s Style) GetFillColor(defaults ...drawing.Color) drawing.Color { if s.FillColor.IsZero() { @@ -388,6 +400,7 @@ func (s Style) InheritFrom(defaults Style) (final Style) { final.StrokeColor = s.GetStrokeColor(defaults.StrokeColor) final.StrokeWidth = s.GetStrokeWidth(defaults.StrokeWidth) final.StrokeDashArray = s.GetStrokeDashArray(defaults.StrokeDashArray) + final.StrokeMaxSpanGap = s.GetStrokeMaxSpanGap() final.DotColor = s.GetDotColor(defaults.DotColor) final.DotWidth = s.GetDotWidth(defaults.DotWidth) @@ -416,6 +429,7 @@ func (s Style) GetStrokeOptions() Style { StrokeDashArray: s.StrokeDashArray, StrokeColor: s.StrokeColor, StrokeWidth: s.StrokeWidth, + StrokeMaxSpanGap:s.StrokeMaxSpanGap, } } @@ -443,7 +457,8 @@ func (s Style) GetFillAndStrokeOptions() Style { return Style{ ClassName: s.ClassName, StrokeDashArray: s.StrokeDashArray, - FillColor: s.FillColor, + StrokeMaxSpanGap:s.StrokeMaxSpanGap, + FillColor: s.FillColor, StrokeColor: s.StrokeColor, StrokeWidth: s.StrokeWidth, }