问题
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?
回答1:
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>
来源:https://stackoverflow.com/questions/49306638/google-timeline-visualization-dont-change-series-row-height-on-slider-interacti