JohnUUU / code.pyret.org

Website for serving Pyret to folks.
Other
0 stars 0 forks source link

Intervals can be hidden by bars #10

Open eyanje opened 3 years ago

eyanje commented 3 years ago

With stacked bar charts, intervals (error bars etc.) are often drawn under other bars.

The interactive chart shows the intervals above the bars as expected. (The highest error bar is clipped, but that is covered in #12) image

However, when the chart is rendered to an Image, the intervals on a bar (let's say Bar A) will be covered up by another bar (Bar B) if Bar B is given after Bar A. image

The root of this problems seems to be with using the getImageURI() function in Google's API to render the chart to an image. The HTML/JS code at the bottom reproduces the Pyret code, with the same problem.

Code for the examples:

include chart
import lists as L

small-data = from-list.stacked-bar-chart(
    [list: "Year 1", "Year 2"],
    [list:
      [list: 50, 20, 10],
      [list: 20, 40, 10]],
    [list: "Mail", "Phone", "Fax"])
error-amounts = [list:
  [list: [list: -5, 2], [list: -4, 2], [list: -3, 2]],
  [list: [list: -3, 6], [list: -1, 4], [list: -5, 5]]]

with-error-bars = small-data.error-bars(error-amounts)

rendered-chart = render-chart(with-error-bars)

rendered-chart.display() # or get-image()
<html>
  <head>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
      google.charts.load('current', {'packages':['corechart']});
      google.charts.setOnLoadCallback(drawChart);

      function drawChart() {
        var data = new google.visualization.arrayToDataTable([
          ['', 'Mail', 'Phone', 'Fax'],
          ['Year 1', 50, 20, 10],
          ['Year 2', 20, 40, 10],
        ]);

        // Add intervals
        data.insertColumn(2, {type: 'number', role: 'interval'});
        data.insertColumn(2, {type: 'number', role: 'interval'});
        data.insertColumn(5, {type: 'number', role: 'interval'});
        data.insertColumn(5, {type: 'number', role: 'interval'});
        data.insertColumn(8, {type: 'number', role: 'interval'});
        data.insertColumn(8, {type: 'number', role: 'interval'});
        data.setValue(0, 2, 45);
        data.setValue(0, 3, 52);
        data.setValue(0, 5, 16);
        data.setValue(0, 6, 22);
        data.setValue(0, 8, 7);
        data.setValue(0, 9, 12);
        data.setValue(1, 2, 17);
        data.setValue(1, 3, 26);
        data.setValue(1, 5, 39);
        data.setValue(1, 6, 44);
        data.setValue(1, 8, 5);
        data.setValue(1, 9, 15);

        var options = {
          width: 800,
          height: 600,
          isStacked: true,
          legend: {position: 'top'}
        };

      var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
      chart.draw(data, options);
      document.getElementById('chart_img').src = chart.getImageURI();
    };
    </script>
  </head>
  <body>
    <h1>Interactive Chart</h1>
    <div id="chart_div"></div>
    <h1>Rendered Chart</h1>
    <img id="chart_img">
  </body>
</html>