vertical reference line in google timeline visualization

后端 未结 5 571
Happy的楠姐
Happy的楠姐 2020-11-28 13:58

Hi I am using google visualization api to draw a timeline chart in my website. It works just fine. But there is one little thing that is bothering me. I want to display a ve

5条回答
  •  伪装坚强ぢ
    2020-11-28 14:01

    to calculate the placement of the date marker,
    find the begin and end dates of the timeline
    use data table method --> getColumnRange()

    var dateRangeStart = dataTable.getColumnRange(2);
    var dateRangeEnd = dataTable.getColumnRange(3);
    

    then divide the width of the chart by the difference in milliseconds
    multiply the result by the difference of the start date and marker date

    the first 'path' element found is the line separating the row labels and the timeline,
    this can be used to offset the width of the row labels

    see following working snippet...

    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();  // keep example current
      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 formatDate = new google.visualization.DateFormat({
        pattern: 'MM/dd/yyyy'
      });
      var rowHeight = 44;
      var options = {
        height: (dataTableGroup.getNumberOfRows() * rowHeight) + rowHeight
      };
    
      function drawChart() {
        chart.draw(dataTable, options);
      }
    
      function addMarker(markerDate) {
        var baseline;
        var baselineBounds;
        var chartElements;
        var markerLabel;
        var markerLine;
        var markerSpan;
        var svg;
        var timeline;
        var timelineUnit;
        var timelineWidth;
        var timespan;
    
        baseline = null;
        timeline = null;
        svg = null;
        markerLabel = null;
        chartElements = container.getElementsByTagName('svg');
        if (chartElements.length > 0) {
          svg = chartElements[0];
        }
        chartElements = container.getElementsByTagName('rect');
        if (chartElements.length > 0) {
          timeline = chartElements[0];
        }
        chartElements = container.getElementsByTagName('path');
        if (chartElements.length > 0) {
          baseline = chartElements[0];
        }
        chartElements = container.getElementsByTagName('text');
        if (chartElements.length > 0) {
          markerLabel = chartElements[0].cloneNode(true);
        }
        if ((svg === null) || (timeline === null) || (baseline === null) || (markerLabel === null) ||
            (markerDate.getTime() < dateRangeStart.min.getTime()) ||
            (markerDate.getTime() > dateRangeEnd.max.getTime())) {
          return;
        }
    
        // calculate placement
        timelineWidth = parseFloat(timeline.getAttribute('width'));
        baselineBounds = baseline.getBBox();
        timespan = dateRangeEnd.max.getTime() - dateRangeStart.min.getTime();
        timelineUnit = (timelineWidth - baselineBounds.x) / timespan;
        markerSpan = markerDate.getTime() - dateRangeStart.min.getTime();
    
        // add label
        markerLabel.setAttribute('fill', '#e91e63');
        markerLabel.setAttribute('y', options.height);
        markerLabel.setAttribute('x', (baselineBounds.x + (timelineUnit * markerSpan) - 4));
        markerLabel.textContent = formatDate.formatValue(markerDate);
        svg.appendChild(markerLabel);
    
        // add line
        markerLine = timeline.cloneNode(true);
        markerLine.setAttribute('y', 0);
        markerLine.setAttribute('x', (baselineBounds.x + (timelineUnit * markerSpan)));
        markerLine.setAttribute('height', options.height);
        markerLine.setAttribute('width', 1);
        markerLine.setAttribute('stroke', 'none');
        markerLine.setAttribute('stroke-width', '0');
        markerLine.setAttribute('fill', '#e91e63');
        svg.appendChild(markerLine);
      }
    
      google.visualization.events.addListener(chart, 'ready', function () {
        // add marker for current date
        addMarker(new Date());
      });
    
      window.addEventListener('resize', drawChart, false);
      drawChart();
    });
    
    

提交回复
热议问题