Комбинированная диаграмма Google - интервалы с несколькими столбцами и линиями

Я пытаюсь создать комбинированную диаграмму с несколькими столбцами и линиями. Поскольку линии являются средними, я также хочу добавить минимальные и максимальные планки ошибок. Google называет их «интервалами».

Проблема в том, что линии выравниваются по центру тактов (между двумя, что нормально), но интервалы для этих линий, похоже, вместо этого совпадают с первым тактом. Смотрите мой пример. Пример проблемы

Мой код, как показано ниже. Любая помощь высоко ценится! Возможно, это ошибка Google? Или может быть есть параметр выравнивания, который я пропустил?

JSFiddle здесь

      google.charts.load('current', {'packages': ['corechart']});
  google.charts.setOnLoadCallback(drawVisualization);

  function drawVisualization() {
    // Some raw data (not necessarily accurate)
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'Week'); // Implicit domain label col.

    data.addColumn('number', 'A average'); // Implicit series 1 data col.
    data.addColumn({type: 'string', role: 'annotation'}); // annotationText col.

    data.addColumn('number', 'A rolling average'); // Implicit series 1 data col.
    data.addColumn({type: 'number', role: 'interval'});  // interval role col.
    data.addColumn({type: 'number', role: 'interval'});  // interval role col.

    data.addColumn('number', 'B average'); // Implicit series 1 data col.
    data.addColumn({type: 'string', role: 'annotation'}); // annotationText col.

    data.addColumn('number', 'B 4wk average'); // Implicit series 1 data col.
    data.addColumn({type: 'number', role: 'interval'});  // interval role col.
    data.addColumn({type: 'number', role: 'interval'});  // interval role col.
    data.addRows([ 
      ['1 (01/03/17)', 0.1, 'A1', 0.2, 0.19, 0.21, 0.20, 'A2', 0.67, 0.66, 0.68],  
      ['2 (08/03/17)', 0.23, 'B1', 0.90, 0.89, 0.91, 0.76, 'B2', 0.43, 0.42, 0.44],  
      ['3 (15/03/17)', 0.10, 'C1', 0.65, 0.63, 0.66, 0.34, 'C2', 0.89, 0.88, 0.90],  
      ['4 (22/03/17)', 0.22, 'D1', 0.20, 0.19, 0.21, 0.23, 'D2', 0.43, 0.42, 0.44]
      //  ['1 (01/03/17)',10,  2, 11,  'A'],
        //  ['2 (08/03/17)',  23, 20, 25,  'B'],
        //  ['3 (15/03/17)',  1,  0.95,  1.15,  'C'],
        //  ['4 (22/03/17)', 22, 20, 30, 'D']
    ]);


    var options = {
      title: 'Test',
      vAxis: {
        title: '% average',
        format: '# %'
      },
      hAxis: {
        title: 'Week number (week commencing)'
      },
      seriesType: 'bars',
      series: {
        1: {type: 'line'},
        3: {type: 'line'}
      },
      intervals: {
        style: 'boxes'
      }
    };

    var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
    chart.draw(data, options);

  }

person TomPygo    schedule 10.03.2017    source источник


Ответы (1)


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

одним из вариантов было бы переместить их вручную, когда срабатывает событие диаграммы 'ready'

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

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


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

google.charts.load('current', {
  callback: drawVisualization,
  packages: ['corechart']
});

function drawVisualization() {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Week'); // Implicit domain label col.

  data.addColumn('number', 'A average'); // Implicit series 1 data col.
  data.addColumn({type:'string', role:'annotation'}); // annotationText col.

  data.addColumn('number', 'A rolling average'); // Implicit series 1 data col.
  data.addColumn({type:'number', role:'interval'});  // interval role col.
  data.addColumn({type:'number', role:'interval'});  // interval role col.

  data.addColumn('number', 'B average'); // Implicit series 1 data col.
  data.addColumn({type:'string', role:'annotation'}); // annotationText col.

  data.addColumn('number', 'B 4wk average'); // Implicit series 1 data col.
  data.addColumn({type:'number', role:'interval'});  // interval role col.
  data.addColumn({type:'number', role:'interval'});  // interval role col.
  data.addRows([
    ['1 (01/03/17)',0.10, 'A1', 0.20,0.19,0.21, 0.20, 'A2', 0.67,0.66,0.68],
    ['2 (08/03/17)',0.23, 'B1', 0.90,0.89,0.91, 0.76, 'B2', 0.43,0.42,0.44],
    ['3 (15/03/17)',0.10, 'C1', 0.65,0.63,0.66, 0.34, 'C2', 0.89,0.88,0.90],
    ['4 (22/03/17)',0.22, 'D1', 0.20,0.19,0.21, 0.23, 'D2', 0.43,0.42,0.44]
  ]);

  var options = {
    title : 'Test',
    vAxis: {title: '% average',format:'# %'},
    hAxis: {title: 'Week number (week commencing)'},
    height: 600,
    seriesType: 'bars',
    series: {
      1: {type: 'line'},
      3: {type: 'line'}
    },
    tooltip: {trigger: 'both'},
    intervals: {style: 'boxes'},
    width: 900
  };

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

  var observer = new MutationObserver(function () {
    getIntervals().forEach(function (rect, index) {
      rect.setAttribute('x', xCoords[index]);
    });
  });

  var xCoords = {};
  google.visualization.events.addListener(chart, 'ready', function () {
    getIntervals().forEach(function (rect, index) {
      xCoords[index] = parseFloat(rect.getAttribute('x')) + 22;
      rect.setAttribute('x', xCoords[index]);
    });

    observer.observe(chartDiv, {
      childList: true,
      subtree: true
    });
  });

  function getIntervals() {
    var intervals = [];
    Array.prototype.forEach.call(chartDiv.getElementsByTagName('rect'), function(rect) {
      if ((rect.getAttribute('fill') === '#a52b0e') ||
          (rect.getAttribute('fill') === '#0c7112')) {
        intervals.push(rect);
      }
    });
    return intervals;
  }

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


примечание: смещение, используемое для перемещения координаты x (22), останется постоянным,
до тех пор, пока размер диаграммы остается постоянным
и, возможно, потребуется отрегулировать ширину изменения графика...

person WhiteHat    schedule 10.03.2017
comment
Спасибо за помощь! - person TomPygo; 27.03.2017