Google Chart: How to draw the vertical axis for LineChart?

风流意气都作罢 提交于 2019-11-27 14:52:46

Gridlines are not supported for category axes. Because the data in question is using strings as the categories (X-axis labels), there is no way to tell how they "should" be split. You can get around this, however, with the following techniques.

Trick 1: Turn your Data Numerical

So right now you have strings which means no gridlines. We want gridlines though, so we have to correct that small problem. So we turn our first column (X) in to a number, with a format on it so it says 'A' or 'B' or 'C' when you mouse over it (and in the legend):

  var data = new google.visualization.DataTable();
  data.addColumn('number', 'x');
  data.addColumn('number', 'Cats');
  data.addColumn('number', 'Blanket 1');
  data.addRows([
    [{v: 1, f:'A'},   1,       10],
    [{v: 2, f:'B'},   2,       5],
    [{v: 3, f:'C'},   4,       12],
    [{v: 4, f:'D'},   8,       5]
  ]);

This doesn't solve the problem though. Now we have numbers on the bottom axis, cut off at weird 0.8 intervals. So we want to fix that. Unfortunately, with the hAxis, you can't set a min/max value and have it stick (I don't know why). We can fix the min by adding baseline: 0 to our options.

To get the max, we have to add a dummy series.

Put it all together, and we get this:

function drawVisualization() {
  // Create and populate the data table.
  var data = new google.visualization.DataTable();
  data.addColumn('number', 'x');
  data.addColumn('number', 'Cats');
  data.addColumn('number', 'Blanket 1');
  // This dummy series is to extend the chart from 0-5 for padding
  data.addColumn('number', null);
  data.addRows([
    [{v: 1, f:'A'}, 1, 10, null],
    [{v: 2, f:'B'}, 2, 5, null],
    [{v: 3, f:'C'}, 4, 12, null],
    [{v: 4, f:'D'}, 8, 5, null],
    [{v: 5, f:''}, null, null, {v: 0, f:''}]
  ]);

  options = {
    curveType: 'function',
    lineWidth: 2,
    hAxis: {
      // Show a baseline at 0
      baseline: 0,
      // 6 Gridlines, 4 labels + left and right for padding
      gridlines: {
        count: 6
      },
    },
    vAxis: {
      baseline: 0,
    },
    series: [
      {},
      {},
      // Hide our dummy series
      {
        lineWidth: 0,
        pointsize: 0,
        visibleInLegend: false
      },
    ]
  };
  chart1 = new google.visualization.LineChart(document.getElementById('visualization'));
  chart1.draw(data, options);
}

Now it's looking more like what you want. There are two main issues. One is that if you mouseover the bottom right of the chart, a blank tooltip pops up (this is not a huge issue I'd hope, though you may have to do some error trapping if you make the chart interactive with events). The other is that the bottom of our chart is showing numbers, not letters.

Unfortunately, there is no easy way to format numbers as letters (at least until Google implements the entire ICU pattern set rather than just dates/numbers). So we need to make another workaround. Basically, what I do is create an entirely new chart just to make the labels. I then format it so that it hides everything but the labels, and make sure that it lines up horizontally with the chart above.

  function drawVisualization() {
    // Create and populate the data table.
    var data = new google.visualization.DataTable();
    data.addColumn('number', 'x');
    data.addColumn('number', 'Cats');
    data.addColumn('number', 'Blanket 1');
    // This dummy series is to extend the chart from 0-5 for padding
    data.addColumn('number', null);
    data.addRows([
      [{v: 1, f:'A'}, 1, 10, null],
      [{v: 2, f:'B'}, 2, 5, null],
      [{v: 3, f:'C'}, 4, 12, null],
      [{v: 4, f:'D'}, 8, 5, null],
      [{v: 5, f:''}, null, null, {v: 0, f:''}]
    ]);

    options = {
      curveType: 'function',
      lineWidth: 2,
      hAxis: {
        // Show a baseline at 0
        baseline: 0,
        // 6 Gridlines, 4 labels + left and right for padding
        gridlines: {
          count: 6
        },
        // Hide our labels
        textPosition: 'none'
      },
      vAxis: {
        baseline: 0,
      },
      series: [
        {},
        {},
        // Hide our dummy series
        {
          lineWidth: 0,
          pointsize: 0,
          visibleInLegend: false
        },
      ]
    };

    // Add dummy data for the axis labels
    var data2 = new google.visualization.DataTable();
    data2.addColumn('string', 'x');
    data2.addColumn('number', 'dummy');
    data2.addRows([
      ['A', null],
      ['B', null],
      ['C', null],
      ['D', null]
    ]);

    chart1 = new google.visualization.LineChart(document.getElementById('visualization'));
    chart1.draw(data, options);

    chart2 = new google.visualization.LineChart(document.getElementById('visualization2'));
    chart2.draw(data2,
                {
                  chartArea: {
                    top:0,
                    height:"0%"
                  },
                  min: 0,
                  max: 0,
                  hAxis: {
                    baselineColor: '#FFFFFF'
                  },
                  vAxis: {
                    baselineColor: '#FFFFFF',
                    direction: -1,
                    textPosition: 'none',
                    gridlines: {
                      color: '#FFFFFF'
                    }
                  }
                });
  }

Just make another below the first one, and use CSS to align it properly (float it around the same position, or whatnot), and it looks like the labels belong to the chart above.

It ain't glorious, but it works.

There is a more elegant solution by using xticks: To do that we define a datatable like this:

var data = new google.visualization.DataTable();
        data.addColumn('number', 'Month');
        data.addColumn('number', 'Sales');
        data.addRows([
        [{v: 0, f:'Jan'}, 1000],
        [{v: 1, f:'Feb'}, 1170],
        [{v: 2, f:'Mar'}, 660],
        [{v: 3, f:'Apr'}, 1030]
    ]);

Where we set number values but also string labels for the Month axis.
With just this and the format attribute removed, we would get vertical lines but numbers instead of the strings for the x axis labels, which is not what we want.
To fix this we can set xticks to force the correct labels in the plot.

var options = {
        title: '',
        hAxis: {
            title: 'Month',
            titleTextStyle: {
                color: '#333'
            },
            baseline: 0,
            gridlines: {
                color: '#f3f3f3',
              count: 4
            },
           ticks: [{v: 0, f:'Jan'},{v: 1, f:'Feb'},{v: 2, f:'Mar'},{v: 3, f:'Apr'}], // <------- This does the trick
        },
        vAxis: {
            minValue: 0,
            gridlines: {
                color: '#f3f3f3',
                count: 5
            }
        }
    };

Hereby a complete working fiddle to show you how it can be done: http://jsfiddle.net/j29Pt/417/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!