
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Add trend lines to any chart. ~1KB gzipped, zero dependencies, works with your data format.
│
8 │ ● .---●
│ ● .--'
4 │ .-●'
│ ●-'
0 └───────────────────
0 1 2 3 4
● actual data
- trend line (calculated)
Try it on StackBlitz · npm · GitHub
@types needednpm install trendline
import { createTrend } from 'trendline';
const data = [
{ month: 1, revenue: 120 },
{ month: 2, revenue: 150 },
{ month: 3, revenue: 170 },
{ month: 4, revenue: 200 },
];
// Pass your data with the key names you're already using
const trend = createTrend(data, 'month', 'revenue');
console.log(trend.slope); // 26.5 (revenue increases ~26.5 per month)
console.log(trend.yStart); // 96.5 (projected revenue at month 0)
console.log(trend.rSquared); // 0.99 (excellent fit!)
console.log(trend.calcY(12)); // 414.5 (predicted revenue at month 12)
D3.js · Recharts · Chart.js · Victory · Nivo · ECharts · Plotly · Highcharts · Canvas · SVG · or any visualization library
import { createTrend } from 'trendline';
import { LineChart, Line, XAxis, YAxis } from 'recharts';
function SalesChart({ data }) {
const trend = createTrend(data, 'day', 'sales');
// Only need two points to draw a straight line
const trendLine = [
{ day: data[0].day, sales: trend.calcY(data[0].day) },
{ day: data.at(-1).day, sales: trend.calcY(data.at(-1).day) },
];
return (
<LineChart width={600} height={300} data={data}>
<XAxis dataKey="day" />
<YAxis />
<Line dataKey="sales" stroke="#8884d8" />
<Line
data={trendLine}
dataKey="sales"
stroke="#ff7300"
strokeDasharray="5 5"
dot={false}
/>
</LineChart>
);
}
import { createTrend } from 'trendline';
import * as d3 from 'd3';
const data = [
{ date: 1, price: 100 },
{ date: 2, price: 120 },
{ date: 3, price: 115 },
{ date: 4, price: 140 },
{ date: 5, price: 150 },
];
const trend = createTrend(data, 'date', 'price');
// Your existing scales
const x = d3.scaleLinear().domain([1, 5]).range([0, width]);
const y = d3.scaleLinear().domain([80, 160]).range([height, 0]);
// Add trend line
svg.append('line')
.attr('x1', x(1))
.attr('y1', y(trend.calcY(1)))
.attr('x2', x(5))
.attr('y2', y(trend.calcY(5)))
.attr('stroke', '#ff7300')
.attr('stroke-dasharray', '5,5');
import { createTrend } from 'trendline';
import Chart from 'chart.js/auto';
const data = [
{ x: 1, y: 10 },
{ x: 2, y: 15 },
{ x: 3, y: 13 },
{ x: 4, y: 17 },
];
const trend = createTrend(data, 'x', 'y');
new Chart(ctx, {
type: 'scatter',
data: {
datasets: [
{ label: 'Data', data },
{
label: `Trend (R²=${trend.rSquared.toFixed(2)})`,
data: [
{ x: 1, y: trend.calcY(1) },
{ x: 4, y: trend.calcY(4) },
],
type: 'line',
borderDash: [5, 5],
},
],
},
});
import { createTrend } from 'trendline';
const data = [
{ x: 0, y: 20 },
{ x: 50, y: 45 },
{ x: 100, y: 40 },
{ x: 150, y: 70 },
{ x: 200, y: 65 },
];
const trend = createTrend(data, 'x', 'y');
const ctx = canvas.getContext('2d');
// Draw data points
data.forEach(({ x, y }) => {
ctx.beginPath();
ctx.arc(x, 100 - y, 4, 0, Math.PI * 2);
ctx.fill();
});
// Draw trend line
ctx.beginPath();
ctx.setLineDash([5, 5]);
ctx.moveTo(0, 100 - trend.calcY(0));
ctx.lineTo(200, 100 - trend.calcY(200));
ctx.stroke();
createTrend(data, xKey, yKey)| Parameter | Type | Description |
|---|---|---|
data | Array<{ [key]: number }> | Your data array |
xKey | string | Property name for X values |
yKey | string | Property name for Y values |
Returns:
| Property | Type | Description |
|---|---|---|
slope | number | Rate of change (rise over run) |
yStart | number | Y-intercept (value when x = 0) |
calcY(x) | function | Get Y value for any X |
rSquared | number | Fit quality: 0 = poor, 1 = perfect |
import { createTrend, TrendResult } from 'trendline';
const trend: TrendResult = createTrend(data, 'time', 'value');
The rSquared value tells you how well the trend line fits your data:
| R² | Fit Quality |
|---|---|
| 0.9 - 1.0 | Excellent — data follows a clear linear pattern |
| 0.7 - 0.9 | Good — trend line is meaningful |
| 0.4 - 0.7 | Moderate — some correlation |
| 0.0 - 0.4 | Weak — data may not be linear |
Found a bug or have a feature request? Open an issue or submit a PR.
MIT
FAQs
Generate a trendline using linear regression
The npm package trendline receives a total of 3,763 weekly downloads. As such, trendline popularity was classified as popular.
We found that trendline demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.