Вертикальная эталонная линия в визуализации временной шкалы google

Привет, я использую google visualization api, чтобы нарисовать график на моем веб-сайте. Он работает отлично. Но есть одна мелочь, которая меня беспокоит. Я хочу отобразить вертикальную линию в области диаграммы для представления текущей даты. Пожалуйста, дайте мне знать любые решения.

Мой код:

<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['timeline']}]}"></script>

<script type="text/javascript">
google.setOnLoadCallback(drawChart);
function drawChart() {

  var container = document.getElementById('example3.1');
  var chart = new google.visualization.Timeline(container);

  var dataTable = new google.visualization.DataTable();
  dataTable.addColumn({ type: 'string', id: 'Position' });
  dataTable.addColumn({ type: 'string', id: 'Name' });
  dataTable.addColumn({ type: 'date', id: 'Start' });
  dataTable.addColumn({ type: 'date', id: 'End' });
  dataTable.addRows([
    [ 'President',          'George Washington', new Date(2014, 3, 29), new Date(2014, 4, 3)],
    [ 'President',          'John Adams',        new Date(2014, 2, 3),  new Date(2014, 3, 3)],
    [ 'President',          'Thomas Jefferson',  new Date(2014, 2, 3),  new Date(2014, 5, 3)],
    [ 'Vice President',     'John Adams',        new Date(2014, 3, 20), new Date(2014, 5, 3)],
    [ 'Vice President',     'Thomas Jefferson',  new Date(2014, 2, 3),  new Date(2014, 6, 3)],
    [ 'Vice President',     'Aaron Burr',        new Date(2014, 2, 3),  new Date(2014, 2, 3)],
    [ 'Vice President',     'George Clinton',    new Date(2014, 2, 3),  new Date(2014, 2, 19)],

    ]);

  chart.draw(dataTable);
}

</script>

<div id="example3.1" style="width: 1000px; height: 200px;"></div>

Предполагаемый результат: зеленая линия представляет текущую дату enter image description here

Edit:

Если это невозможно, предложите любой другой API, который может это сделать.

Ответ 1

Создайте первую задачу для представления текущей даты:

      dataTable.addRows([
['', 'Hoy', new Date(2014,9,2), new Date(2014,9,2) ],

Создайте функцию с jQuery, чтобы сделать эту задачу более длинной:

function MarcarHoy (div, filas){
  $('#'+div+' text:contains("Hoy")').css('font-size','11px').attr('fill','#A6373C').prev().first().attr('height',filas*41+'px').attr('width','1px').attr('y','0');
  }

Вызвать функцию:

    chart.draw(dataTable, options);
  MarcarHoy('example1',23);
  google.visualization.events.addListener(chart, 'onmouseover', function(obj) {
    MarcarHoy('example1');
    });
}

Результат:

enter image description here

Источник: Viviendo en la Era de la Web 2.0

Ответ 2

В сентябре 2016 года я нашел видео о добавлении вертикальной линии на график. https://www.youtube.com/watch?v=sG9tB04aaqE&t=416s

Он также включил пример в видео (https://jsfiddle.net/k5se146d/1/)

Но красная линия может исчезнуть при срабатывании события наведения мыши. Я попытался добавить следующую строку в функцию. Кажется, что взломать график, но я не нашел результата в Google. Надеюсь, что это может помочь кому-нибудь нужно.

function nowLine(div){

//get the height of the timeline div
    var height;
  $('#' + div + ' rect').each(function(index){
    var x = parseFloat($(this).attr('x'));
    var y = parseFloat($(this).attr('y'));

    if(x == 0 && y == 0) {height = parseFloat($(this).attr('height'))}
  })

    var nowWord = $('#' + div + ' text:contains("Now")');

  nowWord.prev().first().attr('height', height + 'px').attr('width', '1px').attr('y', '0');
// add this line to remove the display:none style on the vertical line
        $('#' + div + '  text:contains("Now")').each(function(idx, value) {
            if (idx == 0) {
                $(value).parent().find("rect").first().removeAttr("style");
            } else if (idx == 1) {
                $(value).parent().find("rect").first().attr("style", "display:none;");
            }

        });
}

Ответ 3

чтобы вычислить размещение маркера даты,
найти даты начала и окончания временной шкалы
использовать метод таблицы данных → getColumnRange()

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

затем разделите ширину диаграммы на разницу в миллисекундах
умножьте результат на разницу даты начала и даты маркера

первый найденный элемент 'path' - это строка, разделяющая метки строк и временную шкалу,
это можно использовать для смещения ширины ярлыков строк

см. следующий рабочий фрагмент...

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();
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>

Ответ 4

Используйте столбец ролей "аннотации" в столбце "домен" (дата). В параметрах диаграммы установите для параметра annotation.<annotation column index>.style значение 'line':

function drawVisualization() {
    var data = google.visualization.arrayToDataTable([
        ['Date', {role: 'annotation'}, 'Value'],
        [new Date(2014, 1, 10), null, 5],
        [new Date(2014, 1, 11), null, 4],
        [new Date(2014, 1, 12), null, 3],
        [new Date(2014, 1, 13), null, 7],
        [new Date(2014, 1, 14), null, 5],
        [new Date(2014, 1, 15), null, 6],
        [new Date(2014, 1, 16), null, 9],
        [new Date(2014, 1, 17), null, 2],
        [new Date(2014, 1, 18), null, 2],
        [new Date(2014, 1, 19), 'Today', 4],
        [new Date(2014, 1, 20), null, 6],
        [new Date(2014, 1, 22), null, 5],
        [new Date(2014, 1, 23), null, 8],
        [new Date(2014, 1, 24), null, 8]
    ]);

    var chart = new google.visualization.LineChart(document.querySelector('#chart_div'));
    chart.draw(data, {
        width: 500,
        height: 400,
        annotation: {
            1: {
                style: 'line'
            }
        }
    });
}
google.load('visualization', '1', {packages:['corechart'], callback: drawVisualization});

см. пример здесь: http://jsfiddle.net/asgallant/r37uf/

Ответ 5

У меня была такая же проблема, я не мог найти что-либо в Интернете (хотя это может существовать), и я как бы решил проблему, наложив плавающий div в виде вертикальной линии, которая расположена относительно следующим образом:

Ширина диаграммы временной шкалы (минус ширина метки строки) связана с разницей между датами min-max, отображаемыми на диаграмме. Предполагая, что сегодня дата будет где-то между датами min-max, тогда отношение (today - min date)/(max date - min date) равно отношению (current date line position)/(chart width - label width). Ловушка заключается в том, что, если вы не можете каким-либо образом установить ширину метки на определенный номер (который вы затем можете использовать для расчета эффективной ширины диаграммы), вы получите "сдвинутую" сегодняшнюю строку.

Я не мог найти ничего о том, как установить ширину ярлыка строки (любая помощь по этому поводу очень ценится), поэтому моя сегодняшняя позиция линии является приблизительной... (но непротиворечивой, в то время как ширина метки остается неизменной)

Надеюсь, это поможет, Николас

Ответ 6

У кого-нибудь есть идея, как заставить это работать с инструментальными панелями? Я использую фильтры панели мониторинга, чтобы контролировать, какие строки данных отображаются на временной шкале. Я попробовал оба метода, показанные на этом сайте, и ни один из них не работает. Первая версия, добавленная строка фильтруется и исчезает. Другая версия, линия попадает в неправильный момент времени, когда я фильтрую контент.

есть идеи как это сделать? Я действительно надеюсь, что Google может просто добавить эту функцию.