ChartRangeFilter作为Google时间轴图表的缩放功能,可从具有DataView的专用Google电子表格中读取数据 [英] ChartRangeFilter as a zoom function for a google timeline charts that reads data from a dedicated google spreadsheet with dataview
问题描述
我正在研究一个相当全面的时间表,该时间表可以从使用
I am working on a rather comprehensive timeline that reads data from a dedicated google spreadsheet using dataview.
It does work
// Load the Visualization API and the corechart package.
google.charts.load("current", {packages:["timeline"]});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawGID);
function drawGID() {
var query = new google.visualization.Query(
'https://docs.google.com/spreadsheets/d/1gDsiNSKfPdoutSbtzyt8fExliJpzIWQocEArpAQYD_g/gviz/tq?gid=0&sheet=table');
query.setQuery('select A, B, C, D, E, F, G limit 900 offset 0');
query.send(handleQueryResponse);
} //fine funzione drawGID
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
// Set chart options
var options = {'width':'8600',
'height':'1500'
};// fine options
var data = response.getDataTable();
//da qui proviamo dataview
var view = new google.visualization.DataView(data);
view.setColumns([
{ sourceColumn: 1,
type: 'string',
id: 'materia'},
{ sourceColumn: 2,
type: 'string',
id: 'evento'},
{ sourceColumn: 5,
type: 'date',
id: 'start'},
{ sourceColumn: 6,
type: 'date',
id: 'end'}
]);
// view.setRows([0,1,2,3,4,5,6]);
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
chart.draw(view, options);
} //fine funzione handleQueryResponse
但是我觉得需要缩放功能.
由于无法在Google图表的时间轴(与折线图不同)中通过鼠标选择进行放大和缩小,因此
But I feel the need for a zoom capability.
Since zooming in and out by mouse selection is not possible in google charts' timeline (differently from, say, a line chart) a ChartRangeFilter seems like a good option.
具体答案该网站上的whitehat撰写的内容已经为将ChartRangeFilter应用于时间轴提供了一个很好的工作示例:但是我无法将其应用于我的案例.
A specific answer by whitehat on this site already provides a good working example of a ChartRangeFilter applied to a timeline: but I haven't been able to apply it to my case.
我在这里所做的尝试是在特定电子表格上模拟/a>与示例中使用的数据相同,但没有结果.
What I did here is trying to emulate on a specific spreadsheet the same set of data used in the example, but to no result.
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, 30), 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 query = new google.visualization.Query(
'https://docs.google.com/spreadsheets/d/1WkyxBxKBDntbdqqVmhcwIheRiqsP8A6wKKSzPmryf7I/gviz/tq?gid=0&sheet=table');
query.setQuery('select A, B, C, D, E, F, G limit 4 offset -3');
query.send(handleQueryResponse);
} //fine funzione drawDashboard
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var dataTable = response.getDataTable();
//da qui proviamo dataview
var view = new google.visualization.DataView(dataTable);
view.setColumns([
{ sourceColumn: 1,
type: 'string',
id: 'Row Label'},
{ sourceColumn: 2,
type: 'string',
id: 'Bar Label'},
{ sourceColumn: 3,
type: 'string',
role: 'tooltip',
p: {html:true}},
{ sourceColumn: 4,
type: 'date',
id: 'Start'},
{ sourceColumn: 5,
type: 'date',
id: 'End'},
{ sourceColumn: 6,
type: 'number',
id: 'Scatter'},
{ sourceColumn: 7,
type: 'string',
id: 'Data / Blank'}
]);
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();
});
我想知道的是了解我在哪里做错了,并且可能对所提供代码的主要段落背后的逻辑进行了快速解释. 谢谢
What I would like to know is understand where I do wrong and possibly a quick explanation of the logic behind the main passages of the provided code. thanks
推荐答案
您可以使用类似 Andrea Leofreddi的> svg-pan-zoom 将此功能添加到您的页面.
You can use a library like svg-pan-zoom by Andrea Leofreddi to add this capability to your page.
在将适当的资源添加到页面后,您可以添加一个函数来使用svg图形初始化该库.
After adding the appropriate resource to your page, you can then add a function to initialize this library with your svg graph.
//...
chart.draw(view, options);
//Initialize the code for svgPanZoom
//Limit Paning so chart doesn't go out of viewport:
var beforePan = function(oldPan, newPan) {
var stopHorizontal = false;
var stopVertical = false;
var gutterWidth = 100;
var gutterHeight = 100;
// Computed variables
var sizes = this.getSizes();
var leftLimit = -((sizes.viewBox.x + sizes.viewBox.width) * sizes.realZoom) + gutterWidth;
var rightLimit = sizes.width - gutterWidth - (sizes.viewBox.x * sizes.realZoom)
var topLimit = -((sizes.viewBox.y + sizes.viewBox.height) * sizes.realZoom) + gutterHeight;
var bottomLimit = sizes.height - gutterHeight - (sizes.viewBox.y * sizes.realZoom);
var customPan = {};
customPan.x = Math.max(leftLimit, Math.min(rightLimit, newPan.x));
customPan.y = Math.max(topLimit, Math.min(bottomLimit, newPan.y));
return customPan
}
var chartSvg = document.querySelector("#timeline > div > div:nth-child(1) > div > svg");
var panZoomSvg = svgPanZoom(chartSvg, {
fit: true,
contain: false,
center: true,
beforePan: beforePan
});
//Resized the chart when the window is resized.
window.onresize = function() {
panZoomSvg.resize();
panZoom.fit();
panZoom.center();
};
这篇关于ChartRangeFilter作为Google时间轴图表的缩放功能,可从具有DataView的专用Google电子表格中读取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!