谷歌图表添加图层在最前面时间安排

问题描述 投票:0回答:1

我期待在时间轴上绘制了一系列的开始和结束日期的事件。这似乎是谷歌图表库在时间轴上的图表类型提供特定的功能。

我还需要绘制单一,准时事件(不仅发生在开始/结束的时间跨度事件),并与如圆形,三角形或其他符号代表他们。

我想知道是否有可能在时间轴上添加另一层这样做呢?或许可以添加自定义形状,以表示事件已匹配的存在/结束日期?

任何有识之士将是巨大的!

javascript charts google-visualization google-chartwrapper
1个回答
0
投票

还有,你可以用它来添加另一层/自定义形状没有标准的选项。

但图表的SVG可以手动修改,一旦图表的'ready'事件触发。

看到下面的工作片段, 功能addMarkers将增加自定义形状给定日期和行。

通过“事件”将被添加到图表的阵列。

addMarkers([
  {row: 0, date: new Date(currentYear, 1, 11), name: 'Event A', type: 'triangle', color: 'yellow'},
  {row: 2, date: new Date(currentYear, 10, 15), name: 'Event B', type: 'circle', color: 'lime'}
]);

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 = dataTable.getColumnRange(2);
  var dateRangeEnd = dataTable.getColumnRange(3);
  var rowHeight = 44;
  var options = {
    height: (dataTableGroup.getNumberOfRows() * rowHeight) + rowHeight
  };

  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.max.getTime() - dateRangeStart.min.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.min.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, 11), name: 'Event A', type: 'triangle', color: 'yellow'},
      {row: 2, date: new Date(currentYear, 10, 15), name: 'Event B', type: 'circle', color: 'lime'}
    ]);
  });

  window.addEventListener('resize', drawChart, false);
  drawChart();
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>
© www.soinside.com 2019 - 2024. All rights reserved.