简体   繁体   中英

Chart - google chart with filter by time

I want to make a line chart that represents several actions with the accumulated value for days in a space of time of that action.

This graphic will have a filter, which will filter by day / week / month.

In the beginning I set the date column to type string, and if you have only one action works, but if you have more than one and if it starts at the same time, it duplicates those points, which was not supposed to.

So I set the date column to date and it solves the issue with not duplicating the points, the problem is when I apply the filter to the weeks and months, which will be written as "week 24" or month name and the duplicate points return.

Any suggestion.

Exemple -

 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.2.1/moment.min.js"></script> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <div id="chart_div"></div> <button onclick="filter('DD-M')">day</button> <button onclick="filter('W')">week</button> <button onclick="filter('MMM')">month</button> <script> let data = [ ['2018-06-01', 1, null], ['2018-06-02', 2, null], ['2018-06-03', 3, null], ['2018-06-04', 4, null], ['2018-06-05', 5, null], ['2018-06-06', 6, null], ['2018-06-07', 7, null], ['2018-06-08', 8, null], ['2018-06-09', 9, null], ['2018-06-06', null, 20], ['2018-06-07', null, 30], ['2018-06-08', null, 40], ['2018-06-09', null, 50], ['2018-06-10', null, 60], ['2018-06-11', null, 70], ['2018-06-12', null, 80], ['2018-06-13', null, 90], ['2018-06-14', null, 100] ]; let dataChart = []; function filter (format) { dataChart = []; let lastDate = ''; let value = 0; [].forEach.call(data, (d,i) => { let date = moment(d[0], 'YYYY-MM-DD').format(format); if (i === 0) lastDate = date; if (lastDate === date) { value += (d[1] !== null) ? d[1] : d[2]; } else { dataChart.push([date, d[1], d[2]]); lastDate = date; value = (d[1] !== null) ? d[1] : d[2]; } if ( i === data.length - 1) dataChart.push([date, d[1], d[2]]); }); google.charts.load('current', { packages: ['corechart'] }); google.charts.setOnLoadCallback(drawChart); } filter('DD-M'); function drawChart() { var chart = new google.visualization.DataTable(); chart.addColumn('string', 'date'); chart.addColumn('number', 'action1'); chart.addColumn('number', 'action2'); chart.addRows(dataChart) let container = document.getElementById('chart_div'); let dChart = new google.visualization.LineChart(container); dChart.draw(chart); } </script> 

Problems

"...and if you have only one action works, but if you have more than one and if it starts at the same time, it duplicates those points, which was not supposed to."


Solutions


Array data

The data array had duplicated dates therefore duplicated points are inevitable.

Compare the original values...

let data = [
      ['2018-06-01', 1, null],
      ['2018-06-02', 2, null],
      ['2018-06-03', 3, null],
      ['2018-06-04', 4, null],
      ['2018-06-05', 5, null],
      ['2018-06-06', 6, null],// Duplicated Pair A
      ['2018-06-07', 7, null],// Duplicated Pair B
      ['2018-06-08', 8, null],// Duplicated Pair C
      ['2018-06-09', 9, null],// Duplicated Pair D
      ['2018-06-06', null, 20],// Duplicated Pair A
      ['2018-06-07', null, 30],// Duplicated Pair B
      ['2018-06-08', null, 40],// Duplicated Pair C
      ['2018-06-09', null, 50],// Duplicated Pair D
      ['2018-06-10', null, 60],
      ['2018-06-11', null, 70],
      ['2018-06-12', null, 80],
      ['2018-06-13', null, 90],
      ['2018-06-14', null, 100]
];

...to the corrected values

  let data = [
    ['2018-06-01', 1, null],
    ['2018-06-02', 2, null],
    ['2018-06-03', 3, null],
    ['2018-06-04', 4, null],
    ['2018-06-05', 5, null],
    ['2018-06-06', 6, 20],
    ['2018-06-07', 7, 30],
    ['2018-06-08', 8, 40],
    ['2018-06-09', 9, 50],
    ['2018-06-10', null, 60],
    ['2018-06-11', null, 70],
    ['2018-06-12', null, 80],
    ['2018-06-13', null, 90],
    ['2018-06-14', null, 100]
  ];

One Off .length

The following condition:

if (i === data.length - 1) dataChart.push([date, d[1], d[2]]);

is creating a duplicate day at the end of haxis (x or horizontal axis) in which the last two columns are both: 14-6 .

To correct the column duplication, remove the -1 from .length :

if (i === data.length) dataChart.push([date, d[1], d[2]]);

One off date

The following condition:

 if (lastDate === date) {

causes the haxis to skip the first column so it starts at 02-6 instead of 01-6 :

To add the missing first column, add -1 to the date value:

  if (lastDate === date-1) {

Demo

 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.2.1/moment.min.js"></script> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <div id="chart_div"></div> <button onclick="filter('DD-M')">day</button> <button onclick="filter('W')">week</button> <button onclick="filter('MMM')">month</button> <script> let data = [ ['2018-06-01', 1, null], ['2018-06-02', 2, null], ['2018-06-03', 3, null], ['2018-06-04', 4, null], ['2018-06-05', 5, null], ['2018-06-06', 6, 20], ['2018-06-07', 7, 30], ['2018-06-08', 8, 40], ['2018-06-09', 9, 50], ['2018-06-10', null, 60], ['2018-06-11', null, 70], ['2018-06-12', null, 80], ['2018-06-13', null, 90], ['2018-06-14', null, 100] ]; let dataChart = []; function filter(format) { dataChart = []; let lastDate = ''; let value = 0; [].forEach.call(data, (d, i) => { let date = moment(d[0], 'YYYY-MM-DD').format(format); if (i === 0) lastDate = date; if (lastDate === date - 1) { value += (d[1] !== null) ? d[1] : d[2]; } else { dataChart.push([date, d[1], d[2]]); lastDate = date; value = (d[1] !== null) ? d[1] : d[2]; } if (i === data.length) dataChart.push([date, d[1], d[2]]); }); google.charts.load('current', {packages: ['corechart']}); google.charts.setOnLoadCallback(drawChart); } filter('DD-M'); function drawChart() { var chart = new google.visualization.DataTable(); chart.addColumn('string', 'Date'); chart.addColumn('number', 'Action1'); chart.addColumn('number', 'Action2'); chart.addRows(dataChart) let container = document.getElementById('chart_div'); let dChart = new google.visualization.LineChart(container); dChart.draw(chart); } </script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM