首页 > 解决方案 > 带有自定义注释的谷歌阶梯面积图

问题描述

感谢这篇文章中的白帽,我能够为面积图制作自定义注释。不知何故,阶梯式面积图不起作用。

该图表首先正确地绘制了所有内容,但随后将阶梯区域图中的注释设置回来。在 的帮助下MutationObserver,绘制图表时应覆盖设置,但这仅适用于面积图。

我该如何解决这个问题?

<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']
}).then(function () {
  var data1 = new google.visualization.DataTable();

  data1.addColumn('number', 'x');
  data1.addColumn('number', 'green');

  data1.addRows([
    [0.005, 3],
    [0.006, 6],
    [0.007, 5],
    [0.008, 8],
    [0.009, 2],
    [0.010, 5],
    [0.011, 5],
    [0.012, 4],
    [0.013, 8]
  ]);

  var data2 = new google.visualization.DataTable();
  data2.addColumn('number', 'x');
  data2.addColumn('number', 'red');

  data2.addRows([
    [0.016, 5],
    [0.017, 1],
    [0.018, 3],
    [0.019, 9],
    [0.020, 4],
    [0.021, 5],
    [0.022, 7],
    [0.023, 7],
    [0.024, 3]
  ]);


  var joinedData = google.visualization.data.join(data1, data2, 'full',
    [[0, 0]], [1], [1]);

  var options = {
    annotations: {
      stem: {
        length: 10
      }
    },
    title: 'Playground',
    colors: ['#007f01', '#fe0002'],
    interpolateNulls: true,
    hAxis: {
      titleTextStyle: {
        color: '#333'
      },
      direction: 1,
      format: 'decimal'
    },
    vAxis: {
      direction: 1
    },
    orientation: 'horizontal',

    // customize colum
    series: {
      0: {type: "steppedArea"},
      1: {type: "area"},
    },

    // legend: {position : 'left'},
    animation: {
      startup: true,
      duration: 1000,
      easing: 'out',
    }
  };

  var view = new google.visualization.DataView(joinedData);
  view.setColumns([0,
    1,
    {
      calc: "stringify",
      sourceColumn: 1,
      type: "string",
      role: "annotation"
    },
    2,
    {
      calc: "stringify",
      sourceColumn: 2,
      type: "string",
      role: "annotation"
    }
  ]);

  var container = document.getElementById('chart_div');
  var chart = new google.visualization.ComboChart(container);

  var observer = new MutationObserver(moveAnnotations);
  observer.observe(container, {
    childList: true,
    subtree: true
  });

  function moveAnnotations() {
    var chartLayout = chart.getChartLayoutInterface();
    var chartBounds = chartLayout.getChartAreaBoundingBox();

    var labels = container.getElementsByTagName('text');
    var labelSize = 0;
    Array.prototype.forEach.call(labels, function(label) {
      if (label.getAttribute('text-anchor') === 'middle') {
        if (options.colors.indexOf(label.getAttribute('fill')) > -1) {
          labelSize = (parseFloat(label.getAttribute('font-size')) / 2);
          label.setAttribute('y', chartBounds.top + labelSize);
        }
      }
    });

    var stems = container.getElementsByTagName('rect');
    Array.prototype.forEach.call(stems, function(stem) {
      if ((parseInt(stem.getAttribute('height')) === options.annotations.stem.length) && (stem.getAttribute('fill') === '#999999')) {
        var height = parseFloat(stem.getAttribute('y')) - chartBounds.top;
        stem.setAttribute('height', height);
        stem.setAttribute('y', chartBounds.top + labelSize);
      }
    });
  }

  chart.draw(view.toDataTable(), options);
});
  </script>
</head>

<body>
  <div id="chart_div" style="width: 100%; height: 500px;"></div>
</body>

</html>

标签: chartsgoogle-visualization

解决方案


阶梯面积图的默认注释设置与普通面积图不同

对于stepped,注释出现在区域内,这会将颜色更改为白色,
这不是用于查找标签并移动它们的颜色

一个简单的解决方法是指定注释始终位于该区域之外......

annotations: {
  alwaysOutside: true,
  ...

请参阅以下工作片段...

google.charts.load('current', {
  packages: ['corechart']
}).then(function () {
  var data1 = new google.visualization.DataTable();

  data1.addColumn('number', 'x');
  data1.addColumn('number', 'green');

  data1.addRows([
    [0.005, 3],
    [0.006, 6],
    [0.007, 5],
    [0.008, 8],
    [0.009, 2],
    [0.010, 5],
    [0.011, 5],
    [0.012, 4],
    [0.013, 8]
  ]);

  var data2 = new google.visualization.DataTable();
  data2.addColumn('number', 'x');
  data2.addColumn('number', 'red');

  data2.addRows([
    [0.016, 5],
    [0.017, 1],
    [0.018, 3],
    [0.019, 9],
    [0.020, 4],
    [0.021, 5],
    [0.022, 7],
    [0.023, 7],
    [0.024, 3]
  ]);


  var joinedData = google.visualization.data.join(data1, data2, 'full',
    [[0, 0]], [1], [1]);

  var options = {
    annotations: {
      alwaysOutside: true,
      stem: {
        length: 10
      }
    },
    title: 'Playground',
    colors: ['#007f01', '#fe0002'],
    interpolateNulls: true,
    hAxis: {
      titleTextStyle: {
        color: '#333'
      },
      direction: 1,
      format: 'decimal'
    },
    vAxis: {
      direction: 1
    },
    orientation: 'horizontal',

    // customize colum
    series: {
      0: {type: "steppedArea"},
      1: {type: "area"},
    },

    // legend: {position : 'left'},
    animation: {
      startup: true,
      duration: 1000,
      easing: 'out',
    }
  };

  var view = new google.visualization.DataView(joinedData);
  view.setColumns([0,
    1,
    {
      calc: "stringify",
      sourceColumn: 1,
      type: "string",
      role: "annotation"
    },
    2,
    {
      calc: "stringify",
      sourceColumn: 2,
      type: "string",
      role: "annotation"
    }
  ]);

  var container = document.getElementById('chart_div');
  var chart = new google.visualization.ComboChart(container);

  var observer = new MutationObserver(moveAnnotations);
  observer.observe(container, {
    childList: true,
    subtree: true
  });

  function moveAnnotations() {
    var chartLayout = chart.getChartLayoutInterface();
    var chartBounds = chartLayout.getChartAreaBoundingBox();

    var labels = container.getElementsByTagName('text');
    var labelSize = 0;
    Array.prototype.forEach.call(labels, function(label) {
      if (label.getAttribute('text-anchor') === 'middle') {
        if (options.colors.indexOf(label.getAttribute('fill')) > -1) {
          labelSize = (parseFloat(label.getAttribute('font-size')) / 2);
          label.setAttribute('y', chartBounds.top + labelSize);
        }
      }
    });

    var stems = container.getElementsByTagName('rect');
    Array.prototype.forEach.call(stems, function(stem) {
      if ((parseInt(stem.getAttribute('height')) === options.annotations.stem.length) && (stem.getAttribute('fill') === '#999999')) {
        var height = parseFloat(stem.getAttribute('y')) - chartBounds.top;
        stem.setAttribute('height', height);
        stem.setAttribute('y', chartBounds.top + labelSize);
      }
    });
  }

  chart.draw(view.toDataTable(), options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>


推荐阅读