Как вставить точки поверх гистограмм с помощью Google Charts? - PullRequest
1 голос
/ 06 мая 2020

Учитывая иллюстрацию

enter image description here

Мне удалось создать диаграмму (без точек), используя следующий код:

<html>
  <head>
      <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
      google.charts.load('current', {'packages':['bar']});
      google.charts.setOnLoadCallback(drawStuff);

      var chart;

      function drawStuff() {
        var data = new google.visualization.arrayToDataTable([
          ['Y', 'Series 1','Series 2'],
          ["Element A", 44,11],
          ["Element B", 31,11],
          ["Element C", 12,11],
        ]);

        var options = {
          bars: 'horizontal', // Required for Material Bar Charts.
          axes: {
            x: {
              0: { side: 'bottom', label: 'X'} // Top x-axis.
            }
          }
        };

        var div = document.getElementById('top_x_div');
        var link = document.getElementById('url');
        chart = new google.charts.Bar(div);
        chart.draw(data, options);
        //console.log(chart.getImageURI());
      };
    </script>
  </head>
  <body>
    <div id="top_x_div" style="width: 900px; height: 500px;"></div>
  </body>
</html>

Как вставить точки поверх гистограмм с помощью Google Charts?

1 Ответ

1 голос
/ 06 мая 2020

я придумал несколько способов, чтобы выполнить sh ...

  1. Используйте комбинированную диаграмму
  2. Добавьте точки вручную на 'ready' диаграммы event

однако ни один из вариантов не может быть реализован с помощью диаграммы материала .

google.charts.Bar

во-первых, материал диаграммы не поддерживают Комбо-диаграммы. и, материалы диаграммы не имеют методов , необходимых для добавления точек вручную.

не говоря уже о том, есть также несколько вариантов, которые материал графики не поддерживаются. см. -> Проблема отслеживания для четности функций диаграммы материалов # 2143

, поэтому мы должны использовать classi c диаграмму ...

google.visualization.BarChart

есть опция, которую мы можем использовать, чтобы придать диаграмме classi c аналогичный внешний вид материал диаграммы ...

theme: 'material'

теперь решение ...

при попытке использовать комбинированную диаграмму, точки выравниваются по оси y между двумя полосами. не существует опции, которая позволила бы точкам выровнять на столбцах. поэтому мы должны добавлять точки вручную, на графике событие 'ready' ...

есть несколько графиков методов нам нужно ...

getChartLayoutInterface() - возвращает объект, содержащий информацию о размещении диаграммы и ее элементов на экране.

getBoundingBox(id) - возвращает объект, содержащий левую, верхнюю, ширину и высоту идентификатора элемента диаграммы.

getXLocation(position, optional_axis_index) - возвращает координату по оси x экрана относительно контейнера диаграммы.

после срабатывания события 'ready' диаграммы мы можем получить интерфейс макета, используя -> getChartLayoutInterface()

два других метода, упомянутых выше, являются методами интерфейса макета.

мы используем getBoundingBox(id) для получения координат полосы, на которой будет размещена точка. это даст нам координату Y и высоту точки. идентификатор полосы определяется строкой данных и столбцом серии.

bar#C#R  // where C is the series column index, and R is the row index

мы предоставляем координату X, getXLocation предоставит местоположение на диаграмме, необходимое для размещения точки на оси x, в нашем заранее определенном месте.

// x coordinates of points to add
var points = [
  [36, 8],
  [28, 8],
  [10, 8],
];

// loop data rows and columns
for (var r = 0; r < data.getNumberOfRows(); r++) {
  for (var c = 1; c < data.getNumberOfColumns(); c++) {
    // calculate position of the point
    var barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
    var xCoord = chartLayout.getXLocation(points[r][c - 1]);
    var height = barBounds.height / 4;
    var top = barBounds.top + (height * 2);

    // create and add the point to the chart
    var point = document.createElementNS(svgNS, 'circle');
    point.setAttribute('cx', xCoord);
    point.setAttribute('cy', top);
    point.setAttribute('r', height);
    point.setAttribute('stroke', '#ffffff');
    point.setAttribute('stroke-width', height);
    point.setAttribute('fill', 'transparent');
    svg.appendChild(point);
  }
}

см. Следующий рабочий фрагмент ...

var chart;

google.charts.load('current', {
  packages: ['corechart']
}).then(function drawStuff() {
  var data = new google.visualization.arrayToDataTable([
    ['Y', 'Series 1', 'Series 2'],
    ['Element A', 44, 11],
    ['Element B', 31, 11],
    ['Element C', 12, 11],
  ]);

  // x coordinates of points to add
  var points = [
    [36, 8],
    [28, 8],
    [10, 8],
  ];

  var options = {
    chartArea: {
      left: 128,
      top: 24,
      right: 128,
      bottom: 72,
      height: '100%',
      width: '100%'
    },
    hAxis: {
      title: 'X'
    },
    height: '100%',
    theme: 'material',
    vAxis: {
      title: data.getColumnLabel(0)
    },
    width: '100%'
  };

  var div = document.getElementById('top_x_div');
  //var link = document.getElementById('url');

  chart = new google.visualization.BarChart(div);

  google.visualization.events.addListener(chart, 'ready', function () {
    // get chart layour interface and svg
    var chartLayout = chart.getChartLayoutInterface();
    var svg = div.getElementsByTagName('svg')[0];
    var svgNS = svg.namespaceURI;

    // loop data rows and columns
    for (var r = 0; r < data.getNumberOfRows(); r++) {
      for (var c = 1; c < data.getNumberOfColumns(); c++) {
        // calculate position of the point
        var barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
        var xCoord = chartLayout.getXLocation(points[r][c - 1]);
        var height = barBounds.height / 4;
        var top = barBounds.top + (height * 2);

        // create and add the point to the chart
        var point = document.createElementNS(svgNS, 'circle');
        point.setAttribute('cx', xCoord);
        point.setAttribute('cy', top);
        point.setAttribute('r', height);
        point.setAttribute('stroke', '#ffffff');
        point.setAttribute('stroke-width', height);
        point.setAttribute('fill', 'transparent');
        svg.appendChild(point);
      }
    }
  });

  chart.draw(data, options);
  window.addEventListener('resize', function () {
    chart.draw(data, options);
  });
});
#top_x_div {
  height: 400px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="top_x_div"></div>
...