Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
like image 944
martinho Avatar asked May 04 '26 23:05

martinho


1 Answers

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>
like image 156
zer00ne Avatar answered May 07 '26 14:05

zer00ne



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!