Google 时间线可视化不会在滑块交互中更改系列行高 [英] Google Timeline Visualization doesn't change series row height on slider interaction

查看:16
本文介绍了Google 时间线可视化不会在滑块交互中更改系列行高的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个时间线,其中包含可以并发的数据...

当我将 ChartRangeSlider 移动到不同的时间范围时,一些时间线条会消失或显示,因为在活动的时间范围内没有任何事情发生.

这些是时间线和范围滑块的设置方式.我没有运行任何事件侦听器...

//配置范围滑块var timelineRangeSlider = new google.visualization.ControlWrapper({'controlType': 'ChartRangeFilter','containerId': '时间线过滤器','状态':{'范围':{开始":当前时间,'结束':fourWeek}},'选项':{'过滤器列索引':4,'ui':{'chartType': '散点图','图表选项':{'宽度': '100%','高度':'50','图表区域':{'width': '80%',//确保图表和控件相同,以便轴对齐'高度':'80%'},'h轴':{'基线颜色':'无'}},'图表视图':{列":[4,6]}}}});//配置时间线var 时间线 = 新的 google.visualization.ChartWrapper({'chartType': '时间轴','containerId': '时间线图','选项':{'时间线':{'showBarLabels': 假},'宽度': '100%','高度':'325','工具提示':{'isHtml': 真},'图表区域':{'width': '80%',//确保图表和控件相同,以便轴对齐'高度':'80%'},},'看法':{列":[0,1,2,3,4,5]}});

如何阻止这种情况的发生,并使四个单独的行(每个系列一个)中的每一行都有一个静态高度,当我与范围滑块交互时,该高度不会改变?

解决方案

无论过滤器设置如何,都显示相同的行数,
用空白"行替换过滤器删除的行,
这样做需要一些操作

如果您使用仪表板来绑定图表和过滤器,
单独绘制每个可能会更容易
监听过滤器上的 'statechange' 事件,
知道什么时候重新绘制图表

使用数据视图排除过滤器隐藏的行,
在它们的位置添加空白行
使用时间轴上的 colors 选项将空白行设置为 'transparent'
还对这些行使用空白工具提示

请参阅以下工作片段,了解如何完成此操作的示例...

