//AI assist this code
//Sample
// Your provided JSON data
// const jsonData = [{
// "name": "TRM 2025",
// "data": [264, 322, 272, 475, 305, 792, 542, 650, 0, 0, 0, 114],
// "type": "column"
// }, {
// "name": "TRM 2024",
// "data": [174, 257, 172, 338, 347, 681, 591, 641, 208, 1, 0, 49],
// "type": "line"
// }, {
// "name": "TRM 2023",
// "data": [359, 126, 285, 306, 401, 544, 623, 583, 423, 69, 0, 3],
// "type": "line"
// }];
//imagine you have three data row in a data series
//then you want to make a trendline for a specific data row
function calculateTrendline(data, seriesName, isCombinedResult=true, stopOnZero=false) {
// Find the specific series data you need
const series = data.find(s => s.name === seriesName);
if (!series) {
console.error(`Series with name "${seriesName}" not found.`);
return [];
}
const yValues = series.data;
const n = yValues.length;
// x-values are just the index of each data point, starting from 1
const xValues = Array.from({
length: n
}, (_, i) => i+1);
// Calculate the necessary sums
let sumX = 0;
let sumY = 0;
let sumXY = 0;
let sumX2 = 0;
let istop = -1;
for (let i = 0; i < n; i++) {
if (stopOnZero && yValues[i] == 0) {
istop = i;
break;
}
sumX += xValues[i];
sumY += yValues[i];
sumXY += xValues[i] * yValues[i];
sumX2 += xValues[i] * xValues[i];
}
ntrend = stopOnZero ? istop : n;
//Calculate the slope (m) and y-intercept (b)
const m = (ntrend * sumXY - sumX * sumY) / (ntrend * sumX2 - sumX * sumX);
const b = (sumY / ntrend) - (m * (sumX / ntrend));
//console.log('m = ('+ntrend+' * '+sumXY+' - '+sumX+' * '+sumY+') / ('+ntrend+' * '+sumX2+' - '+sumX+' * '+sumX+')')
//console.log('b = ('+sumY+' / '+ntrend+') - ('+m+' * ('+sumX2+' / '+sumX+'))')
// Generate the new data points for the trendline
const trendlineData = [];
for (let i = 0; i < n; i++) {
if (stopOnZero && i == istop) {
break;
}
// The y-value of the trendline is calculated using y = mx + b
const yTrend = m * xValues[i] + b;
trendlineData.push(yTrend);
}
// Array to hold new trendlines
const chartSeries = [];
if (isCombinedResult) {
data.forEach(series => {
// Add the original series to the chart series array
chartSeries.push(series);
});
}
// Add the new trendline series to the chart series array
chartSeries.push({
name: `${seriesName} Trendline`,
data: trendlineData,
type: 'line', // Trendlines are best represented as lines
});
return chartSeries;
}
// --- Example Usage ---
// To get the trendline data for "TRM 2024"
//const trendlineData = calculateTrendline(jsonData, "TRM 2024", true, true);
//console.log(trendlineData);
//imagine you have three data row in a data series
//then you want to make a trendline for each data row, then will be three trendline (since you have three data row)
function calculateAllTrendline(data, isCombinedResult=true, stopOnZero=false) {
// Array to hold all original series and their new trendlines
const chartSeries = [];
// Iterate through each series in your JSON data
jsonData.forEach(series => {
if (isCombinedResult) {
// Add the original series to the chart series array
chartSeries.push(series);
}
// Calculate the trendline for the current series' data
const trendlineData = calculateRowTrendline(series.data, stopOnZero);
// Add the new trendline series to the chart series array
chartSeries.push({
name: `${series.name} Trendline`,
data: trendlineData,
type: 'line', // Trendlines are best represented as lines
});
});
return chartSeries;
}
function calculateRowTrendline(data, stopOnZero=false) {
const n = data.length;
// The x-values are the index of each data point, starting from 1
const xValues = Array.from({ length: n }, (_, i) => i+1);
// Calculate the necessary sums
let sumX = 0;
let sumY = 0;
let sumXY = 0;
let sumX2 = 0;
let istop = -1;
for (let i = 0; i < n; i++) {
if (stopOnZero && data[i] == 0) {
istop = i;
break;
}
sumX += xValues[i];
sumY += data[i];
sumXY += xValues[i] * data[i];
sumX2 += xValues[i] * xValues[i];
}
ntrend = stopOnZero ? istop : n;
//Calculate the slope (m) and y-intercept (b)
const m = (ntrend * sumXY - sumX * sumY) / (ntrend * sumX2 - sumX * sumX);
const b = (sumY / ntrend) - (m * (sumX / ntrend));
//console.log('m = ('+ntrend+' * '+sumXY+' - '+sumX+' * '+sumY+') / ('+ntrend+' * '+sumX2+' - '+sumX+' * '+sumX+')')
//console.log('b = ('+sumY+' / '+ntrend+') - ('+m+' * ('+sumX2+' / '+sumX+'))')
// Generate the new data points for the trendline
const trendlineData = [];
for (let i = 0; i < n; i++) {
if (stopOnZero && i == istop) {
break;
}
const yTrend = m * xValues[i] + b;
trendlineData.push(yTrend);
}
return trendlineData;
}
// --- Example Usage ---
//const trendlineAllData = calculateAllTrendline(jsonData, false, true);
//console.log(trendlineAllData);
//imagine you have three data row in a data series
//then you want to make a trendline for all your rows (combined)
function calculateCombinedTrendline(jsonData, isCombinedResult=true, stopOnZero=false) {
// 1. Combine all the data from all series into a single array
const combinedYValues = [];
jsonData.forEach(series => {
combinedYValues.push(...series.data);
});
const nseries = jsonData.length;
const n = combinedYValues.length;
const serieslength = n/nseries;
// 2. The x-values are a continuous sequence from 1 to n
const combinedXValues = Array.from({ length: serieslength }, (_, i) => i+1);
// 3. Calculate the sums for linear regression
let sumX = 0;
let sumY = 0;
let sumXY = 0;
let sumX2 = 0;
let istop = serieslength + 1;
//find istop
for (let s = 0; s < nseries; s++) {
for (let i = 0; i < serieslength; i++) {
if (stopOnZero && combinedYValues[(serieslength*s)+i] == 0) {
if (i < istop) {
istop = i;
}
break;
}
}
}
for (let s = 0; s < nseries; s++) {
for (let i = 0; i < serieslength; i++) {
let si = (serieslength*s)+i;
if (stopOnZero && i == istop) {
break;
}
sumX += combinedXValues[i];
sumY += combinedYValues[si];
sumXY += combinedXValues[i] * combinedYValues[si];
sumX2 += combinedXValues[i] * combinedXValues[i];
}
}
ntrend = stopOnZero ? istop*nseries : n;
// 4. Calculate the slope (m) and y-intercept (b)
const m = (ntrend * sumXY - sumX * sumY) / (ntrend * sumX2 - sumX * sumX);
const b = (sumY / ntrend) - (m * (sumX / ntrend));
//console.log('m = ('+ntrend+' * '+sumXY+' - '+sumX+' * '+sumY+') / ('+ntrend+' * '+sumX2+' - '+sumX+' * '+sumX+')')
//console.log('b = ('+sumY+' / '+ntrend+') - ('+m+' * ('+sumX2+' / '+sumX+'))')
// 5. Generate the new data points for the single trendline
const trendlineData = [];
//get the first row on the series
for (let i = 0; i < serieslength; i++) {
let si = i;
if (stopOnZero && si == istop) {
break;
}
const yTrend = m * combinedXValues[si] + b;
trendlineData.push(yTrend);
}
// Array to hold new trendlines
const chartSeries = [];
if (isCombinedResult) {
jsonData.forEach(series => {
// Add the original series to the chart series array
chartSeries.push(series);
});
}
// Add the new trendline series to the chart series array
chartSeries.push({
name: `Trendline`,
data: trendlineData,
type: 'line', // Trendlines are best represented as lines
});
return chartSeries;
}
// --- Example Usage ---
//const combinedTrendlineData = calculateCombinedTrendline(jsonData, true, true);
//console.log(combinedTrendlineData);
Contoh hasil
[
{
name: 'TRM 2025',
data: [
264, 322, 272, 475, 305,
792, 542, 650, 0, 0,
0, 114
],
type: 'column'
},
{
name: 'TRM 2024',
data: [
174, 257, 172, 338, 347,
681, 591, 641, 208, 1,
0, 49
],
type: 'line'
},
{
name: 'TRM 2023',
data: [
359, 126, 285, 306, 401,
544, 623, 583, 423, 69,
0, 3
],
type: 'line'
},
{
name: 'TRM 2024 Trendline',
data: [
299.05454545454546,
308.3757575757576,
317.6969696969697,
327.0181818181818,
336.339393939394,
345.6606060606061,
354.9818181818182,
364.3030303030303,
373.6242424242424,
382.94545454545454
],
type: 'line'
}
]
[
{
name: 'TRM 2025 Trendline',
data: [
236.41666666666663,
298.2261904761905,
360.0357142857143,
421.8452380952381,
483.65476190476187,
545.4642857142858,
607.2738095238095,
669.0833333333333
],
type: 'line'
},
{
name: 'TRM 2024 Trendline',
data: [
299.05454545454546,
308.3757575757576,
317.6969696969697,
327.0181818181818,
336.339393939394,
345.6606060606061,
354.9818181818182,
364.3030303030303,
373.6242424242424,
382.94545454545454
],
type: 'line'
},
{
name: 'TRM 2023 Trendline',
data: [
315.9090909090909,
328.3515151515151,
340.79393939393935,
353.2363636363636,
365.67878787878783,
378.1212121212121,
390.56363636363636,
403.0060606060606,
415.44848484848484,
427.8909090909091
],
type: 'line'
}
]
[
{
name: 'TRM 2025',
data: [
264, 322, 272, 475, 305,
792, 542, 650, 0, 0,
0, 114
],
type: 'column'
},
{
name: 'TRM 2024',
data: [
174, 257, 172, 338, 347,
681, 591, 641, 208, 1,
0, 49
],
type: 'line'
},
{
name: 'TRM 2023',
data: [
359, 126, 285, 306, 401,
544, 623, 583, 423, 69,
0, 3
],
type: 'line'
},
{
name: 'Trendline',
data: [
188.30555555555554,
254.1468253968254,
319.98809523809524,
385.82936507936506,
451.6706349206349,
517.5119047619048,
583.3531746031746,
649.1944444444443
],
type: 'line'
}
]