chartjs-plugin-trendline
Version:
Trendline for Chart.js
192 lines (186 loc) • 9.47 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Trendline Projection & Offset Example</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.9/dist/chart.umd.js"></script>
<script src="../dist/chartjs-plugin-trendline.min.js"></script>
<style>
.chart-container {
width: 800px;
height: 500px;
margin-bottom: 50px;
}
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1, h2 {
text-align: center;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", function (event) {
new Chart(document.getElementById("line-chart"), {
type: 'line',
data: {
datasets: [
{
// Dataset 1: Original data, demonstrates basic projection.
// Observe: Trendline extends to the edges of the chart area.
data: [{ x: 0, y: 30 }, { x: 5, y: 25 }, { x: 10, y: 23 }, { x: 25, y: 23 }, { x: 35, y: 17 }, { x: 45, y: 17 }],
label: "Dataset 1 (Projected)",
borderColor: "#3e95cd",
backgroundColor: "rgba(62,149,205,0.1)",
fill: false,
trendlineLinear: {
colorMin: "#3e95cd", // Should match borderColor or be distinct
lineStyle: "dotted", // "line" was not a valid Chart.js option, "solid" or "dotted", "dashed"
width: 2,
projection: true,
label: {
display: true,
text: "Trend D1 (Proj)",
displayValue: true,
}
}
},
{
// Dataset 2: Clustered data, non-projected.
// Observe: Trendline only spans the range of its data points (approx x=15 to x=35).
// This contrasts with projected lines that extend to chart boundaries.
data: [{ x: 15, y: 10 }, { x: 20, y: 12 }, { x: 25, y: 9 }, { x: 30, y: 11 }, { x: 35, y: 8 }],
label: "Dataset 2 (Non-Projected, Clustered)",
borderColor: "#FF6384",
backgroundColor: "rgba(255,99,132,0.1)",
fill: false,
trendlineLinear: {
colorMin: "#FF6384",
lineStyle: "dashed",
width: 2,
projection: false, // Explicitly false
label: {
display: true,
text: "Trend D2 (No Proj)",
displayValue: true,
}
}
},
{
// Dataset 3: Projected, with positive trendoffset and null data points.
// Observe: Trendline calculation starts after skipping the first 2 data points (due to trendoffset: 2).
// Null values (e.g., at x=65) are correctly ignored by the fitter. The line projects to chart edges.
data: [{ x: 50, y: 10 }, { x: 55, y: 12 }, { x: 60, y: 15 }, null, { x: 70, y: 18 }, { x: 75, y: 22 }, {x: 65, y: null}],
label: "Dataset 3 (Projected, Offset+, Nulls)",
borderColor: "#4BC0C0",
backgroundColor: "rgba(75,192,192,0.1)",
fill: false,
trendlineLinear: {
colorMin: "#4BC0C0",
lineStyle: "solid",
width: 2,
projection: true,
trendoffset: 2, // Skips first 2 data points from calculation {50,y:10}, {55,y:12}
label: {
display: true,
text: "Trend D3 (Proj, Offset+)",
displayValue: true,
}
}
},
{
// Dataset 4: Projected, with negative trendoffset.
// Observe: Trendline calculation excludes the last 2 data points from the set.
// The line projects to chart edges based on the remaining points.
data: [{ x: 0, y: 5 }, { x: 10, y: 8 }, { x: 20, y: 6}, { x: 30, y: 9 }, { x: 40, y: 7 }, { x: 50, y: 10 } ],
label: "Dataset 4 (Projected, Offset-)",
borderColor: "#FF9F40",
backgroundColor: "rgba(255,159,64,0.1)",
fill: false,
trendlineLinear: {
colorMin: "#FF9F40",
lineStyle: "dotted",
width: 2,
projection: true,
trendoffset: -2, // Excludes last 2 data points {40,y:7}, {50,y:10}
label: {
display: true,
text: "Trend D4 (Proj, Offset-)",
displayValue: true,
}
}
},
// Dummy dataset to ensure chart scales to desired max, if other data doesn't reach it.
// { data: [{ x: 80, y: 35 }], label: "ScaleHelper", hidden: true}
]
},
options: {
plugins: {
title: {
display: true,
text: 'Trendline Projection, Offset, and Data Handling Demo',
font: { size: 18 }
},
legend: {
position: 'top',
},
tooltip: {
mode: 'index',
intersect: false,
}
},
maintainAspectRatio: false,
responsive: true,
scales: {
x: {
type: 'linear',
position: 'bottom',
title: { text: 'X Value / Days', display: true },
min: -5, // Adjusted min to give space
max: 80, // Adjusted max to give space for projection
},
y: {
type: 'linear',
position: 'left',
title: { text: 'Y Value / Count', display: true },
min: 0, // Adjusted min
max: 35, // Adjusted max
}
}
}
});
});
</script>
</head>
<body>
<h1>Chart.js Trendline Plugin Demonstration</h1>
<h2>Projection, Data Offset, and Null Value Handling</h2>
<div class="chart-container">
<canvas id="line-chart"></canvas>
</div>
<div style="padding: 20px; background-color: #f4f4f4; border-radius: 5px;">
<h3>Observations Guide:</h3>
<ul>
<li><strong>Dataset 1 (Blue, Dotted Trend):</strong> Shows a standard projected trendline extending to the chart's X-axis boundaries.</li>
<li><strong>Dataset 2 (Red, Dashed Trend):</strong> Demonstrates a <strong>non-projected</strong> trendline. Notice how it only covers the span of its own data points (approx. x=15 to x=35).</li>
<li><strong>Dataset 3 (Teal, Solid Trend):</strong>
<ul>
<li>Uses <code>projection: true</code>.</li>
<li><code>trendoffset: 2</code> means the first two data points ( (50,10) and (55,12) ) are excluded from the trendline calculation.</li>
<li>Contains a <code>null</code> data point (originally at x=65) which is correctly ignored by the trendline fitter.</li>
</ul>
</li>
<li><strong>Dataset 4 (Orange, Dotted Trend):</strong>
<ul>
<li>Uses <code>projection: true</code>.</li>
<li><code>trendoffset: -2</code> means the last two data points ( (40,7) and (50,10) ) are excluded from the trendline calculation.</li>
</ul>
</li>
<li>All trendlines should be clipped correctly within the chart area boundaries, even if their mathematical extension would go beyond.</li>
<li>The slope displayed in the labels should consistently reflect the underlying data used for fitting, regardless of projection.</li>
</ul>
</div>
</body>
</html>