google.charts.load('current', {包:['控制','时间线']}).then(函数(){var dataTable = google.visualization.arrayToDataTable([['行标签', '条形标签', {role: 'tooltip', type: 'string', p: {html: true}}, 'Start', 'End', 'Scatter', 'Data/Blank'],['A', 'Series 0', null, new Date(2018, 1, 1), new Date(2018, 1, 28), 1, 'data'],['B', 'Series 1', null, new Date(2018, 4, 1), new Date(2018, 4, 31), 1, 'data'],['C', 'Series 2', null, new Date(2018, 7, 1), new Date(2018, 7, 31), 1, 'data'],['D', 'Series 3', null, new Date(2018, 10, 1), new Date(2018, 10, 30), 1, 'data']]);var blankTooltip = '<div class="hidden"></div>';var colorPallette = ['青色','洋红色','石灰','黄色'];var 日期范围 = {开始:dataTable.getColumnRange(3),结束:dataTable.getColumnRange(4)};//配置范围滑块var timelineRangeSlider = new google.visualization.ControlWrapper({controlType: 'ChartRangeFilter',containerId: '时间线过滤器',数据表:数据表,状态: {范围: {开始:dateRange.start.min,结束: dateRange.end.max}},选项: {过滤列索引:3,用户界面:{图表类型:'散点图',图表选项:{宽度: '100%',高度:'50',图表区域:{宽度: '80%',高度:'80%'},h轴:{基线颜色:'无'}},图表视图:{列:[3,5]}}}});google.visualization.events.addListener(timelineRangeSlider, 'statechange', function (props) {//过滤状态var state = timelineRangeSlider.getState();//等待状态改变完成如果 (!props.inProgress) {//删除之前添加的空白行var blankRows = dataTable.getFilteredRows([{列:6,值:'空白'}]);var i = blankRows.length;当我 - ) {dataTable.removeRow(blankRows[i]);}//为不可见行添加空白行var blankRows = [];var timelineColors = [];var visibleRows = dataTable.getFilteredRows([{列:3,minValue: state.range.start}, {列:4,最大值:state.range.end}]);for (var i = 0; i < dataTable.getNumberOfRows(); i++) {if (visibleRows.indexOf(i) === -1) {blankRows.push([数据表.getValue(i, 0),数据表.getValue(i, 1),空白工具提示,state.range.start,state.range.start,1、'空白的']);timelineColors.push('透明');} 别的 {timelineColors.push(colorPallette[i]);}}//构建时间线视图行var lastRowIndex = dataTable.addRows(blankRows);var i = blankRows.length;当我 - ) {visibleRows.push((lastRowIndex - i));}//重新配置时间线var timelineView = new google.visualization.DataView(dataTable);timelineView.setRows(visibleRows);时间线视图 = 时间线视图.toDataTable();timelineView.sort([{column: 0}]);时间线.setDataTable(timelineView);时间线.setOption('颜色',时间线颜色);时间线.绘制();}});timelineRangeSlider.draw();//配置时间线var 时间线 = 新的 google.visualization.ChartWrapper({chartType: '时间线',containerId: '时间线图表',数据表:数据表,选项: {颜色:colorPallette,时间线: {showBarLabels: 假},宽度: '100%',高度:'325',工具提示:{isHtml: 真},图表区域:{宽度: '80%',高度:'80%'}},看法: {列:[0,1,2,3,4]}});时间线.绘制();});

.hidden {显示:无;可见性:隐藏;}

<script src="https://www.gstatic.com/charts/loader.js"></script><div id="dashboard_div"><div id="timeline-filter"></div><div id="时间线图表"></div>

So I've got a timeline with data in it that can be concurrent...

When I move the ChartRangeSlider to a different timeframe, some of the timeline bars will either disappear or show because there is nothing happening in the timeframe that is active.

These is how the timeline and the range slider are set up. I don't have any event listeners running...

       // Configure range slider
        var timelineRangeSlider = new google.visualization.ControlWrapper({
            'controlType': 'ChartRangeFilter',
            'containerId': 'timeline-filter',
            'state': 
            {
                'range': 
                {
                    'start': currentTime,
                    'end':   fourWeek                   
                }
            },
            'options': 
            {
                'filterColumnIndex': 4,
                'ui': 
                {
                    'chartType': 'ScatterChart',
                    'chartOptions': 
                    {
                        'width': '100%',
                        'height': '50',
                        'chartArea': 
                        {
                            'width': '80%', // make sure this is the same for the chart and control so the axes align right
                            'height': '80%'
                        },
                        'hAxis': 
                        {
                            'baselineColor': 'none'
                        }
                    },
                    'chartView': 
                    {
                        'columns': [4,6]
                    }
                }
            }
        });

        // Configure timeline
        var timeline = new google.visualization.ChartWrapper({
            'chartType': 'Timeline',
            'containerId': 'timeline-chart',
            'options': 
            {
                'timeline': 
                {
                    'showBarLabels': false
                },
                'width': '100%',
                'height': '325',
                'tooltip': 
                {
                    'isHtml': true
                },
                'chartArea': 
                {
                    'width': '80%', // make sure this is the same for the chart and control so the axes align right
                    'height': '80%'
                }, 
            },
            'view': 
            {
                'columns': [0,1,2,3,4,5]
            }           
        });

How can I stop this from happening, and have each of the four separate rows (one for each series) have a static height that won't change when I interact with the range slider?

解决方案

to display the same number of rows, regardless of the filter settings,
replace the rows removed by the filter with "blank" rows,
doing so will require some manipulation

if you're using a dashboard to bind the chart and filter,
it will probably be easier to draw each independently
listen for the 'statechange' event on the filter,
to know when to re-draw the chart

use a data view to exclude the rows hidden by the filter,
add blank rows in their place
use the colors option on the timeline to set blank rows to 'transparent'
also use a blank tooltip for these rows

see following working snippet, for an example of how this could be accomplished...

google.charts.load('current', {
  packages: ['controls', 'timeline']
}).then(function () {
  var dataTable = google.visualization.arrayToDataTable([
    ['Row Label', 'Bar Label', {role: 'tooltip', type: 'string', p: {html: true}}, 'Start', 'End', 'Scatter', 'Data / Blank'],
    ['A', 'Series 0', null, new Date(2018, 1, 1), new Date(2018, 1, 28), 1, 'data'],
    ['B', 'Series 1', null, new Date(2018, 4, 1), new Date(2018, 4, 31), 1, 'data'],
    ['C', 'Series 2', null, new Date(2018, 7, 1), new Date(2018, 7, 31), 1, 'data'],
    ['D', 'Series 3', null, new Date(2018, 10, 1), new Date(2018, 10, 30), 1, 'data']
  ]);

  var blankTooltip = '<div class="hidden"></div>';
  var colorPallette = ['cyan', 'magenta', 'lime', 'yellow'];
  var dateRange = {
    start: dataTable.getColumnRange(3),
    end: dataTable.getColumnRange(4)
  };

  // Configure range slider
  var timelineRangeSlider = new google.visualization.ControlWrapper({
    controlType: 'ChartRangeFilter',
    containerId: 'timeline-filter',

    dataTable: dataTable,

    state: {
      range: {
        start: dateRange.start.min,
        end: dateRange.end.max
      }
    },
    options: {
      filterColumnIndex: 3,
      ui: {
        chartType: 'ScatterChart',
        chartOptions: {
          width: '100%',
          height: '50',
          chartArea: {
            width: '80%',
            height: '80%'
          },
          hAxis: {
            baselineColor: 'none'
          }
        },
        chartView: {
          columns: [3,5]
        }
      }
    }
  });

  google.visualization.events.addListener(timelineRangeSlider, 'statechange', function (props) {
    // filter state
    var state = timelineRangeSlider.getState();

    // wait until statechange has finished
    if (!props.inProgress) {
      // delete previously added blank rows
      var blankRows = dataTable.getFilteredRows([{
        column: 6,
        value: 'blank'
      }]);
      var i = blankRows.length;
      while (i--) {
        dataTable.removeRow(blankRows[i]);
      }

      // add blank rows for non-visible rows
      var blankRows = [];
      var timelineColors = [];
      var visibleRows = dataTable.getFilteredRows([{
        column: 3,
        minValue: state.range.start
      }, {
        column: 4,
        maxValue: state.range.end
      }]);
      for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
        if (visibleRows.indexOf(i) === -1) {
          blankRows.push([
            dataTable.getValue(i, 0),
            dataTable.getValue(i, 1),
            blankTooltip,
            state.range.start,
            state.range.start,
            1,
            'blank'
          ]);
          timelineColors.push('transparent');
        } else {
          timelineColors.push(colorPallette[i]);
        }
      }

      // build timeline view rows
      var lastRowIndex = dataTable.addRows(blankRows);
      var i = blankRows.length;
      while (i--) {
        visibleRows.push((lastRowIndex - i));
      }

      // re-config timeline
      var timelineView = new google.visualization.DataView(dataTable);
      timelineView.setRows(visibleRows);
      timelineView = timelineView.toDataTable();
      timelineView.sort([{column: 0}]);
      timeline.setDataTable(timelineView);
      timeline.setOption('colors', timelineColors);
      timeline.draw();
    }
  });

  timelineRangeSlider.draw();

  // Configure timeline
  var timeline = new google.visualization.ChartWrapper({
    chartType: 'Timeline',
    containerId: 'timeline-chart',

    dataTable: dataTable,

    options: {
      colors: colorPallette,

      timeline: {
        showBarLabels: false
      },
      width: '100%',
      height: '325',
      tooltip: {
        isHtml: true
      },
      chartArea: {
        width: '80%',
        height: '80%'
      }
    },
    view: {
      columns: [0,1,2,3,4]
    }
  });
  timeline.draw();
});

.hidden {
  display: none;
  visibility: hidden;
}

<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard_div">
  <div id="timeline-filter"></div>
  <div id="timeline-chart"></div>
</div>

这篇关于Google 时间线可视化不会在滑块交互中更改系列行高的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