【问题标题】:vertical reference line in google timeline visualization谷歌时间线可视化中的垂直参考线
【发布时间】:2014-02-19 06:37:26
【问题描述】:

您好,我正在使用谷歌可视化 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>

预期结果:绿线代表当前日期

编辑:

如果这不可行,请建议任何其他可以实现此目的的 API。

【问题讨论】:

  • 感谢大家的宝贵意见,即使在 2 年后也是如此。从长远来看,这将帮助很多人。

标签: google-api google-visualization


【解决方案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');
    });
}

结果:

来源:Viviendo en la Era de la Web 2.0

【讨论】:

  • 我只需要稍作调整,正如他的博文所述。
  • 简单的 CSS 等价物:rect[fill="#A6373C"]{ height: 100%; }
【解决方案2】:

计算日期标记的位置,
查找时间线的开始和结束日期
使用数据表法 --> getColumnRange()

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

然后将图表的宽度除以毫秒差
将结果乘以开始日期和标记日期的差

找到的第一个 'path' 元素是分隔行标签和时间线的线,
这可以用来偏移行标签的宽度

请参阅以下工作 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();  // 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>

【讨论】:

    【解决方案3】:

    我在 2016 年 9 月发现了一个关于在时间线图表中添加垂直线的视频。 https://www.youtube.com/watch?v=sG9tB04aaqE&t=416s

    它还包括视频中的示例 (https://jsfiddle.net/k5se146d/1/)

    但是当鼠标悬停事件触发时,红线可能会消失。我试图在函数中添加以下行。这似乎是对时间线图的黑客攻击,但我在谷歌上没有找到任何结果。希望它可以帮助任何需要的人。

    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;");
                }
    
            });
    }
    

    【讨论】:

      【解决方案4】:

      在域(日期)列上使用“注释”角色列。在图表选项中,将annotation.&lt;annotation column index&gt;.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/

      【讨论】:

      • 感谢您的回复。其实我想要的正是你所展示的。除了,我希望它在我包含的图表中。请告诉我如何在我包含的这个时间线图中实现相同的结果。谢谢。
      • 时间轴图表尚不支持注释,因此您不能这样做,抱歉。
      • OP一直在专门要求时间表,所以我不明白这是如何回答这个问题的。
      【解决方案5】:

      我自己也有同样的问题,在网上找不到任何东西(尽管它可能确实存在),我通过覆盖垂直线形状的浮动 div 来解决这个问题,该垂直线的相对位置如下:

      时间线图表的宽度(减去行标签宽度)与图表上显示的最小-最大日期之间的差异有关。假设今天的日期介于最小-最大日期之间,则比率(today - min date)/(max date - min date) 等于比率(current date line position)/(chart width - label width)。 问题是,除非您可以以某种方式将标签宽度设置为特定数字(然后您可以使用它来计算有效图表宽度),否则您最终会得到一条“偏移”的今天线。

      我找不到任何关于如何设置行标签宽度的信息(非常感谢任何帮助)所以我今天的行位置是近似的......(但在标签宽度保持不变的情况下保持一致)

      希望这会有所帮助, 尼古拉斯

      【讨论】:

      • 感谢 Nicholas 提供的解决方案。我会尝试一下,稍后再回来。对于您的问题,如果标签不是很重要,您可以使用“showRowLabels”选项将其隐藏。
      • 顺便说一句,您是如何设置最小和最大日期的?我尝试使用 hAxis.viewWindow.minhAxis.viewWindow.max 。它们似乎在这些图表中不起作用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多