简体   繁体   中英

Draw a boxplot in Google Visualization when hardcoding the stats within your script

I am trying to create a boxplot in Google Charts. The official documentation (see the bottom of the page) works with loading the actual dataset and calculating the stats within javascript; however, I am planning to calculate the stats (ie min, max, quartiles, median) elsewhere and read them in.

I tried that by creating a DataTable and directly inputting my stats (compare the snippet below to the linked documentation above). Although I can get the table and it looks fine, nothing is rendered within the boxplot.

The only thing that I can think of is that somehow when using arrayToDataTable , ids are lost so chart cannot get the right elements.

 google.charts.load('current', { 'packages': ['corechart'] }); google.charts.setOnLoadCallback(drawBoxPlot); google.charts.load('current', { 'packages': ['table'] }); google.charts.setOnLoadCallback(drawTable); function drawBoxPlot() { var data = google.visualization.arrayToDataTable( [ [{ label: 'Var', type: 'string' }, { label: 'Max', id: 'max', type: 'number', role: 'interval' }, { label: 'Min', id: 'min', type: 'number', role: 'interval' }, { label: '1st Q', id: 'firstQuartile', type: 'number', role: 'interval' }, { label: 'Median', id: 'median', type: 'number', role: 'interval' }, { label: '3rd Q', id: 'thirdQuartile', type: 'number', role: 'interval' } ], ['A', 120, 85, 93, 100, 107], ['B', 140, 90, 104, 120, 127], ['C', 140, 100, 111, 130, 136], ['D', 95, 85, 86.5, 90, 93.5], ['E', 120, 85, 93, 100, 107], ['F', 140, 90, 104, 120, 127], ['G', 140, 100, 111, 130, 136], ['H', 95, 85, 86.5, 90, 93.5], ['I', 120, 85, 93, 100, 107], ['J', 140, 90, 104, 120, 127], ['K', 140, 100, 111, 130, 136], ['L', 95, 85, 86.5, 90, 93.5] ]); var options = { title: 'Box Plot', height: 500, legend: { position: 'none' }, hAxis: { gridlines: { color: '#fff' } }, lineWidth: 0, series: [{ 'color': '#D3362D' }], intervals: { barWidth: 1, boxWidth: 1, lineWidth: 2, style: 'boxes' }, interval: { max: { style: 'bars', fillOpacity: 1, color: '#777' }, min: { style: 'bars', fillOpacity: 1, color: '#777' } } }; var chart = new google.visualization.LineChart(document.getElementById('box_plot')); chart.draw(data, options); } function drawTable() { var data = google.visualization.arrayToDataTable( [ [{ label: 'Var', type: 'string' }, { label: 'Max', id: 'max', type: 'number', role: 'interval' }, { label: 'Min', id: 'min', type: 'number', role: 'interval' }, { label: '1st Q', id: 'firstQuartile', type: 'number', role: 'interval' }, { label: 'Median', id: 'median', type: 'number', role: 'interval' }, { label: '3rd Q', id: 'thirdQuartile', type: 'number', role: 'interval' } ], ['A', 120, 85, 93, 100, 107], ['B', 140, 90, 104, 120, 127], ['C', 140, 100, 111, 130, 136], ['D', 95, 85, 86.5, 90, 93.5], ['E', 120, 85, 93, 100, 107], ['F', 140, 90, 104, 120, 127], ['G', 140, 100, 111, 130, 136], ['H', 95, 85, 86.5, 90, 93.5], ['I', 120, 85, 93, 100, 107], ['J', 140, 90, 104, 120, 127], ['K', 140, 100, 111, 130, 136], ['L', 95, 85, 86.5, 90, 93.5] ]); var table = new google.visualization.Table(document.getElementById('table_div')); table.draw(data, { showRowNumber: true, width: '100%', height: '100%' }); }
 <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <div id="box_plot"></div> <div id="table_div"></div>

first, you can load multiple packages at the same time,
only need to load google once...

google.charts.load('current', {
  packages: ['corechart', 'table']
}).then(function () {
  drawBoxPlot();
  drawTable();
});

next, your data.table is missing all of the series columns required by the box plot,
you're only providing the data roles / intervals.

notice in their example, there are 7 series columns, then the intervals...

  var data = new google.visualization.DataTable();
  data.addColumn('string', 'x');
  data.addColumn('number', 'series0');
  data.addColumn('number', 'series1');
  data.addColumn('number', 'series2');
  data.addColumn('number', 'series3');
  data.addColumn('number', 'series4');
  data.addColumn('number', 'series5');
  data.addColumn('number', 'series6');

  data.addColumn({id:'max', type:'number', role:'interval'});
  data.addColumn({id:'min', type:'number', role:'interval'});
  data.addColumn({id:'firstQuartile', type:'number', role:'interval'});
  data.addColumn({id:'median', type:'number', role:'interval'});
  data.addColumn({id:'thirdQuartile', type:'number', role:'interval'});

and if we look closer, they are using function getBoxPlotValues to format their array, before drawing the chart.

  data.addRows(getBoxPlotValues(array));

