【问题标题】:How to add custom markers to Google Timeline Chart?如何将自定义标记添加到 Google 时间轴图表?
【发布时间】:2020-09-10 07:42:47
【问题描述】:

我想在 Google 时间轴图表上添加标记,如下所示Timeline Chart with Markers

我目前正在关注此处给出的解决方案:Google Charts Add Layer On Top Of Timeline。但是,这里需要有一个时间线元素,然后标记才能出现在它上面。但是,我想要一种可以添加标记的方法,而在行中的该位置没有任何时间线数据。是否有在 Google 时间轴中添加标记的内置功能,或者不需要添加虚拟时间轴的自定义方式。

【问题讨论】:

    标签: javascript charts google-visualization


    【解决方案1】:

    没有用于添加标记的内置功能。 并且由于您引用的答案是自定义解决方案,
    我们可以修改解决方案以满足我们的需求。

    我们不一定需要时间线元素来放置标记。
    但我们确实需要数据来绘制时间线,
    放置标记的位置。

    开箱即用,时间线会将 x 轴限制在数据中找到的日期范围内。

    但我们可以设置自定义 x 轴范围,使其更大,
    并为没有时间线元素的标记留出更多空间。

    hAxis: {
      minValue: dateRangeStart,
      maxValue: dateRangeEnd,
    }
    

    请参阅以下工作 sn-p...

    google.charts.load('current', {
      packages:['timeline']
    }).then(function () {
      var container = document.getElementById('timeline');
      var chart = new google.visualization.Timeline(container);
      var dataTable = new google.visualization.DataTable();
      dataTable.addColumn({type: 'string', id: 'Row'});
      dataTable.addColumn({type: 'string', id: 'Bar'});
      dataTable.addColumn({type: 'date', id: 'Start'});
      dataTable.addColumn({type: 'date', id: 'End'});
      var currentYear = (new Date()).getFullYear();
      dataTable.addRows([
        ['Row 1', 'A-1', new Date(currentYear, 0, 1), new Date(currentYear, 2, 31)],
        ['Row 1', 'A-2', new Date(currentYear, 3, 1), new Date(currentYear, 5, 30)],
        ['Row 2', 'B-1', new Date(currentYear, 6, 1), new Date(currentYear, 8, 31)],
        ['Row 2', 'B-2', new Date(currentYear, 9, 1), new Date(currentYear, 11, 31)]
      ]);
      var dataTableGroup = google.visualization.data.group(dataTable, [0]);
      var dateRangeStart = new Date(currentYear - 1, 0, 1);
      var dateRangeEnd = new Date(currentYear + 1, 11, 31);
      var rowHeight = 44;
      var options = {
        height: (dataTableGroup.getNumberOfRows() * rowHeight) + rowHeight,
        hAxis: {
          minValue: dateRangeStart,
          maxValue: dateRangeEnd,
        }
      };
    
      function drawChart() {
        chart.draw(dataTable, options);
      }
    
      // add custom marker
      function addMarkers(events) {
        var baseline;
        var baselineBounds;
        var chartElements;
        var labelFound;
        var labelText;
        var marker;
        var markerLabel;
        var markerSpan;
        var rowLabel;
        var svg;
        var svgNS;
        var timeline;
        var timelineUnit;
        var timelineWidth;
        var timespan;
        var xCoord;
        var yCoord;
    
        // initialize chart elements
        baseline = null;
        svg = null;
        svgNS = null;
        timeline = null;
        chartElements = container.getElementsByTagName('svg');
        if (chartElements.length > 0) {
          svg = chartElements[0];
          svgNS = svg.namespaceURI;
        }
        chartElements = container.getElementsByTagName('rect');
        if (chartElements.length > 0) {
          timeline = chartElements[0];
        }
        chartElements = container.getElementsByTagName('path');
        if (chartElements.length > 0) {
          baseline = chartElements[0];
        }
        if ((svg === null) || (timeline === null) || (baseline === null)) {
          return;
        }
        timelineWidth = parseFloat(timeline.getAttribute('width'));
        baselineBounds = baseline.getBBox();
        timespan = dateRangeEnd.getTime() - dateRangeStart.getTime();
        timelineUnit = (timelineWidth - baselineBounds.x) / timespan;
    
        // add events
        events.forEach(function (event) {
          // find row label
          rowLabel = dataTable.getValue(event.row, 0);
          chartElements = container.getElementsByTagName('text');
          if (chartElements.length > 0) {
            Array.prototype.forEach.call(chartElements, function(label) {
              if (label.textContent.indexOf('…') > -1) {
                labelText = label.textContent.replace('…', '');
              } else {
                labelText = label.textContent;
              }
              if (rowLabel.indexOf(labelText) > -1) {
                markerLabel = label.cloneNode(true);
              }
            });
          }
    
          // calculate placement
          markerSpan = event.date.getTime() - dateRangeStart.getTime();
    
          // add label
          markerLabel.setAttribute('text-anchor', 'start');
          markerLabel.setAttribute('fill', event.color);
          markerLabel.setAttribute('x', (baselineBounds.x + (timelineUnit * markerSpan) + 6));
          markerLabel.textContent = event.name;
          svg.appendChild(markerLabel);
    
          // add marker
          xCoord = (baselineBounds.x + (timelineUnit * markerSpan) - 4);
          yCoord = parseFloat(markerLabel.getAttribute('y'));
          switch (event.type) {
            case 'triangle':
              marker = document.createElementNS(svgNS, 'polygon');
              marker.setAttribute('fill', 'transparent');
              marker.setAttribute('stroke', event.color);
              marker.setAttribute('stroke-width', '3');
              marker.setAttribute('points', xCoord + ',' + (yCoord - 10) + ' ' + (xCoord - 5) + ',' + yCoord + ' ' + (xCoord + 5) + ',' + yCoord);
              svg.appendChild(marker);
              break;
    
            case 'circle':
              marker = document.createElementNS(svgNS, 'circle');
              marker.setAttribute('cx', xCoord);
              marker.setAttribute('cy', yCoord - 5);
              marker.setAttribute('r', '6');
              marker.setAttribute('stroke', event.color);
              marker.setAttribute('stroke-width', '3');
              marker.setAttribute('fill', 'transparent');
              svg.appendChild(marker);
              break;
          }
        });
      }
    
      google.visualization.events.addListener(chart, 'ready', function () {
        addMarkers([
          {row: 0, date: new Date(currentYear - 1, 1, 11), name: 'Event 1', type: 'triangle', color: 'red'},
          {row: 1, date: new Date(currentYear + 1, 5, 23), name: 'Event 2', type: 'circle', color: 'purple'},
          {row: 3, date: new Date(currentYear + 1, 8, 2), name: 'Event 3', type: 'triangle', color: 'magenta'}
        ]);
      });
    
      window.addEventListener('resize', drawChart, false);
      drawChart();
    });
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="timeline"></div>

    【讨论】:

      猜你喜欢
      • 2011-04-14
      • 2023-01-16
      • 2014-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-07
      相关资源
      最近更新 更多