[Chartjs]-Dynamic line chart with chart.js and PHP

1πŸ‘

In my opinion, multi-level arrays in javascript are more painful because you must do an array-object combo or have a fixed cube:

See https://www.quora.com/Why-cant-I-push-values-into-this-2D-array-in-JavaScript

Hence why PHP, or even in SQL, it would be easier to build your data set. However, I chose to endure and here you go:

 var jsondata = [
 {"0":"MARKER01","timestamp":"1607943600","VALUE1":"3.02","VALUE2":"3.03","VALUE3":"3.16"},
 {"0":"MARKER01","timestamp":"1607932800","VALUE1":"3.72","VALUE2":"2.93","VALUE3":"3.00"},
 {"0":"MARKER01","timestamp":"1607882400","VALUE1":"3.10","VALUE2":"3.06","VALUE3":"2.98"},
 {"0":"MARKER01","timestamp":"1607864400","VALUE1":"3.10","VALUE2":"3.06","VALUE3":"2.98"},
 {"0":"MARKER03","timestamp":"1607943600","VALUE1":"2.30","VALUE2":"2.41","VALUE3":"2.74"},
 {"0":"MARKER03","timestamp":"1607864400","VALUE1":"2.30","VALUE2":"2.41","VALUE3":"2.74"},
 {"0":"MARKER03","timestamp":"1607943600","VALUE1":"2.29","VALUE2":"2.37","VALUE3":"2.74"},
 {"0":"MARKER03","timestamp":"1607864400","VALUE1":"2.29","VALUE2":"2.37","VALUE3":"2.74"},
 {"0":"MARKER07","timestamp":"1607882400","VALUE1":"2.74","VALUE2":"4.26","VALUE3":"4.26"},
 {"0":"MARKER07","timestamp":"1607884400","VALUE1":"2.75","VALUE2":"4.26","VALUE3":"4.26"},
 {"0":"MARKER00","timestamp":"1607882400","VALUE1":"5.64","VALUE2":"2.09","VALUE3":"1.30"},
 {"0":"MARKER00","timestamp":"1607884400","VALUE1":"5.65","VALUE2":"2.09","VALUE3":"1.30"},
 ];

// default obj for testing
var obj = [{
    id : 1, 
    label: 'MARKER01', 
    stamp: '',
    data: [],
}];

for (var i = 0; i < jsondata.length; i++) 
{
    var row = Object.values(jsondata[i]);
    var marker = row[0];  
    var index = add(obj, marker);
    obj[index].stamp = new Date( row[1] *1000);
    for (var j = 2; j < row.length; j++) {
       obj[index].data.push(row[j]);
    }
   
}

console.log(obj);

/**
 * add function thanks to: https://stackoverflow.com/questions/15997879/get-the-index-of-the-object-inside-an-array-matching-a-condition
 */
function add(arr, name) {
  var { length } = arr;
  var id = length + 1;
  var index = arr.findIndex(x => x.label === name);
  if (index === -1) {
    arr.push({ id, label: name, stamp: '', data: []})
    index = arr.findIndex(x => x.label === name);
  } 
  console.log(index);
  return index;
}

// You can test with console.log(add(obj, 'test'));

