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

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

问题描述

我正在尝试向 Google 烛台图表添加一些注释.我注意到有人已经问过同样的问题(向 Google 烛台图表添加注释).用户 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)

推荐答案

每根蜡烛线或柱线都将由一个 元素表示

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

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

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天全站免登陆