Chart.js, как отображать несколько меток на многостарочной диаграмме - PullRequest
0 голосов
/ 07 сентября 2018

Как я могу отображать разные метки под каждым столбцом, а также иметь другую метку для всей группы?

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

Линии тренда, которые соединяют отдельные столбцы, не так важны, но было бы замечательно, если бы я мог узнать, как их добавить.

Кроме того, график должен быть прокручиваемым, поскольку он может содержать большое количество данных и метки должны быть показаны. Я нашел несколько примеров со свитком.

Любая информация высоко ценится. Или есть какие-то другие платформы диаграмм с открытым исходным кодом, в которых я мог бы реализовать это или что-то подобное в соответствии со своими потребностями?

Chart

1 Ответ

0 голосов
/ 07 сентября 2018

используя гугл чарты ...

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

var chartLayout = chart.getChartLayoutInterface();

интерфейс имеет метод -> getBoundingBox()
который вернет позицию запрошенного элемента графика
чтобы получить позицию бара ...

var barBounds = chartLayout.getBoundingBox('bar#0#0');

, где первый #0 - это серия, а второй - строка,
'bar#0#0' получит первый столбец в первом ряду

мы также можем получить положение метки оси ...

var labelBounds = chartLayout.getBoundingBox('hAxis#0#label#0');

мы можем использовать комбинацию границ полосы и метки, чтобы разместить иконку
мы хотим, чтобы позиция left от бара, а позиция top от метки

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

google.charts.load('current', {
  packages: ['corechart']
}).then(function () {
  var data = new google.visualization.DataTable({
    cols: [
      {label: 'x', type: 'string'},
      {label: 'file', type: 'number', p: {icon: 'fa-file'}},
      {label: 'database', type: 'number', p: {icon: 'fa-database'}},
      {label: 'random', type: 'number', p: {icon: 'fa-random'}},
    ],
    rows: [
      {c:[{v: 'Label 1'}, {v: 11}, {v: 6}, {v: 15}]},
      {c:[{v: 'Label 2'}, {v: 8}, {v: null}, {v: 12}]},
      {c:[{v: 'Label 3'}, {v: 6}, {v: 8}, {v: 18}]},
      {c:[{v: 'Label 4'}, {v: null}, {v: 1}, {v: 16}]},
    ]
  });

  var options = {
    bar: {
      groupWidth: '50%',
      width: 20
    },
    colors: ['#ffc107', '#d32f2f', '#00bcd4'],
    height: 600,
    legend: 'none',
    title: 'Capacities',
    width: 1000,
  };

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

  google.visualization.events.addListener(chart, 'ready', function () {
    // initialize bounds variables
    var axisLabels = container.getElementsByTagName('text');
    var chartLayout = chart.getChartLayoutInterface();
    var chartBounds = chartLayout.getChartAreaBoundingBox();
    var containerBounds = container.getBoundingClientRect();
    var labelIndex;

    // add icons
    for (var r = 0; r < data.getNumberOfRows(); r++) {
      var barBounds;
      var icon;
      var iconBounds;
      var labelBounds = chartLayout.getBoundingBox('hAxis#0#label#' + r);
      for (var c = 1; c < data.getNumberOfColumns(); c++) {
        barBounds = chartLayout.getBoundingBox('bar#' + (c - 1) + '#' + r);
        if (barBounds !== null) {
          icon = container.appendChild(document.createElement('i'));
          icon.className = 'fa ' + data.getColumnProperty(c, 'icon');
          icon.style.position = 'absolute';
          iconBounds = icon.getBoundingClientRect();
          icon.style.top = (containerBounds.top + labelBounds.top) + 'px';
          icon.style.left = (barBounds.left + containerBounds.left + (barBounds.width / 2) - (iconBounds.width / 2)) + 'px';
        }
      }

      // move axis label down
      labelIndex = -1;
      Array.prototype.forEach.call(axisLabels, function(label) {
        if (label.getAttribute('text-anchor') === 'middle') {
          labelIndex++;
          if (labelIndex === r) {
            label.setAttribute('y', (parseFloat(label.getAttribute('y')) + (iconBounds.height * 2)));
          }
        }
      });
    }
  });

  chart.draw(data, options);
});
i {
  color: #00bcd4;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
...