From 0b87455cc29146d684ef0ede8990a94d6d0fefd3 Mon Sep 17 00:00:00 2001 From: Jamie Schouten Date: Sun, 19 Jan 2025 22:56:58 +0100 Subject: [PATCH] Add step line (#13) --- README.md | 4 + examples/output/simple-step-chart.svg | 20 ++++ examples/simple-step-chart.php | 36 +++++++ src/Line/Line.php | 29 +++++- tests/Unit/CurvedLineChartTest.php | 130 ++++++++++++++++++++++++++ tests/Unit/StepLineChartTest.php | 130 ++++++++++++++++++++++++++ 6 files changed, 347 insertions(+), 2 deletions(-) create mode 100644 examples/output/simple-step-chart.svg create mode 100644 examples/simple-step-chart.php create mode 100644 tests/Unit/CurvedLineChartTest.php create mode 100644 tests/Unit/StepLineChartTest.php diff --git a/README.md b/README.md index 0caddea..869bb71 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,10 @@ Below are some examples of the types of charts you can create using this library ![alt text](./examples/output/simple-curved-chart.svg) [View source](./examples/simple-curved-chart.php) +### Step line chart +![alt text](./examples/output/simple-step-chart.svg) +[View source](./examples/simple-step-chart.php) + ### Simple bar chart ![alt text](./examples/output/simple-bar-chart.svg) [View source](./examples/simple-bar-chart.php) diff --git a/examples/output/simple-step-chart.svg b/examples/output/simple-step-chart.svg new file mode 100644 index 0000000..f9363aa --- /dev/null +++ b/examples/output/simple-step-chart.svg @@ -0,0 +1,20 @@ + + + 022446688110 + 0 +50 +100 +150 +200 +250 +300 +350 +400 +450 + + + + +152520453565558575110 + + \ No newline at end of file diff --git a/examples/simple-step-chart.php b/examples/simple-step-chart.php new file mode 100644 index 0000000..cbf596e --- /dev/null +++ b/examples/simple-step-chart.php @@ -0,0 +1,36 @@ +render(); diff --git a/src/Line/Line.php b/src/Line/Line.php index 03c7063..86e1144 100644 --- a/src/Line/Line.php +++ b/src/Line/Line.php @@ -17,7 +17,8 @@ public function __construct( public int $size = 5, public ?string $yAxis = null, public string $lineColor = 'black', - public ?float $curve = null + public ?float $curve = null, + public bool $stepLine = false, ) {} public function render(Chart $chart): string @@ -36,7 +37,9 @@ public function render(Chart $chart): string $pointsSvg .= $point->render($x, $y); } - $d = $this->generateSmoothPath($points, $this->curve); + $d = $this->stepLine + ? $this->generateStepPath($points) + : $this->generateSmoothPath($points, $this->curve); return new Fragment([ new Path( @@ -90,4 +93,26 @@ public function generateSmoothPath(array $points, ?float $curveFactor = null): s return $d; } + + /** + * @param array{float, float}[] $points + */ + public function generateStepPath(array $points): string + { + if (count($points) < 2) { + return ''; + } + + $d = "M {$points[0][0]},{$points[0][1]}"; + + for ($i = 1; $i < count($points); $i++) { + $current = $points[$i]; + + $d .= " H {$current[0]}"; + + $d .= " V {$current[1]}"; + } + + return $d; + } } diff --git a/tests/Unit/CurvedLineChartTest.php b/tests/Unit/CurvedLineChartTest.php new file mode 100644 index 0000000..5b08298 --- /dev/null +++ b/tests/Unit/CurvedLineChartTest.php @@ -0,0 +1,130 @@ + +render()))->toBe(<<<'SVG' + + + + + 0 + 5 + 10 + 14 + 19 + 24 + + + 0 + + 100 + + 200 + + 300 + + + + + + + + + + + 0 + + + 4 + + + 12 + + + 8 + + + + 4 + + + 12 + + + 24 + + + 7 + + +SVG + ); +}); + +it('renders empty line chart', function () { + $chart = new Chart( + series: [ + new Lines( + lines: [] + ), + ], + ); + + $svg = <<<'SVG' + + + + + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + + +SVG; + + expect(pretty($chart->render()))->toBe($svg); +}); diff --git a/tests/Unit/StepLineChartTest.php b/tests/Unit/StepLineChartTest.php new file mode 100644 index 0000000..1e53001 --- /dev/null +++ b/tests/Unit/StepLineChartTest.php @@ -0,0 +1,130 @@ + +render()))->toBe(<<<'SVG' + + + + + 0 + 5 + 10 + 14 + 19 + 24 + + + 0 + + 100 + + 200 + + 300 + + + + + + + + + + + 0 + + + 4 + + + 12 + + + 8 + + + + 4 + + + 12 + + + 24 + + + 7 + + +SVG + ); +}); + +it('renders empty line chart', function () { + $chart = new Chart( + series: [ + new Lines( + lines: [] + ), + ], + ); + + $svg = <<<'SVG' + + + + + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + + +SVG; + + expect(pretty($chart->render()))->toBe($svg); +});