I would like a dashboard with a pie chart like this example but keep the colors consistent. E.g. in the example, the color of Margreth changes from pink to orange if you set the filter from None to Female.
The { role: 'style' } option is unfortunately not available for pie charts. Instead, a list of colors has to be provided in the options. When using the filter, the first available colors from the list are used. So unlike this (unfortenately) accepted answer, it does not help to provide a list of colors with a size equal to the total unfiltered dataset.
Instead, I think a function needs to be defined to dynamically create a list of colors that aligns with the filtered data, like:
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() },
FYI this jsfiddle.
However, if I do that, getColors returns the colors for the complete dataset.
=> how do I?:
FYI my code for this dashboard:
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());
});
};
we can draw the filter and pie chart independently from one another,
rather than using a dashboard.
we use the 'ready'
and 'statechange'
events on the filter to know when to draw the pie chart.
when either of these events are fired, we get the selected value from the filter.
var filterValue = filter.getState().selectedValues[0];
since you have the following options set on the filter,
we can be sure there is always only one value in the selectedValues
array...
allowNone: false,
allowMultiple: false,
using the value from the filter, we can find the rows that meet the filter using getFilteredRows
var visibleRows = data.getFilteredRows([{
column: 3,
value: filterValue
}]);
we can then use the visible rows to build a data view over the original data table.
var dataView = new google.visualization.DataView(data);
dataView.setRows(visibleRows);
then we can pull the colors from the style column in the data view.
var colors = [];
for (var i = 0; i < dataView.getNumberOfRows(); i++) {
colors.push(dataView.getValue(i, 2));
}
and apply the colors and data view to the pie chart and draw it...
pie.setDataTable(dataView);
pie.setOption('colors', colors);
pie.draw();
see following working snippet...
it appears you had the same set of colors for each filter value,
so I've changed the second set of colors for example purposes...
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>