so they start with their values for the vertical lines within each box plot...
these are the values for the series columns.

  var array = [
    ['a', 100, 90, 110, 85, 96, 104, 120],
    ['b', 120, 95, 130, 90, 113, 124, 140],
    ['c', 130, 105, 140, 100, 117, 133, 139],
    ['d', 90, 85, 95, 85, 88, 92, 95],
    ['e', 70, 74, 63, 67, 69, 70, 72],
    ['f', 30, 39, 22, 21, 28, 34, 40],
    ['g', 80, 77, 83, 70, 77, 85, 90],
    ['h', 100, 90, 110, 85, 95, 102, 110]
  ];

then they use getBoxPlotValues to add the values for the data roles / intervals.
following is the array of values returned by getBoxPlotValues

  [
    ["a",100,90,110,85,96,104,120,120,85,93,100,107],
    ["b",120,95,130,90,113,124,140,140,90,104,120,127],
    ["c",130,105,140,100,117,133,139,140,100,111,130,136],
    ["d",90,85,95,85,88,92,95,95,85,86.5,90,93.5],
    ["e",70,74,63,67,69,70,72,74,63,68,70,71],
    ["f",30,39,22,21,28,34,40,40,21,25,30,36.5],
    ["g",80,77,83,70,77,85,90,90,70,77,80,84],
    ["h",100,90,110,85,95,102,110,110,85,92.5,100,106]
  ]

it's the same series values, with the intervals added to the end of each row.
if you want to feed your values directly, your array needs to look similar to the above.

see following working snippet...

 google.charts.load('current', { packages: ['corechart', 'table'] }).then(function() { drawBoxPlot(); drawTable(); }); function drawBoxPlot() { var data = google.visualization.arrayToDataTable( [ [{ label: 'Var', type: 'string' }, { label: 'series0', type: 'number' }, { label: 'series1', type: 'number' }, { label: 'series2', type: 'number' }, { label: 'series3', type: 'number' }, { label: 'series4', type: 'number' }, { label: 'series5', type: 'number' }, { label: 'series6', type: 'number' }, { label: 'Max', id: 'max', type: 'number', role: 'interval' }, { label: 'Min', id: 'min', type: 'number', role: 'interval' }, { label: '1st Q', id: 'firstQuartile', type: 'number', role: 'interval' }, { label: 'Median', id: 'median', type: 'number', role: 'interval' }, { label: '3rd Q', id: 'thirdQuartile', type: 'number', role: 'interval' } ], ["a", 100, 90, 110, 85, 96, 104, 120, 120, 85, 93, 100, 107], ["b", 120, 95, 130, 90, 113, 124, 140, 140, 90, 104, 120, 127], ["c", 130, 105, 140, 100, 117, 133, 139, 140, 100, 111, 130, 136], ["d", 90, 85, 95, 85, 88, 92, 95, 95, 85, 86.5, 90, 93.5], ["e", 70, 74, 63, 67, 69, 70, 72, 74, 63, 68, 70, 71], ["f", 30, 39, 22, 21, 28, 34, 40, 40, 21, 25, 30, 36.5], ["g", 80, 77, 83, 70, 77, 85, 90, 90, 70, 77, 80, 84], ["h", 100, 90, 110, 85, 95, 102, 110, 110, 85, 92.5, 100, 106] ]); var options = { title: 'Box Plot', height: 500, legend: { position: 'none' }, hAxis: { gridlines: { color: '#fff' } }, lineWidth: 0, series: [{ color: '#D3362D' }], intervals: { barWidth: 1, boxWidth: 1, lineWidth: 2, style: 'boxes' }, interval: { max: { style: 'bars', fillOpacity: 1, color: '#777' }, min: { style: 'bars', fillOpacity: 1, color: '#777' } } }; var chart = new google.visualization.LineChart(document.getElementById('box_plot')); chart.draw(data, options); } function drawTable() { var data = google.visualization.arrayToDataTable( [ [{ label: 'Var', type: 'string' }, { label: 'Max', id: 'max', type: 'number', }, { label: 'Min', id: 'min', type: 'number', }, { label: '1st Q', id: 'firstQuartile', type: 'number', }, { label: 'Median', id: 'median', type: 'number', }, { label: '3rd Q', id: 'thirdQuartile', type: 'number', } ], ['A', 120, 85, 93, 100, 107], ['B', 140, 90, 104, 120, 127], ['C', 140, 100, 111, 130, 136], ['D', 95, 85, 86.5, 90, 93.5], ['E', 120, 85, 93, 100, 107], ['F', 140, 90, 104, 120, 127], ['G', 140, 100, 111, 130, 136], ['H', 95, 85, 86.5, 90, 93.5], ['I', 120, 85, 93, 100, 107], ['J', 140, 90, 104, 120, 127], ['K', 140, 100, 111, 130, 136], ['L', 95, 85, 86.5, 90, 93.5] ]); var table = new google.visualization.Table(document.getElementById('table_div')); table.draw(data, { showRowNumber: true, width: '100%', height: '100%' }); }
 <script src="https://www.gstatic.com/charts/loader.js"></script> <div id="box_plot"></div> <div id="table_div"></div>

note: the table chart does not use any data roles,
I would remove role: 'interval' from the columns used there...

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