[英]toggling series of google chart on and off by clicking on legend
I have an area chart that has 6 series. 我有一个有6个系列的面积图。 I want the user to be able to click on the legend to toggle the visibility of a series.
我希望用户能够点击图例来切换系列的可见性。
I found this example & have tried including it in my code below but nothing happens. 我找到了这个例子 ,并尝试将其包含在我的代码中,但没有任何反应。 Before adding this code if I clicked on one of the series in the legend the series would become thicker, then click on it again & it would go back to normal, believe this is some default behaviour.
在添加此代码之前,如果我点击了图例中的一个系列,那么系列会变得更厚,然后再次点击它会恢复正常,相信这是一些默认行为。 However with this code included once the series gets thicker I can't do anything, ie zoom or click on the chart to get the value of a point.
然而,一旦系列变得更厚,包含此代码我就无法做任何事情,即缩放或点击图表以获得一个点的值。
Not sure what I am missing? 不确定我错过了什么?
Update 更新
I have also tried following this post but same result. 我也尝试过这篇文章,但结果相同。
latest update 最新更新
I have changed my code to the following. 我已将代码更改为以下内容。
The error I'm getting now is the following... 我现在得到的错误如下......
Uncaught Error: Invalid column index 8. Should be an integer in the range [0-7]. 未捕获的错误:列索引无效8.应该是[0-7]范围内的整数。 at gvjs_en (jsapi_compiled_default_module.js:75) at gvjs_P.gvjs_.uc (jsapi_compiled_default_module.js:92) at gvjs_P.gvjs_.Za (jsapi_compiled_default_module.js:91) at Data.displayed.reduce (jScore.js:220) at Array.reduce () at vparse (jScore.js:214) at showHideSeries (jScore.js:202) at gvjs_Zn.
at gvjs_en(jsapi_compiled_default_module.js:75)at gvjs_P.gvjs_.uc(jsapi_compiled_default_module.js:92)at gvjs_P.gvjs_.Za(jsapi_compiled_default_module.js:91)at Data.displayed.reduce(jScore.js:220)at Array .duce()at vparse(jScore.js:214)at showHideSeries(jScore.js:202)at gvjs_Zn。 (jsapi_compiled_default_module.js:179) at gvjs__n (jsapi_compiled_default_module.js:129) at gvjs_Zn.gvjs_.dispatchEvent (jsapi_compiled_default_module.js:127)
(jsapi_compiled_default_module.js:179)在gvjs__n(jsapi_compiled_default_module.js:129)gvjs_Zn.gvjs_.dispatchEvent(jsapi_compiled_default_module.js:127)
My HTML 我的HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script src="scripts/jScore.js"></script>
<script type="text/javascript">
google.charts.load('current', { 'packages': ['corechart', 'table'] });
</script>
</head>
<body>
<div id="chartScore" style="height:1000px"></div>
</body>
</html>
My JS file 我的JS文件
var MyData = {};
$(document).ready(function () {
$.ajax({
type: 'GET',
url: 'api/Score',
dataType: 'json',
success: function (data) {
MyData.dataValues = data;
PopulateData();
DrawChartScores();
},
error: function () {
alert("Error loading data! Please try again");
}
});
};
var Data = {};
function PopulateData() {
Data = {
displayed: [...MyData.dataValues],
hidden: Object.keys(MyData.dataValues[0]).reduce((a, c) => {
a[c] = false;
return a;
}, {}),
map: Object.keys(MyData.dataValues[0])
};
}
function DrawChartScores() {
var dataValues = MyData.dataValues;
var data = new google.visualization.DataTable();
var options = {
title: 'Scores', width: '80%', height: '80%',
explorer:
{
keepInBounds: true,
actions: ['dragToZoom', 'rightClickToReset']
},
series: Data.map.reduce((a, c, i) => {
a[i] = {};
return a;
}, {})
};
data.addColumn('date', 'Day');
data.addColumn('number', 'A');
data.addColumn('number', 'B');
data.addColumn('number', 'C');
data.addColumn('number', 'D');
data.addColumn('number', 'E');
data.addColumn('number', 'F');
data.addColumn('number', 'Nrs');
// add data
for (var i = 0; i < dataValues.length; i++) {
data.addRow([new Date(dataValues[i].DateRet), dataValues[i].A, dataValues[i].B, dataValues[i].C,
dataValues[i].D, dataValues[i].E, dataValues[i].F, dataValues[i].Nrs]);
}
var chart = new google.visualization.AreaChart(document.getElementById('chartScore'));
var last = {
column: true,
row: true
};
function showHideSeries() {
var sel = chart.getSelection();
if (sel.length === 0 && last.row === null) {
Data.hidden[Data.map[last.column]] = !Data.hidden[Data.map[last.column]];
} else if (sel.length && sel[0].row === null) {
// toggle the current item selected
Data.hidden[Data.map[sel[0].column]] = !Data.hidden[Data.map[sel[0].column]];
last = sel[0];
} else {
return;
}
vparse(data);
options = vkillLegend(options);
chart.draw(data, options);
};
google.visualization.events.addListener(chart, 'select', showHideSeries);
chart.draw(data, options);
};
function vparse(data) {
Data.displayed.reduce((a, c, i) => {
for (let k in c) {
if (k === "DateRet") continue;
if (Data.hidden[k])
data.setValue(i, Data.map.indexOf(k), null);
else
data.setValue(i, Data.map.indexOf(k), c[k]);
}
return true;
}, []);
return data;
}
function vkillLegend(options) {
options.series = Object.keys(options.series).reduce((a, c, i) => {
let current = {};
if (Data.hidden[Data.map[i]]) current.color = "#CCCCCC";
else c.color = null;
a[i - 1] = current;
return a;
}, {});
return options;
};
// jshint esnext: true google.charts.load('current', {'packages': ['corechart', 'table']}); var dataValues = [{DateScore: '2018-6-14', A: 1000, B: 900, C: 800, D: 700, E: 600, F: 500, NrS: 400, }, {DateScore: '2018-6-15', A: 1000, B: 900, C: 800, D: 700, E: 600, F: 500, NrS: 400, }, {DateScore: '2018-6-17', A: 1000, B: 900, C: 800, D: 700, E: 600, F: 500, NrS: 400, }, {DateScore: '2018-6-22', A: 800, B: 600, C: 1000, D: 900, E: 300, F: 100, NrS: 600, } ]; var Data = { displayed: [...dataValues], hidden: Object.keys(dataValues[0]).reduce((a, c) => { a[c] = false; return a; }, {}), map: Object.keys(dataValues[0]) }; google.charts.setOnLoadCallback(DrawChartScores); function DrawChartScores() { var data = new google.visualization.DataTable(); var options = { title: 'Scores', width: '80%', height: '80%', explorer: { keepInBounds: true, actions: ['dragToZoom', 'rightClickToReset'] }, series: Data.map.reduce((a, c, i) => { a[i] = {}; return a; }, {}) }; data.addColumn('date', 'Day'); data.addColumn('number', 'A'); data.addColumn('number', 'B'); data.addColumn('number', 'C'); data.addColumn('number', 'D'); data.addColumn('number', 'E'); data.addColumn('number', 'F'); data.addColumn('number', 'NrS'); for (var i = 0; i < dataValues.length; i++) { let newRow = Object.values(dataValues[i]); newRow[0] = new Date(newRow[0]); data.addRow(newRow); } var chart = new google.visualization.AreaChart(document.getElementById('chartP')); var last = { column: true, row: true }; function showHideSeries() { var sel = chart.getSelection(); if (sel.length === 0 && last.row === null) { Data.hidden[Data.map[last.column]] = !Data.hidden[Data.map[last.column]]; } else if (sel.length && sel[0].row === null) { // toggle the current item selected Data.hidden[Data.map[sel[0].column]] = !Data.hidden[Data.map[sel[0].column]]; last = sel[0]; } else { return; } vparse(data); options = vkillLegend(options); chart.draw(data, options); } google.visualization.events.addListener(chart, 'select', showHideSeries); chart.draw(data, options); } function vparse(data) { Data.displayed.reduce((a, c, i) => { for (let k in c) { if (k === "DateScore") continue; if (Data.hidden[k]) data.setValue(i, Data.map.indexOf(k), null); else data.setValue(i, Data.map.indexOf(k), c[k]); } return true; }, []); return data; } function vkillLegend(options) { options.series = Object.keys(options.series).reduce((a, c, i) => { let current = {}; if (Data.hidden[Data.map[i]]) current.color = "#CCCCCC"; else c.color = null; a[i - 1] = current; return a; }, {}); return options; }
<!DOCTYPE html> <html> <head> <title>My Title</title> <meta charset="utf-8" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> </head> <body> <div id="chartP" style="height:1000px"></div> </body>
Data
object: Data
对象:
displayed
- array that contains all the starting data provided by dataValues
displayed
- 包含dataValues
提供的所有起始数据的dataValues
hidden
- keeps track of the legend items that have been hidden with a simple object mapping the column key to the boolean representation of their display hidden
- 使用将列键映射到其显示的布尔表示的简单对象来跟踪已隐藏的图例项 map
- simply an array where the index of the item is the location on the chart, also used to convert column index to column key map
- 只是一个数组,其中项的索引是图表上的位置,也用于将列索引转换为列键 options.series
- an object representation of each of the columns; options.series
- 每个列的对象表示; this is used to modify the legend color when clicked. last
- this is more-so a product of google charts event handling; last
- 这是谷歌图表事件处理的产物; essentially, if you click on the same thing twice, the second click will register with no data from getSelection()
. getSelection()
数据。 This means we have to store all the previous clicks if we want a user-friendly experience. When the legend item is clicked, there are a few things that happens: 单击图例项时,会发生以下几种情况:
showHideSeries()
decides whether or not the click was on the legend, and if it was on the legend, act accordingly - regardless of the selection being empty or not; showHideSeries()
决定点击是否在图例上,如果它在图例上,则相应地采取行动 - 无论选择是否为空; vparse()
prepares the new data set based on the base data provided in dataValues
vparse()
根据dataValues
提供的基础数据准备新数据集 vkillLegend()
kills the styling on the legend items which are no longer present in the data set, and restores styling for data that was re-added; vkillLegend()
杀死数据集中不再存在的图例项的样式,并恢复重新添加的数据的样式; chart.draw()
chart.draw()
You can see a working example by clicking the Run code snippet
button above. 您可以点击上面的
Run code snippet
按钮查看工作示例。
I hope this helps! 我希望这有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.