go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/nodes/pkg/funcs/scatter_chart.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package funcs 9 10 import ( 11 "bytes" 12 "context" 13 14 "github.com/wcharczuk/go-chart/v2" 15 "github.com/wcharczuk/go-chart/v2/drawing" 16 "go.charczuk.com/projects/nodes/pkg/types" 17 ) 18 19 // ScatterChart renders a chart to svg. 20 func ScatterChart(config ChartConfig) func(context.Context, []float64, []float64) (types.SVG, error) { 21 return func(ctx context.Context, xValues, yValues []float64) (types.SVG, error) { 22 if len(xValues) < 2 { 23 return types.SVG{}, nil 24 } 25 main, err := scatterMain(ctx, config, xValues, yValues) 26 if err != nil { 27 return types.SVG{}, err 28 } 29 thumbnail, err := scatterThumbnail(ctx, config, xValues, yValues) 30 if err != nil { 31 return types.SVG{}, err 32 } 33 return types.SVG{ 34 Main: main, 35 Thumbnail: thumbnail, 36 }, nil 37 } 38 } 39 40 func scatterMain(_ context.Context, config ChartConfig, xValues, yValues []float64) (string, error) { 41 primarySeries := chart.ContinuousSeries{ 42 Style: chart.Style{ 43 StrokeColor: chart.ColorBlue, 44 FillColor: chart.ColorBlue.WithAlpha(100), 45 }, 46 XValues: xValues, 47 YValues: yValues, 48 } 49 config.ApplyPrimaryContinuousSeries(&primarySeries) 50 51 var series []chart.Series 52 if !config.HideSeries { 53 series = append(series, primarySeries) 54 } 55 56 if !config.HideSeriesLastValue { 57 primarySeriesLastValue := chart.LastValueAnnotationSeries(primarySeries) 58 primarySeriesLastValue.Style.FillColor = drawing.ColorFromHex("252a31") 59 primarySeriesLastValue.Style.StrokeColor = drawing.ColorFromHex("2d72d2") 60 primarySeriesLastValue.Style.FontColor = drawing.ColorFromHex("abb3bf") 61 series = append(series, primarySeriesLastValue) 62 } 63 64 linRegSeries := &chart.LinearRegressionSeries{ 65 Style: chart.Style{ 66 StrokeColor: drawing.ColorFromHex("8E292C"), 67 }, 68 InnerSeries: primarySeries, 69 } 70 config.ApplyRegressionSeries(linRegSeries) 71 72 if !config.HideRegression { 73 series = append(series, linRegSeries) 74 } 75 if !config.HideRegressionLastValue { 76 linearRegLastValue := chart.LastValueAnnotationSeries(linRegSeries) 77 linearRegLastValue.Style.FillColor = drawing.ColorFromHex("252a31") 78 linearRegLastValue.Style.StrokeColor = drawing.ColorFromHex("8E292C") 79 linearRegLastValue.Style.FontColor = drawing.ColorFromHex("abb3bf") 80 series = append(series, linearRegLastValue) 81 } 82 83 c := chart.Chart{ 84 Width: 720, 85 Height: 405, 86 XAxis: chart.XAxis{ 87 TickStyle: chart.Style{ 88 StrokeColor: drawing.ColorFromHex("383e47"), 89 FontColor: drawing.ColorFromHex("abb3bf"), 90 }, 91 }, 92 YAxis: chart.YAxis{ 93 TickStyle: chart.Style{ 94 StrokeColor: drawing.ColorFromHex("383e47"), 95 FontColor: drawing.ColorFromHex("abb3bf"), 96 }, 97 }, 98 YAxisSecondary: chart.HideYAxis(), 99 Canvas: chart.Style{ 100 FillColor: drawing.ColorTransparent, 101 }, 102 Background: chart.Style{ 103 FillColor: drawing.ColorTransparent, 104 }, 105 Series: series, 106 } 107 config.ApplyChart(&c) 108 buf := new(bytes.Buffer) 109 if err := c.Render(chart.SVG, buf); err != nil { 110 return "", err 111 } 112 return buf.String(), nil 113 } 114 115 func scatterThumbnail(_ context.Context, config ChartConfig, xValues, yValues []float64) (string, error) { 116 primarySeries := chart.ContinuousSeries{ 117 Style: chart.Style{ 118 StrokeColor: chart.ColorBlue, 119 FillColor: chart.ColorBlue.WithAlpha(100), 120 }, 121 XValues: xValues, 122 YValues: yValues, 123 } 124 config.ApplyPrimaryContinuousSeries(&primarySeries) 125 126 c := chart.Chart{ 127 Width: 300, 128 Height: 100, 129 XAxis: chart.XAxis{ 130 Style: chart.Hidden(), 131 TickStyle: chart.Hidden(), 132 }, 133 YAxis: chart.YAxis{ 134 Style: chart.Hidden(), 135 TickStyle: chart.Hidden(), 136 }, 137 YAxisSecondary: chart.HideYAxis(), 138 Canvas: chart.Style{ 139 FillColor: drawing.ColorTransparent, 140 }, 141 Background: chart.Style{ 142 FillColor: drawing.ColorTransparent, 143 }, 144 Series: []chart.Series{ 145 primarySeries, 146 }, 147 } 148 buf := new(bytes.Buffer) 149 if err := c.Render(chart.SVG, buf); err != nil { 150 return "", err 151 } 152 return buf.String(), nil 153 }