如何使用带有饼图的 Google 图表(可视化)过滤器保持一致的颜色?
How to maintain consistent colors using a Google charts (visualisation) filter with a pie chart?
我想要一个像 this example 这样带有饼图的仪表板,但要保持颜色一致。例如。在示例中,如果将过滤器从 None 设置为女性,Margreth 的颜色会从粉红色变为橙色。
不幸的是,{ role: 'style' } 选项不适用于饼图。相反,必须在选项中提供颜色列表。使用过滤器时,将使用列表中的第一个可用颜色。因此,与 this (unfortenately) accepted answer 不同,提供大小等于未过滤数据集总数的颜色列表无济于事。
相反,我认为需要定义一个函数来动态创建与过滤数据对齐的颜色列表,例如:
function getColors () {
// build colors array
var colors = [];
for (var i = 0; i < data.getNumberOfRows(); i++) {
colors.push(data.getValue(i, 2)); // color is in the 3nd column of the datatable
}
return colors; }
'options':{
colors: getColors() },
仅供参考 jsfiddle。
但是,如果我这样做,getColors return 是完整数据集的颜色。
=> 我该怎么做?:
- 只有 return 过滤后的行,因此只有颜色列表可以显示?我注意到一个方法“getFilteredRows”,但这似乎更像是一种构建您自己的过滤器的方法,我不明白。
- 确保每次更改滤镜时更新并应用颜色列表?上面的 fiddle 是在单击按钮时完成的。我不知道如何使用 google 图表过滤器来做到这一点。我尝试使用过滤器、select 或仪表板等值准备好 addListener(见下文)。但是 none 这些工作。
仅供参考,我的仪表板代码:
HTML:
<div id = "dashboard_TK_stemmen">
<div id="filter_TK_stemmen"></div>
<p id = "pie_TK_stemmen"></p>
</div>
JS:
google.charts.setOnLoadCallback(Dashboard);
function Dashboard() {
var data = google.visualization.arrayToDataTable([ ['Partij', 'Aantal', { role: 'style' }, 'Datum'], ['PvdA', 20105, '#E30613', '20 maart 2019'], ['VVD', 9919, '#F47621', '20 maart 2019'], ['CDA', 6480, '#007B5F', '20 maart 2019'], ['PvdA', 13303, '#E30613', '18 maart 2015'], ['VVD', 8096, '#F47621', '18 maart 2015'], ['CDA', 5896, '#007B5F', '18 maart 2015'] ]);
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_TK_stemmen'));
var filter = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'filter_TK_stemmen',
'options': {
'filterColumnLabel': 'Datum',
'ui': {'caption': 'Kies een verkiezingsuitslag', 'label': 'Uitslag van: ', 'allowNone': false, 'allowMultiple': false,
'sortValues':false,'allowTyping':false} } });
function getColors () {
// build colors array
var colors = [];
for (var i = 0; i < data.getNumberOfRows(); i++) {
colors.push(data.getValue(i, 2));
}
return colors; }
var pie = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'pie_TK_stemmen',
'options':{
pieHole: 0.3,
chartArea: {bottom: 0, width: '100%', height: '85%'},
hAxis: {textPosition: 'in'}, vAxis: {textPosition: 'in'},
legend: {position: 'top', maxLines: 3},
colors: getColors() },
'view': {'columns': [0, 1]}
});
dashboard.bind(filter, pie);
dashboard.draw(data);
google.visualization.events.addListener(pie, 'ready', function() {
pie.setOption('colors', getColors());
});
};
我们可以独立绘制过滤器和饼图,
而不是使用仪表板。
我们使用过滤器上的 'ready'
和 'statechange'
事件来知道何时绘制饼图。
当这些事件中的任何一个被触发时,我们都会从过滤器中获取选定的值。
var filterValue = filter.getState().selectedValues[0];
由于您在过滤器上设置了以下选项,
我们可以确定 selectedValues
数组中始终只有一个值...
allowNone: false,
allowMultiple: false,
使用过滤器的值,我们可以使用 getFilteredRows
找到符合过滤器的行
var visibleRows = data.getFilteredRows([{
column: 3,
value: filterValue
}]);
然后我们可以使用可见行在原始数据上构建数据视图 table。
var dataView = new google.visualization.DataView(data);
dataView.setRows(visibleRows);
然后我们可以从数据视图中的样式列中提取颜色。
var colors = [];
for (var i = 0; i < dataView.getNumberOfRows(); i++) {
colors.push(dataView.getValue(i, 2));
}
并将颜色和数据视图应用于饼图并绘制...
pie.setDataTable(dataView);
pie.setOption('colors', colors);
pie.draw();
请参阅以下工作片段...
看起来每个过滤器值都有相同的颜色集,
所以出于示例目的,我更改了第二组颜色...
google.charts.load('current', {
packages: ['controls', 'corechart']
}).then(Dashboard);
function Dashboard() {
// build data table
var data = google.visualization.arrayToDataTable([
['Partij', 'Aantal', { role: 'style' }, 'Datum'],
['PvdA', 20105, '#E30613', '20 maart 2019'],
['VVD', 9919, '#F47621', '20 maart 2019'],
['CDA', 6480, '#007B5F', '20 maart 2019'],
['PvdA', 13303, 'cyan', '18 maart 2015'],
['VVD', 8096, 'magenta', '18 maart 2015'],
['CDA', 5896, 'yellow', '18 maart 2015']
]);
// build filter
var filter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'filter_TK_stemmen',
dataTable: data, // <-- assign data table to filter
options: {
filterColumnLabel: 'Datum',
ui: {
caption: 'Kies een verkiezingsuitslag',
label: 'Uitslag van: ',
allowNone: false,
allowMultiple: false,
sortValues: false,
allowTyping: false
}
}
});
// build pie chart
var pie = new google.visualization.ChartWrapper({
chartType: 'PieChart',
containerId: 'pie_TK_stemmen',
options: {
pieHole: 0.3,
chartArea: {bottom: 0, width: '100%', height: '85%'},
legend: {position: 'top', maxLines: 3},
},
view: {
columns: [0, 1]
}
});
// assign filter event listeners
google.visualization.events.addListener(filter, 'statechange', drawPie);
google.visualization.events.addListener(filter, 'ready', drawPie);
// draw filter
filter.draw();
// draw pie chart, called from filter events
function drawPie() {
// get selected filter value
var filterValue = filter.getState().selectedValues[0];
// get visible rows for filter value
var visibleRows = data.getFilteredRows([{
column: 3,
value: filterValue
}]);
// build data view over original data table
var dataView = new google.visualization.DataView(data);
dataView.setRows(visibleRows);
// get colors from style column in data view
var colors = [];
for (var i = 0; i < dataView.getNumberOfRows(); i++) {
colors.push(dataView.getValue(i, 2));
}
// assign data view, colors, and draw pie chart
pie.setDataTable(dataView);
pie.setOption('colors', colors);
pie.draw();
}
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id = "dashboard_TK_stemmen">
<div id="filter_TK_stemmen"></div>
<p id = "pie_TK_stemmen"></p>
</div>
我想要一个像 this example 这样带有饼图的仪表板,但要保持颜色一致。例如。在示例中,如果将过滤器从 None 设置为女性,Margreth 的颜色会从粉红色变为橙色。
不幸的是,{ role: 'style' } 选项不适用于饼图。相反,必须在选项中提供颜色列表。使用过滤器时,将使用列表中的第一个可用颜色。因此,与 this (unfortenately) accepted answer 不同,提供大小等于未过滤数据集总数的颜色列表无济于事。
相反,我认为需要定义一个函数来动态创建与过滤数据对齐的颜色列表,例如:
function getColors () {
// build colors array
var colors = [];
for (var i = 0; i < data.getNumberOfRows(); i++) {
colors.push(data.getValue(i, 2)); // color is in the 3nd column of the datatable
}
return colors; }
'options':{
colors: getColors() },
仅供参考 jsfiddle。
但是,如果我这样做,getColors return 是完整数据集的颜色。
=> 我该怎么做?:
- 只有 return 过滤后的行,因此只有颜色列表可以显示?我注意到一个方法“getFilteredRows”,但这似乎更像是一种构建您自己的过滤器的方法,我不明白。
- 确保每次更改滤镜时更新并应用颜色列表?上面的 fiddle 是在单击按钮时完成的。我不知道如何使用 google 图表过滤器来做到这一点。我尝试使用过滤器、select 或仪表板等值准备好 addListener(见下文)。但是 none 这些工作。
仅供参考,我的仪表板代码:
HTML:
<div id = "dashboard_TK_stemmen">
<div id="filter_TK_stemmen"></div>
<p id = "pie_TK_stemmen"></p>
</div>
JS:
google.charts.setOnLoadCallback(Dashboard);
function Dashboard() {
var data = google.visualization.arrayToDataTable([ ['Partij', 'Aantal', { role: 'style' }, 'Datum'], ['PvdA', 20105, '#E30613', '20 maart 2019'], ['VVD', 9919, '#F47621', '20 maart 2019'], ['CDA', 6480, '#007B5F', '20 maart 2019'], ['PvdA', 13303, '#E30613', '18 maart 2015'], ['VVD', 8096, '#F47621', '18 maart 2015'], ['CDA', 5896, '#007B5F', '18 maart 2015'] ]);
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_TK_stemmen'));
var filter = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'filter_TK_stemmen',
'options': {
'filterColumnLabel': 'Datum',
'ui': {'caption': 'Kies een verkiezingsuitslag', 'label': 'Uitslag van: ', 'allowNone': false, 'allowMultiple': false,
'sortValues':false,'allowTyping':false} } });
function getColors () {
// build colors array
var colors = [];
for (var i = 0; i < data.getNumberOfRows(); i++) {
colors.push(data.getValue(i, 2));
}
return colors; }
var pie = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'pie_TK_stemmen',
'options':{
pieHole: 0.3,
chartArea: {bottom: 0, width: '100%', height: '85%'},
hAxis: {textPosition: 'in'}, vAxis: {textPosition: 'in'},
legend: {position: 'top', maxLines: 3},
colors: getColors() },
'view': {'columns': [0, 1]}
});
dashboard.bind(filter, pie);
dashboard.draw(data);
google.visualization.events.addListener(pie, 'ready', function() {
pie.setOption('colors', getColors());
});
};
我们可以独立绘制过滤器和饼图,
而不是使用仪表板。
我们使用过滤器上的 'ready'
和 'statechange'
事件来知道何时绘制饼图。
当这些事件中的任何一个被触发时,我们都会从过滤器中获取选定的值。
var filterValue = filter.getState().selectedValues[0];
由于您在过滤器上设置了以下选项,
我们可以确定 selectedValues
数组中始终只有一个值...
allowNone: false,
allowMultiple: false,
使用过滤器的值,我们可以使用 getFilteredRows
var visibleRows = data.getFilteredRows([{
column: 3,
value: filterValue
}]);
然后我们可以使用可见行在原始数据上构建数据视图 table。
var dataView = new google.visualization.DataView(data);
dataView.setRows(visibleRows);
然后我们可以从数据视图中的样式列中提取颜色。
var colors = [];
for (var i = 0; i < dataView.getNumberOfRows(); i++) {
colors.push(dataView.getValue(i, 2));
}
并将颜色和数据视图应用于饼图并绘制...
pie.setDataTable(dataView);
pie.setOption('colors', colors);
pie.draw();
请参阅以下工作片段...
看起来每个过滤器值都有相同的颜色集,
所以出于示例目的,我更改了第二组颜色...
google.charts.load('current', {
packages: ['controls', 'corechart']
}).then(Dashboard);
function Dashboard() {
// build data table
var data = google.visualization.arrayToDataTable([
['Partij', 'Aantal', { role: 'style' }, 'Datum'],
['PvdA', 20105, '#E30613', '20 maart 2019'],
['VVD', 9919, '#F47621', '20 maart 2019'],
['CDA', 6480, '#007B5F', '20 maart 2019'],
['PvdA', 13303, 'cyan', '18 maart 2015'],
['VVD', 8096, 'magenta', '18 maart 2015'],
['CDA', 5896, 'yellow', '18 maart 2015']
]);
// build filter
var filter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'filter_TK_stemmen',
dataTable: data, // <-- assign data table to filter
options: {
filterColumnLabel: 'Datum',
ui: {
caption: 'Kies een verkiezingsuitslag',
label: 'Uitslag van: ',
allowNone: false,
allowMultiple: false,
sortValues: false,
allowTyping: false
}
}
});
// build pie chart
var pie = new google.visualization.ChartWrapper({
chartType: 'PieChart',
containerId: 'pie_TK_stemmen',
options: {
pieHole: 0.3,
chartArea: {bottom: 0, width: '100%', height: '85%'},
legend: {position: 'top', maxLines: 3},
},
view: {
columns: [0, 1]
}
});
// assign filter event listeners
google.visualization.events.addListener(filter, 'statechange', drawPie);
google.visualization.events.addListener(filter, 'ready', drawPie);
// draw filter
filter.draw();
// draw pie chart, called from filter events
function drawPie() {
// get selected filter value
var filterValue = filter.getState().selectedValues[0];
// get visible rows for filter value
var visibleRows = data.getFilteredRows([{
column: 3,
value: filterValue
}]);
// build data view over original data table
var dataView = new google.visualization.DataView(data);
dataView.setRows(visibleRows);
// get colors from style column in data view
var colors = [];
for (var i = 0; i < dataView.getNumberOfRows(); i++) {
colors.push(dataView.getValue(i, 2));
}
// assign data view, colors, and draw pie chart
pie.setDataTable(dataView);
pie.setOption('colors', colors);
pie.draw();
}
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id = "dashboard_TK_stemmen">
<div id="filter_TK_stemmen"></div>
<p id = "pie_TK_stemmen"></p>
</div>