为 Google 数字范围过滤器的下限设置最大值
Set Maximum Value for Lower Range of Google Number Range Filter
我有一个交互式 Google 折线图,它显示了用户 select 编辑的两个不同年份之间的历史海平面数据。该图表还显示了 selected 期间的线性和多项式趋势线。可用的历史数据范围为 1904 年至 2018 年(含)。但是,用户可以 select 从 1904 年到 2120 年(含)的任何开始年份和结束年份。如果 select 编辑了 2018 年之后的结束年份,图表会显示截至 2018 年的可用历史数据,然后扩展两条趋势线以显示截至用户 select 编辑的预测海平面。
这似乎工作正常,直到 selected 年份都超过 2018 年,即 2020 年和 2056 年抛出错误时 ("Cannot read property 'top' of null"),因为它无法从期间不包含观测数据。目前,我正在使用一个错误处理程序来解决这个问题,该错误处理程序会在发生这种情况时启动并显示一条警告消息,告知用户他们不能 select 大于 2018 年的开始年份。然后页面会重新加载并显示数字range filter 默认回到 1904 年和 2018 年的开始和结束年份,这并不理想。我想做的是限制用户 select 开始年份不超过 2018 年,但数字范围过滤器控件中似乎没有 option/setting 来执行此操作.有什么想法吗?
我的代码:
<html>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {
packages: ['controls']
}).then(initialize);
function initialize() {
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1vn1iuhsG33XzFrC4QwkTdUnxOGdcPQOj-cuaEZeX-eA/edit#gid=0');
query.send(drawDashboard);
}
function drawDashboard(response) {
var data = response.getDataTable();
//Asign units of 'mm' to data.
var formatMS = new google.visualization.NumberFormat({
pattern: '# mm'
});
// format data into mm.
for (var colIndex = 1; colIndex < data.getNumberOfColumns(); colIndex++) {
formatMS.format(data, colIndex);
}
var YearPicker = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'filter_div',
options: {
maxValue:2120,
filterColumnLabel: 'Year',
ui: {
cssClass: 'filter-date',
format: {pattern: '0000'},
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
},
"state": {"lowValue": 1904, "highValue": 2018},
});
google.visualization.events.addListener(YearPicker, 'statechange', filterChange);
var MSLChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
dataTable: data,
options: {
fontSize: '14',
title: 'Timbucktoo Annual Mean Sea Level Summary',
hAxis: {title: 'Year', format: '0000'},
vAxis: {title: 'Height above Chart Datum (mm)', format:'###0'},
height: 600,
chartArea: {height: '81%', width: '85%', left: 100},
legend: {position: 'in', alignment: 'end', textStyle: {fontSize: 13}},
colors: ['blue'],
trendlines: {
0: {
type: 'polynomial',
degree: 2,
color: 'green',
visibleInLegend: true,
},
1: {
type: 'linear',
color: 'black',
visibleInLegend: true,
},
},
series: {
0: { visibleInLegend: true },
1: { visibleInLegend: false },
},
},
view: {columns: [0,1,2]}
});
google.visualization.events.addOneTimeListener(MSLChart, 'ready', filterChange);
function filterChange() {
// get chart layout
var chartLayout = MSLChart.getChart().getChartLayoutInterface();
// get y-axis bounds
var yAxisCoords = {min: null, max: null};
var lineIndex = 0;
var boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
try {
do {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
} while (boundsLine !== null);
}
catch (error) {alert("Please choose a start year less than or equal to 2018");
window.location.reload(false);
exit;
}
var state = YearPicker.getState();
var EndYear = state.highValue;
// re-draw chart
MSLChart.setOption('vAxis.viewWindow.max', chartLayout.getVAxisValue(yAxisCoords.max));
MSLChart.setOption('vAxis.viewWindow.min', chartLayout.getVAxisValue(yAxisCoords.min));
MSLChart.setOption('hAxis.viewWindow.max', EndYear);
MSLChart.draw();
google.visualization.events.addOneTimeListener(MSLChart.getChart(), 'ready', filterChange);
}
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div')
).bind(YearPicker, MSLChart).draw(data);
}
</script>
<div id="dashboard_div">
<div id="chart_div"></div>
<div id="filter_div"></div>
</div>
</html>
为了防止出错,在filterChange
函数中,
更改 do...while
语句,
do {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
} while (boundsLine !== null);
只是一个 while
语句
while (boundsLine !== null) {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
};
do...while
假定总会至少绘制一条线。
我们无法阻止用户选择超过 2018 年的开始年份,
但我们可以在他们这样做时立即重新设置开始年份。
google.visualization.events.addListener(YearPicker, 'statechange', function () {
var state = YearPicker.getState();
state.lowValue = Math.min(2018, state.lowValue);
YearPicker.setState({
lowValue: state.lowValue,
highValue: state.highValue
});
YearPicker.draw();
filterChange();
});
请参阅以下工作片段...
google.charts.load('current', {
packages: ['controls']
}).then(initialize);
function initialize() {
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1vn1iuhsG33XzFrC4QwkTdUnxOGdcPQOj-cuaEZeX-eA/edit#gid=0');
query.send(drawDashboard);
}
function drawDashboard(response) {
var data = response.getDataTable();
//Asign units of 'mm' to data.
var formatMS = new google.visualization.NumberFormat({
pattern: '# mm'
});
// format data into mm.
for (var colIndex = 1; colIndex < data.getNumberOfColumns(); colIndex++) {
formatMS.format(data, colIndex);
}
var YearPicker = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'filter_div',
options: {
maxValue: 2120,
filterColumnLabel: 'Year',
ui: {
cssClass: 'filter-date',
format: {pattern: '0000'},
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
},
state: {lowValue: 1904, highValue: 2018},
});
google.visualization.events.addListener(YearPicker, 'statechange', function () {
var state = YearPicker.getState();
state.lowValue = Math.min(2018, state.lowValue);
YearPicker.setState({
lowValue: state.lowValue,
highValue: state.highValue
});
YearPicker.draw();
filterChange();
});
var MSLChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
dataTable: data,
options: {
fontSize: '14',
title: 'Timbucktoo Annual Mean Sea Level Summary',
hAxis: {title: 'Year', format: '0000'},
vAxis: {title: 'Height above Chart Datum (mm)', format:'###0'},
height: 600,
chartArea: {height: '81%', width: '85%', left: 100},
legend: {position: 'in', alignment: 'end', textStyle: {fontSize: 13}},
colors: ['blue'],
trendlines: {
0: {
type: 'polynomial',
degree: 2,
color: 'green',
visibleInLegend: true,
},
1: {
type: 'linear',
color: 'black',
visibleInLegend: true,
},
},
series: {
0: { visibleInLegend: true },
1: { visibleInLegend: false },
},
},
view: {columns: [0,1,2]}
});
google.visualization.events.addOneTimeListener(MSLChart, 'ready', filterChange);
function filterChange() {
// get chart layout
var chartLayout = MSLChart.getChart().getChartLayoutInterface();
// get y-axis bounds
var yAxisCoords = {min: null, max: null};
var lineIndex = 0;
var boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
while (boundsLine !== null) {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
};
var state = YearPicker.getState();
var EndYear = state.highValue;
// re-draw chart
MSLChart.setOption('vAxis.viewWindow.max', chartLayout.getVAxisValue(yAxisCoords.max));
MSLChart.setOption('vAxis.viewWindow.min', chartLayout.getVAxisValue(yAxisCoords.min));
MSLChart.setOption('hAxis.viewWindow.max', EndYear);
MSLChart.draw();
google.visualization.events.addOneTimeListener(MSLChart.getChart(), 'ready', filterChange);
}
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div')
).bind(YearPicker, MSLChart).draw(data);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard_div">
<div id="chart_div"></div>
<div id="filter_div"></div>
</div>
编辑
没有修改趋势线工具提示的选项,
但我们可以在 'onmouseover'
事件期间手动更改它。
首先,我们需要使用html工具提示,它们默认是svg。
添加此选项...
tooltip: {
isHtml: true
},
然后将 'onmouseover'
事件添加到图表中,
我们可以在包装器的 'ready'
事件中执行此操作。
google.visualization.events.addOneTimeListener(MSLChart, 'ready', function () {
google.visualization.events.addListener(MSLChart.getChart(), 'onmouseover', function (props) {
// ensure trendline tooltip
if ((props.column === 0) && (props.row !== null)) {
// get year value
var year = MSLChart.getDataTable().getValue(props.row, 0);
// get tooltip, remove width
var tooltip = MSLChart.getChart().getContainer().getElementsByTagName('ul');
tooltip[0].parentNode.style.width = null;
// get tooltip labels
var tooltipLabels = MSLChart.getChart().getContainer().getElementsByTagName('span');
// set year
tooltipLabels[0].innerHTML = year;
// remove formula
tooltipLabels[1].innerHTML = '';
// set height value
var height = parseFloat(tooltipLabels[2].innerHTML.split(' ')[2].replace(',', '')).toFixed(0);
tooltipLabels[2].innerHTML = height + ' mm';
}
});
});
请参阅以下工作片段...
google.charts.load('current', {
packages: ['controls']
}).then(initialize);
function initialize() {
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1vn1iuhsG33XzFrC4QwkTdUnxOGdcPQOj-cuaEZeX-eA/edit#gid=0');
query.send(drawDashboard);
}
function drawDashboard(response) {
var data = response.getDataTable();
//Asign units of 'mm' to data.
var formatMS = new google.visualization.NumberFormat({
pattern: '# mm'
});
// format data into mm.
for (var colIndex = 1; colIndex < data.getNumberOfColumns(); colIndex++) {
formatMS.format(data, colIndex);
}
var YearPicker = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'filter_div',
options: {
maxValue: 2120,
filterColumnLabel: 'Year',
ui: {
cssClass: 'filter-date',
format: {pattern: '0000'},
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
},
state: {lowValue: 1904, highValue: 2018},
});
google.visualization.events.addListener(YearPicker, 'statechange', function () {
var state = YearPicker.getState();
state.lowValue = Math.min(2018, state.lowValue);
YearPicker.setState({
lowValue: state.lowValue,
highValue: state.highValue
});
YearPicker.draw();
filterChange();
});
var MSLChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
dataTable: data,
options: {
fontSize: '14',
title: 'Timbucktoo Annual Mean Sea Level Summary',
hAxis: {title: 'Year', format: '0000'},
vAxis: {title: 'Height above Chart Datum (mm)', format:'###0'},
height: 600,
chartArea: {height: '81%', width: '85%', left: 100},
legend: {position: 'in', alignment: 'end', textStyle: {fontSize: 13}},
colors: ['blue'],
tooltip: {
isHtml: true
},
trendlines: {
0: {
type: 'polynomial',
degree: 2,
color: 'green',
visibleInLegend: true,
},
1: {
type: 'linear',
color: 'black',
visibleInLegend: true,
},
},
series: {
0: { visibleInLegend: true },
1: { visibleInLegend: false },
},
},
view: {columns: [0,1,2]}
});
google.visualization.events.addOneTimeListener(MSLChart, 'ready', filterChange);
function filterChange() {
// get chart layout
var chartLayout = MSLChart.getChart().getChartLayoutInterface();
// get y-axis bounds
var yAxisCoords = {min: null, max: null};
var lineIndex = 0;
var boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
while (boundsLine !== null) {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
};
var state = YearPicker.getState();
var EndYear = state.highValue;
// re-draw chart
MSLChart.setOption('vAxis.viewWindow.max', chartLayout.getVAxisValue(yAxisCoords.max));
MSLChart.setOption('vAxis.viewWindow.min', chartLayout.getVAxisValue(yAxisCoords.min));
MSLChart.setOption('hAxis.viewWindow.max', EndYear);
MSLChart.draw();
google.visualization.events.addOneTimeListener(MSLChart.getChart(), 'ready', filterChange);
}
google.visualization.events.addOneTimeListener(MSLChart, 'ready', function () {
google.visualization.events.addListener(MSLChart.getChart(), 'onmouseover', function (props) {
// ensure trendline tooltip
if ((props.column === 0) && (props.row !== null)) {
var year = MSLChart.getDataTable().getValue(props.row, 0);
// get tooltip, remove width
var tooltip = MSLChart.getChart().getContainer().getElementsByTagName('ul');
tooltip[0].parentNode.style.width = null;
// get tooltip labels
var tooltipLabels = MSLChart.getChart().getContainer().getElementsByTagName('span');
// set year
tooltipLabels[0].innerHTML = year;
// remove formula
tooltipLabels[1].innerHTML = '';
// set height
var height = parseFloat(tooltipLabels[2].innerHTML.split(' ')[2].replace(',', '')).toFixed(0);
tooltipLabels[2].innerHTML = height + ' mm';
}
});
});
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div')
).bind(YearPicker, MSLChart).draw(data);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard_div">
<div id="chart_div"></div>
<div id="filter_div"></div>
</div>
我有一个交互式 Google 折线图,它显示了用户 select 编辑的两个不同年份之间的历史海平面数据。该图表还显示了 selected 期间的线性和多项式趋势线。可用的历史数据范围为 1904 年至 2018 年(含)。但是,用户可以 select 从 1904 年到 2120 年(含)的任何开始年份和结束年份。如果 select 编辑了 2018 年之后的结束年份,图表会显示截至 2018 年的可用历史数据,然后扩展两条趋势线以显示截至用户 select 编辑的预测海平面。
这似乎工作正常,直到 selected 年份都超过 2018 年,即 2020 年和 2056 年抛出错误时 ("Cannot read property 'top' of null"),因为它无法从期间不包含观测数据。目前,我正在使用一个错误处理程序来解决这个问题,该错误处理程序会在发生这种情况时启动并显示一条警告消息,告知用户他们不能 select 大于 2018 年的开始年份。然后页面会重新加载并显示数字range filter 默认回到 1904 年和 2018 年的开始和结束年份,这并不理想。我想做的是限制用户 select 开始年份不超过 2018 年,但数字范围过滤器控件中似乎没有 option/setting 来执行此操作.有什么想法吗?
我的代码:
<html>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {
packages: ['controls']
}).then(initialize);
function initialize() {
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1vn1iuhsG33XzFrC4QwkTdUnxOGdcPQOj-cuaEZeX-eA/edit#gid=0');
query.send(drawDashboard);
}
function drawDashboard(response) {
var data = response.getDataTable();
//Asign units of 'mm' to data.
var formatMS = new google.visualization.NumberFormat({
pattern: '# mm'
});
// format data into mm.
for (var colIndex = 1; colIndex < data.getNumberOfColumns(); colIndex++) {
formatMS.format(data, colIndex);
}
var YearPicker = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'filter_div',
options: {
maxValue:2120,
filterColumnLabel: 'Year',
ui: {
cssClass: 'filter-date',
format: {pattern: '0000'},
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
},
"state": {"lowValue": 1904, "highValue": 2018},
});
google.visualization.events.addListener(YearPicker, 'statechange', filterChange);
var MSLChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
dataTable: data,
options: {
fontSize: '14',
title: 'Timbucktoo Annual Mean Sea Level Summary',
hAxis: {title: 'Year', format: '0000'},
vAxis: {title: 'Height above Chart Datum (mm)', format:'###0'},
height: 600,
chartArea: {height: '81%', width: '85%', left: 100},
legend: {position: 'in', alignment: 'end', textStyle: {fontSize: 13}},
colors: ['blue'],
trendlines: {
0: {
type: 'polynomial',
degree: 2,
color: 'green',
visibleInLegend: true,
},
1: {
type: 'linear',
color: 'black',
visibleInLegend: true,
},
},
series: {
0: { visibleInLegend: true },
1: { visibleInLegend: false },
},
},
view: {columns: [0,1,2]}
});
google.visualization.events.addOneTimeListener(MSLChart, 'ready', filterChange);
function filterChange() {
// get chart layout
var chartLayout = MSLChart.getChart().getChartLayoutInterface();
// get y-axis bounds
var yAxisCoords = {min: null, max: null};
var lineIndex = 0;
var boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
try {
do {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
} while (boundsLine !== null);
}
catch (error) {alert("Please choose a start year less than or equal to 2018");
window.location.reload(false);
exit;
}
var state = YearPicker.getState();
var EndYear = state.highValue;
// re-draw chart
MSLChart.setOption('vAxis.viewWindow.max', chartLayout.getVAxisValue(yAxisCoords.max));
MSLChart.setOption('vAxis.viewWindow.min', chartLayout.getVAxisValue(yAxisCoords.min));
MSLChart.setOption('hAxis.viewWindow.max', EndYear);
MSLChart.draw();
google.visualization.events.addOneTimeListener(MSLChart.getChart(), 'ready', filterChange);
}
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div')
).bind(YearPicker, MSLChart).draw(data);
}
</script>
<div id="dashboard_div">
<div id="chart_div"></div>
<div id="filter_div"></div>
</div>
</html>
为了防止出错,在filterChange
函数中,
更改 do...while
语句,
do {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
} while (boundsLine !== null);
只是一个 while
语句
while (boundsLine !== null) {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
};
do...while
假定总会至少绘制一条线。
我们无法阻止用户选择超过 2018 年的开始年份,
但我们可以在他们这样做时立即重新设置开始年份。
google.visualization.events.addListener(YearPicker, 'statechange', function () {
var state = YearPicker.getState();
state.lowValue = Math.min(2018, state.lowValue);
YearPicker.setState({
lowValue: state.lowValue,
highValue: state.highValue
});
YearPicker.draw();
filterChange();
});
请参阅以下工作片段...
google.charts.load('current', {
packages: ['controls']
}).then(initialize);
function initialize() {
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1vn1iuhsG33XzFrC4QwkTdUnxOGdcPQOj-cuaEZeX-eA/edit#gid=0');
query.send(drawDashboard);
}
function drawDashboard(response) {
var data = response.getDataTable();
//Asign units of 'mm' to data.
var formatMS = new google.visualization.NumberFormat({
pattern: '# mm'
});
// format data into mm.
for (var colIndex = 1; colIndex < data.getNumberOfColumns(); colIndex++) {
formatMS.format(data, colIndex);
}
var YearPicker = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'filter_div',
options: {
maxValue: 2120,
filterColumnLabel: 'Year',
ui: {
cssClass: 'filter-date',
format: {pattern: '0000'},
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
},
state: {lowValue: 1904, highValue: 2018},
});
google.visualization.events.addListener(YearPicker, 'statechange', function () {
var state = YearPicker.getState();
state.lowValue = Math.min(2018, state.lowValue);
YearPicker.setState({
lowValue: state.lowValue,
highValue: state.highValue
});
YearPicker.draw();
filterChange();
});
var MSLChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
dataTable: data,
options: {
fontSize: '14',
title: 'Timbucktoo Annual Mean Sea Level Summary',
hAxis: {title: 'Year', format: '0000'},
vAxis: {title: 'Height above Chart Datum (mm)', format:'###0'},
height: 600,
chartArea: {height: '81%', width: '85%', left: 100},
legend: {position: 'in', alignment: 'end', textStyle: {fontSize: 13}},
colors: ['blue'],
trendlines: {
0: {
type: 'polynomial',
degree: 2,
color: 'green',
visibleInLegend: true,
},
1: {
type: 'linear',
color: 'black',
visibleInLegend: true,
},
},
series: {
0: { visibleInLegend: true },
1: { visibleInLegend: false },
},
},
view: {columns: [0,1,2]}
});
google.visualization.events.addOneTimeListener(MSLChart, 'ready', filterChange);
function filterChange() {
// get chart layout
var chartLayout = MSLChart.getChart().getChartLayoutInterface();
// get y-axis bounds
var yAxisCoords = {min: null, max: null};
var lineIndex = 0;
var boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
while (boundsLine !== null) {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
};
var state = YearPicker.getState();
var EndYear = state.highValue;
// re-draw chart
MSLChart.setOption('vAxis.viewWindow.max', chartLayout.getVAxisValue(yAxisCoords.max));
MSLChart.setOption('vAxis.viewWindow.min', chartLayout.getVAxisValue(yAxisCoords.min));
MSLChart.setOption('hAxis.viewWindow.max', EndYear);
MSLChart.draw();
google.visualization.events.addOneTimeListener(MSLChart.getChart(), 'ready', filterChange);
}
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div')
).bind(YearPicker, MSLChart).draw(data);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard_div">
<div id="chart_div"></div>
<div id="filter_div"></div>
</div>
编辑
没有修改趋势线工具提示的选项,
但我们可以在 'onmouseover'
事件期间手动更改它。
首先,我们需要使用html工具提示,它们默认是svg。
添加此选项...
tooltip: {
isHtml: true
},
然后将 'onmouseover'
事件添加到图表中,
我们可以在包装器的 'ready'
事件中执行此操作。
google.visualization.events.addOneTimeListener(MSLChart, 'ready', function () {
google.visualization.events.addListener(MSLChart.getChart(), 'onmouseover', function (props) {
// ensure trendline tooltip
if ((props.column === 0) && (props.row !== null)) {
// get year value
var year = MSLChart.getDataTable().getValue(props.row, 0);
// get tooltip, remove width
var tooltip = MSLChart.getChart().getContainer().getElementsByTagName('ul');
tooltip[0].parentNode.style.width = null;
// get tooltip labels
var tooltipLabels = MSLChart.getChart().getContainer().getElementsByTagName('span');
// set year
tooltipLabels[0].innerHTML = year;
// remove formula
tooltipLabels[1].innerHTML = '';
// set height value
var height = parseFloat(tooltipLabels[2].innerHTML.split(' ')[2].replace(',', '')).toFixed(0);
tooltipLabels[2].innerHTML = height + ' mm';
}
});
});
请参阅以下工作片段...
google.charts.load('current', {
packages: ['controls']
}).then(initialize);
function initialize() {
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1vn1iuhsG33XzFrC4QwkTdUnxOGdcPQOj-cuaEZeX-eA/edit#gid=0');
query.send(drawDashboard);
}
function drawDashboard(response) {
var data = response.getDataTable();
//Asign units of 'mm' to data.
var formatMS = new google.visualization.NumberFormat({
pattern: '# mm'
});
// format data into mm.
for (var colIndex = 1; colIndex < data.getNumberOfColumns(); colIndex++) {
formatMS.format(data, colIndex);
}
var YearPicker = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'filter_div',
options: {
maxValue: 2120,
filterColumnLabel: 'Year',
ui: {
cssClass: 'filter-date',
format: {pattern: '0000'},
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
},
state: {lowValue: 1904, highValue: 2018},
});
google.visualization.events.addListener(YearPicker, 'statechange', function () {
var state = YearPicker.getState();
state.lowValue = Math.min(2018, state.lowValue);
YearPicker.setState({
lowValue: state.lowValue,
highValue: state.highValue
});
YearPicker.draw();
filterChange();
});
var MSLChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
dataTable: data,
options: {
fontSize: '14',
title: 'Timbucktoo Annual Mean Sea Level Summary',
hAxis: {title: 'Year', format: '0000'},
vAxis: {title: 'Height above Chart Datum (mm)', format:'###0'},
height: 600,
chartArea: {height: '81%', width: '85%', left: 100},
legend: {position: 'in', alignment: 'end', textStyle: {fontSize: 13}},
colors: ['blue'],
tooltip: {
isHtml: true
},
trendlines: {
0: {
type: 'polynomial',
degree: 2,
color: 'green',
visibleInLegend: true,
},
1: {
type: 'linear',
color: 'black',
visibleInLegend: true,
},
},
series: {
0: { visibleInLegend: true },
1: { visibleInLegend: false },
},
},
view: {columns: [0,1,2]}
});
google.visualization.events.addOneTimeListener(MSLChart, 'ready', filterChange);
function filterChange() {
// get chart layout
var chartLayout = MSLChart.getChart().getChartLayoutInterface();
// get y-axis bounds
var yAxisCoords = {min: null, max: null};
var lineIndex = 0;
var boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
while (boundsLine !== null) {
yAxisCoords.max = yAxisCoords.max || boundsLine.top;
yAxisCoords.max = Math.min(yAxisCoords.max, boundsLine.top);
yAxisCoords.min = yAxisCoords.min || (boundsLine.top + boundsLine.height);
yAxisCoords.min = Math.max(yAxisCoords.min, (boundsLine.top + boundsLine.height));
lineIndex++;
boundsLine = chartLayout.getBoundingBox('line#' + lineIndex);
};
var state = YearPicker.getState();
var EndYear = state.highValue;
// re-draw chart
MSLChart.setOption('vAxis.viewWindow.max', chartLayout.getVAxisValue(yAxisCoords.max));
MSLChart.setOption('vAxis.viewWindow.min', chartLayout.getVAxisValue(yAxisCoords.min));
MSLChart.setOption('hAxis.viewWindow.max', EndYear);
MSLChart.draw();
google.visualization.events.addOneTimeListener(MSLChart.getChart(), 'ready', filterChange);
}
google.visualization.events.addOneTimeListener(MSLChart, 'ready', function () {
google.visualization.events.addListener(MSLChart.getChart(), 'onmouseover', function (props) {
// ensure trendline tooltip
if ((props.column === 0) && (props.row !== null)) {
var year = MSLChart.getDataTable().getValue(props.row, 0);
// get tooltip, remove width
var tooltip = MSLChart.getChart().getContainer().getElementsByTagName('ul');
tooltip[0].parentNode.style.width = null;
// get tooltip labels
var tooltipLabels = MSLChart.getChart().getContainer().getElementsByTagName('span');
// set year
tooltipLabels[0].innerHTML = year;
// remove formula
tooltipLabels[1].innerHTML = '';
// set height
var height = parseFloat(tooltipLabels[2].innerHTML.split(' ')[2].replace(',', '')).toFixed(0);
tooltipLabels[2].innerHTML = height + ' mm';
}
});
});
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div')
).bind(YearPicker, MSLChart).draw(data);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard_div">
<div id="chart_div"></div>
<div id="filter_div"></div>
</div>