在Google烛台图表中添加注释(发布的解决方案会触发TypeError) [英] Adding annotations to Google candlestick chart (Posted solution triggers TypeError)

查看:61
本文介绍了在Google烛台图表中添加注释(发布的解决方案会触发TypeError)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试向Google烛台图表添加一些注释.我注意到有人已经问过同样的问题(向Google Candlestick图表添加注释 ).用户Aperçu回答了详细的解决方案,以扩展图表并添加注释,因为图表没有内置任何此类功能.但是,当我尝试此解决方案时,出现错误"TypeError:document.querySelectorAll(...)[0]未定义"

I am trying to add some annotations to a Google Candlestick chart. I noticed someone had already asked this same question (Adding annotations to Google Candlestick chart). The user Aperçu replied with a detailed solution to extend the chart and add annotations since the chart doesn't have any such feature built in. However, when I try this solution I get an error "TypeError: document.querySelectorAll(...)[0] is undefined"

这是我的代码:

        chartPoints = [
            ['Budget', 0, 0, 9999, 9999, 'foo1'],
            ['Sales', 0, 0, 123, 123, 'foo2'],
            ['Backlog', 123, 123, 456, 456, 'foo3'],
            ['Hard Forecast', 456, 456, 789, 789, 'foo4'],
            ['Sales to Budget', 789, 789, 1000, 1000, 'foo5']
        ];
        var data = google.visualization.arrayToDataTable(chartPoints, true);
        data.setColumnProperty(5, 'role', 'annotation');
        var options = {
            legend: 'none',
            bar: { groupWidth: '40%', width: '100%' },
            candlestick: {
                fallingColor: { strokeWidth: 0, fill: '#a52714' },
                risingColor: { strokeWidth: 0, fill: '#0f9d58' }
            }
        };    

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

        // attempt to use Aperçu's solution
        const bars = document.querySelectorAll('#chart_div svg > g:nth-child(5) > g')[0].lastChild.children // this triggers a TypeError
        for (var i = 0 ; i < bars.length ; i++) {
          const bar = bars[i]
          const { top, left, width } = bar.getBoundingClientRect()
          const hint = document.createElement('div')
          hint.style.top = top + 'px'
          hint.style.left = left + width + 5 + 'px'
          hint.classList.add('hint')
          hint.innerText = rawData.filter(t => t[1])[i][0]
          document.getElementById('chart_div').append(hint)
        }

我希望图表在条形图旁边显示最后一条数据(即"foo1","foo2"等)

I want the chart to show the last piece of data next to the bars (i.e. "foo1", "foo2", etc)

推荐答案

每个蜡烛或条形图均由<rect>元素

each candle or bar will be represented by a <rect> element

我们可以使用上升和下降颜色将条形图与图表中的其他<rect>元素分开

we can use the rise and fall colors to separate the bars from other <rect> elements in the chart

与数据表中的行有相同数量的条形

there will be the same number of bars as rows in the data table

找到第一个小节后,可以使用零的rowIndex从数据中提取值

once we find the first bar, we can use rowIndex of zero to pull values from the data

我们需要找到上升/下降的值,才能知道在何处放置注释

we need to find the value of the rise / fall, to know where to place the annotation

然后使用图表方法查找注释的位置

then use chart methods to find the location for the annotation

getChartLayoutInterface()-返回一个对象,其中包含有关图表及其元素在屏幕上的位置的信息.

getChartLayoutInterface() - Returns an object containing information about the onscreen placement of the chart and its elements.

getYLocation(position, optional_axis_index)-返回相对于图表容器的位置的屏幕y坐标.

getYLocation(position, optional_axis_index) - Returns the screen y-coordinate of position relative to the chart's container.

请参阅以下工作片段
添加了两个注释
一个代表上升和下降的差异
另一个用于具有注释角色的列中的值

see following working snippet
two annotations are added
one for the difference in rise and fall
and the other for the value in the column with annotation role

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

function drawChart() {
  var chartPoints = [
    ['Budget', 0, 0, 9999, 9999, 'foo1'],
    ['Sales', 0, 0, 123, 123, 'foo2'],
    ['Backlog', 123, 123, 456, 456, 'foo3'],
    ['Hard Forecast', 456, 456, 789, 789, 'foo4'],
    ['Sales to Budget', 789, 789, 1000, 1000, 'foo5']
  ];
  var data = google.visualization.arrayToDataTable(chartPoints, true);
  data.setColumnProperty(5, 'role', 'annotation');
  var options = {
    legend: 'none',
    bar: { groupWidth: '40%', width: '100%' },
    candlestick: {
      fallingColor: { strokeWidth: 0, fill: '#a52714' },
      risingColor: { strokeWidth: 0, fill: '#0f9d58' }
    }
  };

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

  google.visualization.events.addListener(chart, 'ready', function () {
    var annotation;
    var bars;
    var chartLayout;
    var formatNumber;
    var positionY;
    var positionX;
    var rowBalance;
    var rowBottom;
    var rowIndex;
    var rowTop;
    var rowValue;
    var rowWidth;

    chartLayout = chart.getChartLayoutInterface();
    rowIndex = 0;
    formatNumber = new google.visualization.NumberFormat({
      pattern: '#,##0'
    });

    bars = container.getElementsByTagName('rect');
    for (var i = 0; i < bars.length; i++) {
      switch (bars[i].getAttribute('fill')) {
        case '#a52714':
        case '#0f9d58':
          rowWidth = parseFloat(bars[i].getAttribute('width'));
          if (rowWidth > 2) {
            rowBottom = data.getValue(rowIndex, 1);
            rowTop = data.getValue(rowIndex, 3);
            rowValue = rowTop - rowBottom;
            rowBalance = Math.max(rowBottom, rowTop);
            positionY = chartLayout.getYLocation(rowBalance) - 6;
            positionX = parseFloat(bars[i].getAttribute('x'));

            // row value
            annotation = container.getElementsByTagName('svg')[0].appendChild(container.getElementsByTagName('text')[0].cloneNode(true));
            annotation.textContent = formatNumber.formatValue(rowValue);
            annotation.setAttribute('x', (positionX + (rowWidth / 2)));
            annotation.setAttribute('y', positionY);
            annotation.setAttribute('font-weight', 'bold');

            // annotation column
            annotation = container.getElementsByTagName('svg')[0].appendChild(container.getElementsByTagName('text')[0].cloneNode(true));
            annotation.textContent = data.getValue(rowIndex, 5);
            annotation.setAttribute('x', (positionX + (rowWidth / 2)));
            annotation.setAttribute('y', positionY - 18);
            annotation.setAttribute('font-weight', 'bold');

            rowIndex++;
          }
          break;
      }
    }
  });

  chart.draw(data, options);
}

<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

这篇关于在Google烛台图表中添加注释(发布的解决方案会触发TypeError)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