Ouput

 Object { id: 1, label: "MARKER01", stamp: Sun Dec 13 2020 08:00:00 GMT-0500 (Eastern Standard Time), data: Array ["3.02", "3.03", "3.16", "3.72", "2.93", "3.00", "3.10", "3.06", "2.98", "3.10", "3.06", "2.98"] },
 Object { id: 2, label: "MARKER03", stamp: Sun Dec 13 2020 08:00:00 GMT-0500 (Eastern Standard Time), data: Array ["2.30", "2.41", "2.74", "2.30", "2.41", "2.74", "2.29", "2.37", "2.74", "2.29", "2.37", "2.74"] },
 Object { id: 3, label: "MARKER07", stamp: Sun Dec 13 2020 13:33:20 GMT-0500 (Eastern Standard Time), data: Array ["2.74", "4.26", "4.26", "2.75", "4.26", "4.26"] },
 Object { id: 4, label: "MARKER00", stamp: Sun Dec 13 2020 13:33:20 GMT-0500 (Eastern Standard Time), data: Array ["5.64", "2.09", "1.30", "5.65", "2.09", "1.30"] }
]```

0πŸ‘

Using your code:

Try parseInt when adding the values to your array:

for (var i = 0; i < data.length; i++) {
    var date = new Date( data[i].timestamp *1000);
    time.push(date.toLocaleString());
    value1.push(parseInt(data[i].a));
    value2.push(parseInt(data[i].b));
    console.log(parseInt(data[i].b));
    
}

Debugging

On the php side, make sure you convert your numbers from string to inter, on the js side you can also do:

var jsonString = '[{"x":1.5}, {"x":2.7}]';

var obj  = JSON.parse(jsonString);
console.log('obj:'); console.log(obj);
// outputs obj array: [{x: 1.5} {x: 2.7}]

var dataset1 = $.map(obj, function(val, i){
    console.log('x: ' + val.x);
    return val.x;
});
console.log('dataset1 :'); console.log(dataset1);
//ouputs new array with just values: (2) [1.5, 2.7]

With Your Full Code

chartjs

var data = [
{"timestamp":"1607943100","a":"1.5", "b":"2.81", "c":"7.81"},
{"timestamp":"1607943200","a":"2.7", "b":"8.10", "c":"3.10"},
{"timestamp":"1607943300","a":"1.3", "b":"1.77", "c":"4.77"},
{"timestamp":"1607943400","a":"5.2", "b":"4.71", "c":"2.71"},
{"timestamp":"1607943500","a":"9.4", "b":"4.43", "c":"7.43"},
{"timestamp":"1607943600","a":"6.5", "b":"3.26", "c":"9.26"},
];

//get the line chart canvas
var ctx = $("#myChart");

//line chart data
var time = [];
var value1 = [];
var value2 = [];
var value3 = [];

for (var i = 0; i < data.length; i++) {
    var date = new Date( data[i].timestamp *1000);
    time.push(date.toLocaleString());
    value1.push(parseInt(data[i].a));
    value2.push(parseInt(data[i].b));
    value3.push(parseInt(data[i].c));
    
    // some debugging
    console.log(parseInt(data[i].b));
}

var chartData = {
    labels: time,
    datasets: [
        {
            label: 'Value1',
            backgroundColor: 'blue',
            borderColor: 'blue',
            hoverBackgroundColor: '#CCCCCC',
            hoverBorderColor: '#666666',
            fill: false,
            lineTension: 0,
            radius: 0,
            data: value1
        },
        {
            label: 'Value2',
            backgroundColor: 'green',
            borderColor: 'green',
            hoverBackgroundColor: '#CCCCCC',
            hoverBorderColor: '#666666',
            fill: false,
            lineTension: 0,
            radius: 0,
            data: value2
        },
        {
            label: 'Value3',
            backgroundColor: 'red',
            borderColor: 'red',
            hoverBackgroundColor: '#CCCCCC',
            hoverBorderColor: '#666666',
            fill: false,
            lineTension: 0,
            radius: 0,
            data: value3
        },
    ]
};

//options
var options = {
    responsive: true,
    title: {
        display: true,
        position: "top",
        text: "Chart",
        fontSize: 18,
        fontColor: "#111"
},
legend: {
    display: true,
    position: "top",
    labels: {
        fontColor: "#333",
        fontSize: 16
        }
    },
    scales: {
        yAxes: [{
        scaleLabel: {
            display: true,
            labelString: 'Value [ ]'
        },
        ticks: {
            beginAtZero: true   
        }
        }]
    }
};

//create Chart class object
var chart = new Chart(ctx, {
    type: "line",
    data: chartData,
    options: options
});

0πŸ‘

For formatting date and time:

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<canvas id="myChart"></canvas>

<script>
var s1 = {
  label: 's1',
  borderColor: 'blue',
  data: [
    { x: 1606943100000, y: 1.5 },
    { x: 1607943200000, y: 2.7 },
    { x: 1608943300000, y: 1.3 },
    { x: 1609943400000, y: 5.2 },
    { x: 1610943500000, y: 9.4 },
    { x: 1611943600000, y: 6.5 },
  ]
};

var s2 = {
  label: 's2',
  borderColor: 'red',
  data: [
    { x: 1604953100000, y: 4.5 },
    { x: 1607963200000, y: 2.7 },
    { x: 1608973300000, y: 3.3 },
    { x: 1613983400000, y: 4.2 },
    { x: 1620993500000, y: 7.4 },
    { x: 1632043600000, y: 6.5 },
  ]
};

var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
  type: 'line',
  data: { datasets: [s1, s2] },
  options: {
    scales: {
      xAxes: [{
        type: 'time',
        time: {
          unitStepSize: 500,
          unit: 'hour', // check displayFormat to match
          displayFormats: {
            hour: 'hA', 
            day: 'YYYY-MM-DD',
            month: 'YYYY-MM'
          }
        }
      }]
    }
  }
});
</script>

Leave a comment