我有两张折线图,每张都有一张rangeFilter
(就像here一样。)
我想同步两个图表的比例。也就是说,当一个图表更改范围视图时,它将更改vAxis max value
以适应该范围内的最大数据,并且我希望另一个图表将比例更改为相同的值。
如何在实时中获取vAxis.viewWindow.max
?
答案 0 :(得分:4)
如果您只是询问如何确定vAxis.viewWindow.min
(和.max
)值,可以使用以下代码执行此操作:
alert('Min ViewWindow: ' + chart.getOption('vAxis.viewWindow.min') + ', Max: ' + chart.getOption('vAxis.viewWindow.max'));
(给定名为chart
的图表包装器对象。)
每次调整图表时都可以通过向控件包装器添加statechange事件来告诉您最大/最小值:
google.visualization.events.addListener(control, 'statechange', function(e) {
if(e.inProgress == false) {
alert('Min ViewWindow: ' + chart.getOption('vAxis.viewWindow.min') + ', Max: ' + chart.getOption('vAxis.viewWindow.max'));
}
这实际上不会改变任何东西,介意,它只会报告你想要的东西。另一方面,如果您希望图表根据图表中的过滤值更改最大/最小viewWindow值,这是我执行的非常糟糕的:
function drawVisualization() {
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard'));
var control = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'control',
'options': {
// Filter by the date axis.
'filterColumnIndex': 0,
'ui': {
'chartType': 'LineChart',
'chartOptions': {
'chartArea': {'width': '90%'},
'hAxis': {'baselineColor': 'none'}
},
// Display a single series that shows the closing value of the stock.
// Thus, this view has two columns: the date (axis) and the stock value (line series).
'chartView': {
'columns': [0, 3]
},
// 1 day in milliseconds = 24 * 60 * 60 * 1000 = 86,400,000
'minRangeSize': 86400000
}
},
// Initial range: 2012-02-09 to 2012-03-20.
'state': {'range': {'start': new Date(2012, 1, 9), 'end': new Date(2012, 2, 20)}}
});
var chart = new google.visualization.ChartWrapper({
'chartType': 'CandlestickChart',
'containerId': 'chart',
'options': {
// Use the same chart area width as the control for axis alignment.
'chartArea': {'height': '80%', 'width': '90%'},
'hAxis': {'slantedText': false},
'vAxis': {'viewWindow': {'min': 0, 'max': 2000}},
'legend': {'position': 'none'}
},
// Convert the first column from 'date' to 'string'.
'view': {
'columns': [
{
'calc': function(dataTable, rowIndex) {
return dataTable.getFormattedValue(rowIndex, 0);
},
'type': 'string'
}, 1, 2, 3, 4]
}
});
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Stock low');
data.addColumn('number', 'Stock open');
data.addColumn('number', 'Stock close');
data.addColumn('number', 'Stock high');
// Create random stock values, just like it works in reality.
var open, close = 300;
var low, high;
for (var day = 1; day < 121; ++day) {
var change = (Math.sin(day / 2.5 + Math.PI) + Math.sin(day / 3) - Math.cos(day * 0.7)) * 150;
change = change >= 0 ? change + 10 : change - 10;
open = close;
close = Math.max(50, open + change);
low = Math.min(open, close) - (Math.cos(day * 1.7) + 1) * 15;
low = Math.max(0, low);
high = Math.max(open, close) + (Math.cos(day * 1.3) + 1) * 15;
var date = new Date(2012, 0 ,day);
data.addRow([date, Math.round(low), Math.round(open), Math.round(close), Math.round(high)]);
}
// This function determines the maximum and minimum values of the data
function calculateMinMax(data) {
// Get max and min values for the data table
var totalMin = data.getValue(0,1);
var totalMax = data.getValue(0,1);
for (var i = 1;i < data.getNumberOfColumns();i++) {
for (var j = 0;j < data.getNumberOfRows();j++){
if ( data.getValue(j, i) < totalMin ) {
totalMin = data.getValue(j, i);
}
if ( data.getValue(j, i) > totalMax ) {
totalMax = data.getValue(j, i);
}
}
}
// Calculate grid line axes and min/max settings
// Figure out the largest number (positive or negative)
var biggestNumber = Math.max(Math.abs(totalMax),Math.abs(totalMin));
// Round to an exponent of 10 appropriate for the biggest number
var roundingExp = Math.floor(Math.log(biggestNumber) / Math.LN10);
var roundingDec = Math.pow(10,roundingExp);
// Round your max and min to the nearest exponent of 10
var newMax = Math.ceil(totalMax/roundingDec)*roundingDec;
var newMin = Math.floor(totalMin/roundingDec)*roundingDec;
// Determine the range of your values
var range = newMax - newMin;
// Define the number of gridlines (default 5)
var gridlines = 5;
// Determine an appropriate gap between gridlines
var interval = range / (gridlines - 1);
// Round that interval up to the exponent of 10
var newInterval = Math.ceil(interval/roundingDec)*roundingDec;
// Re-round your max and min to the new interval
var finalMax = Math.ceil(totalMax/newInterval)*newInterval;
var finalMin = Math.floor(totalMin/newInterval)*newInterval;
var result = [finalMin, finalMax];
return result;
}
var axisMinMax = calculateMinMax(data);
alert('Min: ' + axisMinMax[0] + ', Max: ' + axisMinMax[1]);
chart.setOption('vAxis.viewWindow.min', axisMinMax[0]);
chart.setOption('vAxis.viewWindow.max', axisMinMax[1]);
dashboard.bind(control, chart);
dashboard.draw(data);
google.visualization.events.addListener(control, 'statechange', function(e) {
if(e.inProgress == false) {
var axisMinMax = calculateMinMax(chart.getDataTable());
chart.setOption('vAxis.viewWindow.min', axisMinMax[0]);
chart.setOption('vAxis.viewWindow.max', axisMinMax[1]);
var filteredData = chart.getDataTable();
chart.draw(filteredData);
}
});
}
答案 1 :(得分:2)
在不了解有关图表的更多细节的情况下,我无法给出非常详细的答案,但假设您有两个图表(chart1
和chart2
)由两个控件驱动({{1}在仪表板中分别有}和control1
,每个图表各有一个数据系列,然后您可以使用这样的内容来同步比例:
control2
如果您有更多数据系列,那么它会变得稍微复杂一些,因为您必须获取两个图表中所有数据系列的范围才能找到它们的最小值/最大值,并设置function syncChartScales () {
var range1 = chart1.getDataTable().getColumnRange(1);
var range2 = chart2.getDataTable().getColumnRange(1);
var minMax = {
min: Math.min(range1.min, range2.min),
max: Math.max(range1.max, range2.max)
}
chart1.setOption('vAxis.minValue', minMax.min);
chart1.setOption('vAxis.maxValue', minMax.max);
chart2.setOption('vAxis.minValue', minMax.min);
chart2.setOption('vAxis.maxValue', minMax.max);
chart1.draw();
chart2.draw();
}
google.visualization.events.addListener(control1, 'statechange', syncChartScales);
google.visualization.events.addListener(control2, 'statechange', syncChartScales);
选项两个图表都显示所有系列的最小值/最大值。
答案 2 :(得分:0)