1

I have a google chart timeline with a list of different contracts in each row. Having the start and end date is easy, but i also want do show specific moments in each row (let's say tenant contract deadline, and other important moments) - it could be something like a dot in the date of that moment.

I have already search a lot but can't find a example

this is what i have: sample code and here is my code:

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

    function drawChart() {
      var data = new google.visualization.DataTable();
      data.addColumn('string', 'Team');
      data.addColumn('date', 'Season Start Date');
      data.addColumn('date', 'Season End Date');

      data.addRows([
['drwerwer', new Date(2018, 9, 25), new Date(2019, 11, 31)],
['drwerwer', new Date(2018, 9, 25), new Date(2019, 11, 31)],
['WBOX LDA', new Date(2019, 0, 01), new Date(2025, 0, 01)]]);

var options = {
  height: 450,
  timeline: {
    groupByRowLabel: false
  }
};

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

chart.draw(data, options);
}
castro_pereira
  • 301
  • 2
  • 12
  • check [this answer](https://stackoverflow.com/a/48509661/5090771)... – WhiteHat Oct 25 '18 at 15:43
  • That answer is great!!! my problem is that I only want to put a marker for that specific row... each row has it's owns markers... if I can't find a solution maybe I'll do that! – castro_pereira Oct 25 '18 at 16:11

1 Answers1

2

see addMarker in the following working snippet.
which has been modified from the answer found here.
vertical reference line in google timeline visualization

usage, provide date of event, the data table row on which it should appear, and the text to dispaly...

addMarker(new Date(), 3, 'Test Event');

google.charts.load('current', {
  packages:['timeline']
}).then(function () {
  var container = document.getElementById('chart_div');
  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 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, row, label) {
    var baseline;
    var baselineBounds;
    var chartElements;
    var markerLabel;
    var markerLine;
    var markerSpan;
    var svg;
    var timeline;
    var timelineRect;
    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) {
      var rowIndex = 0;
      Array.prototype.forEach.call(chartElements, function(rect) {
        switch (rect.getAttribute('fill')) {
          case 'none':
          case '#ffffff':
          case '#e6e6e6':
            // ignore
            break;

          default:
            console.log(rowIndex, row, (rowIndex === row));
            if (rowIndex === row) {
              timelineRect = rect;
              console.log(timelineRect);
            }
            rowIndex++;
        }
      });
      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) || (timelineRect === 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
    svg.appendChild(markerLabel);
    markerLabel.setAttribute('text-anchor', 'start');
    markerLabel.setAttribute('fill', '#000000');
    markerLabel.setAttribute('y', parseFloat(timelineRect.getAttribute('y')) + parseFloat(markerLabel.getAttribute('font-size')));
    markerLabel.setAttribute('x', (baselineBounds.x + (timelineUnit * markerSpan) + 4));
    markerLabel.textContent = label;

    // add line
    markerLine = timeline.cloneNode(true);
    markerLine.setAttribute('y', timelineRect.getAttribute('y'));
    markerLine.setAttribute('x', (baselineBounds.x + (timelineUnit * markerSpan)));
    markerLine.setAttribute('height', timelineRect.getAttribute('height'));
    markerLine.setAttribute('width', 1);
    markerLine.setAttribute('stroke', 'none');
    markerLine.setAttribute('stroke-width', '0');
    markerLine.setAttribute('fill', '#000000');
    svg.appendChild(markerLine);
  }

  google.visualization.events.addListener(chart, 'ready', function () {
    // add marker for current date
    addMarker(new Date(), 3, 'Test Event');
  });

  window.addEventListener('resize', drawChart, false);
  drawChart();
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
WhiteHat
  • 59,912
  • 7
  • 51
  • 133
  • hope this helps, I'm not sure what's going on with the above "Run code snippet", doesn't seem to want to run, but works fine in [this fiddle](https://jsfiddle.net/wj2kqcr8/) – WhiteHat Oct 25 '18 at 16:43
  • can you please point me in the right direction to understand how the " addMarker(new Date(), 3, 'Test Event');" knows where to add too marker...??? – castro_pereira Nov 11 '18 at 18:47
  • is there a way to identify the row by name or something like that?? As i'm fetching the data from a php and Mysql query i'll not know the array order to identify the slot or line here to add the marker – castro_pereira Nov 11 '18 at 18:57