mirror of
https://github.com/seigler/neat-charts
synced 2025-07-27 09:26:10 +00:00
switched to an options array
This commit is contained in:
parent
9e83c583d8
commit
1ed50094fd
3 changed files with 64 additions and 39 deletions
|
@ -2,7 +2,17 @@
|
||||||
|
|
||||||
class SVGChartBuilder {
|
class SVGChartBuilder {
|
||||||
|
|
||||||
public static function renderStockChart($chartData, $width = 700, $lineColor = "#FF2F00", $gridLabelColor = "#999", $smoothed = false) {
|
public static function renderStockChart($chartData, $options) {
|
||||||
|
function arrayGet($array, $key, $default = NULL)
|
||||||
|
{
|
||||||
|
return isset($array[$key]) ? $array[$key] : $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
$width = arrayGet($options, "width", 800) - 100;
|
||||||
|
$height = arrayGet($options, "height");
|
||||||
|
$lineColor = arrayGet($options, "lineColor", "#FF2F00");
|
||||||
|
$labelColor = arrayGet($options, "labelColor", "#999");
|
||||||
|
$smoothed = arrayGet($options, "smoothed", false);
|
||||||
// we assume $chartData is sorted by key and keys and values are all numeric
|
// we assume $chartData is sorted by key and keys and values are all numeric
|
||||||
$previousY = $previousY = null;
|
$previousY = $previousY = null;
|
||||||
end($chartData);
|
end($chartData);
|
||||||
|
@ -40,6 +50,7 @@ class SVGChartBuilder {
|
||||||
$yRange = $yMax - $yMin;
|
$yRange = $yMax - $yMin;
|
||||||
$averageAbsSlope /= $yRange * $deltaX; // turn this absolute-deltas total into a slope
|
$averageAbsSlope /= $yRange * $deltaX; // turn this absolute-deltas total into a slope
|
||||||
|
|
||||||
|
if ($smoothed) {
|
||||||
// take all these slopes and average them with their neighbors
|
// take all these slopes and average them with their neighbors
|
||||||
// unless they change direction, then make them zero
|
// unless they change direction, then make them zero
|
||||||
// also restrict them a bit when they are very different
|
// also restrict them a bit when they are very different
|
||||||
|
@ -68,6 +79,7 @@ class SVGChartBuilder {
|
||||||
$previousX = $x;
|
$previousX = $x;
|
||||||
$previousSecant = $secant;
|
$previousSecant = $secant;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We want the height of the median y-delta to be the same as
|
We want the height of the median y-delta to be the same as
|
||||||
|
@ -114,6 +126,7 @@ class SVGChartBuilder {
|
||||||
transformX($x, $xMin, $xRange, $width).",".
|
transformX($x, $xMin, $xRange, $width).",".
|
||||||
transformY($y, $yMax, $yRange, $height) . "\n";
|
transformY($y, $yMax, $yRange, $height) . "\n";
|
||||||
|
|
||||||
|
if ($smoothed) {
|
||||||
$controlX = $deltaX / 3 / sqrt(1 + $tangents[$x]**2);
|
$controlX = $deltaX / 3 / sqrt(1 + $tangents[$x]**2);
|
||||||
$controlY = $tangents[$x] * $controlX;
|
$controlY = $tangents[$x] * $controlX;
|
||||||
if ($x != $xMin) {
|
if ($x != $xMin) {
|
||||||
|
@ -124,8 +137,9 @@ class SVGChartBuilder {
|
||||||
transformY($y, $yMax, $yRange, $height);
|
transformY($y, $yMax, $yRange, $height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$numLabels = 1 + ceil($height / 60);
|
$numLabels = 2 + ceil($height / 60);
|
||||||
$labelInterval = $yRange / $numLabels;
|
$labelInterval = $yRange / $numLabels;
|
||||||
$labelModulation = 10 ** (1 + floor(-log($yRange / $numLabels, 10)));
|
$labelModulation = 10 ** (1 + floor(-log($yRange / $numLabels, 10)));
|
||||||
|
|
||||||
|
@ -192,7 +206,7 @@ class SVGChartBuilder {
|
||||||
.chart__gridLines {
|
.chart__gridLines {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
font-size: 10;
|
font-size: 10;
|
||||||
fill: '.( $gridLabelColor ).';
|
fill: '.( $labelColor ).';
|
||||||
text-anchor: end;
|
text-anchor: end;
|
||||||
shape-rendering: crispEdges;
|
shape-rendering: crispEdges;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ spl_autoload_register(function ($class_name) {
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
|
|
||||||
$offset = 100 * (rand()/getRandMax())**4;
|
$offset = 100 * (rand()/getRandMax())**4;
|
||||||
$scale = 100 * (rand()/getRandMax())**4;
|
$scale = 100 * (rand()/getRandMax())**2;
|
||||||
$volatility = 0.5 * (rand()/getRandMax())**3;
|
$volatility = 0.5 * (rand()/getRandMax())**3;
|
||||||
|
|
||||||
for ($n = 0, $current = $offset + 0.5 * $scale; $n < 96; $n++) {
|
for ($n = 0, $current = $offset + 0.5 * $scale; $n < 96; $n++) {
|
||||||
|
@ -30,4 +30,10 @@ for ($n = 0, $current = $offset + 0.5 * $scale; $n < 96; $n++) {
|
||||||
$chartData[$n] = $current;
|
$chartData[$n] = $current;
|
||||||
}
|
}
|
||||||
|
|
||||||
print SVGChartBuilder::renderStockChart($chartData, 1000, "#708", "#777", false);
|
print SVGChartBuilder::renderStockChart($chartData, [
|
||||||
|
'width'=>1000,
|
||||||
|
'height'=>250,
|
||||||
|
'lineColor'=>"#708",
|
||||||
|
'labelColor'=>"#777",
|
||||||
|
'smoothed'=>false
|
||||||
|
]);
|
||||||
|
|
|
@ -20,7 +20,7 @@ spl_autoload_register(function ($class_name) {
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
|
|
||||||
$start = 100 * (rand()/getRandMax())**3;
|
$start = 100 * (rand()/getRandMax())**3;
|
||||||
$volatility = rand()/getRandMax();
|
$volatility = rand()/getRandMax() + 0.01;
|
||||||
$velocity = (rand()/getRandMax() - 0.5);
|
$velocity = (rand()/getRandMax() - 0.5);
|
||||||
$acceleration = 0.1 * (rand()/getRandMax())**2;
|
$acceleration = 0.1 * (rand()/getRandMax())**2;
|
||||||
|
|
||||||
|
@ -31,4 +31,9 @@ for ($n = 0, $current = $start; $n < 24; $n++) {
|
||||||
$chartData[$n] = $current;
|
$chartData[$n] = $current;
|
||||||
}
|
}
|
||||||
|
|
||||||
print SVGChartBuilder::renderStockChart($chartData, 1000, "#708", "#777", true);
|
print SVGChartBuilder::renderStockChart($chartData, [
|
||||||
|
'width'=>1000,
|
||||||
|
'lineColor'=>"#708",
|
||||||
|
'labelColor'=>"#777",
|
||||||
|
'smoothed'=>true
|
||||||
|
]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue