I have a webpage featuring pie charts and a bar chart. While the rest of the functionality works as expected, I'm encountering issues with the filtering mechanism. Specifically, when I filter out a segment from a pie chart, it's being visually represented as if the remaining segments fill up the entire pie.
For instance, let's consider Chart A with three segments: 50%, 25%, and 25%. When I click on the legend to filter out the segment representing 50%, instead of greying out this segment and displaying the remaining segments (25%, 25%) as they are, the chart appears as if the remaining segments now occupy the entire pie.
I'd like the filtered-out segment to be visually differentiated, perhaps by graying it out, while still showing the remaining segments (25%, 25%) as they are.
Here is my code -
document.addEventListener('DOMContentLoaded', function () {
// Check if Highcharts is defined before calling the function
if (typeof Highcharts !== 'undefined') {
var example1Table;
var exampleTable;
// Initialize DataTable for #example1
initializeChart('demo-output', '#example1', 'test 2023');
// Initialize DataTable for #example
initializeChart('demo-output2', '#example', 'test 2022');
var allSeriesData = [];
var categories = [];
var table = $("#example2").DataTable({
searching: false,
responsive: true,
lengthChange: false,
ordering: false,
info: false,
paging: false,
initComplete: function (settings, json) {
let api = new $.fn.dataTable.Api(settings);
// get the x-axis caregories from the table headings:
var headers = api.columns().header().toArray();
headers.forEach(function (heading, index) {
if (index > 0 && index < headers.length) {
categories.push($(heading).html());
}
});
// get the seris data as an array of numbers from the table row data:
let rows = api.rows().data().toArray();
rows.forEach(function (row) {
group = {
name: '',
data: []
};
row.forEach(function (cell, idx) {
if (idx == 0) {
group.name = cell;
} else if (idx < row.length) {
group.data.push(parseFloat(cell.replace(/,/g, '')));
}
});
allSeriesData.push(group);
});
}
});
Highcharts.setOptions({
lang: {
thousandsSep: ','
}
});
// Function to initialize chart
function initializeChart(chartId, tableId, chartTitle) {
// Destroy existing DataTable instance
if ($.fn.DataTable.isDataTable(tableId)) {
$(tableId).DataTable().destroy();
}
// Create DataTable
const table = new DataTable(tableId, {
searching: false,
info: true,
paging: false,
sort: false
});
// Create chart
const chart = Highcharts.chart(chartId, {
chart: {
type: 'pie',
styledMode: false
},
title: {
text: chartTitle
},
colors: ['#1a4480', '#e52207', '#e66f0e', '#ffbe2e', '#fee685', '#538200', '#04c585', '#97d4ea', '#009ec1', '#0076d6', '#adadad', '#8168b3', '#d72d79', '#f2938c' ],
tooltip: {
pointFormat: '</b> {point.y:.1f}%'
},
series: [
{
data: chartData(table)
}
],
credits: {
enabled: false
},
plotOptions: {
pie: {
size: 270,
innerSize:70,
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
distance: 30,
padding: 1,
style: {
fontSize: "12px"
},
format: '{point.y:.1f}%'
},
showInLegend: true // Show legends
}
}
});
// On each draw, update the data in the chart
table.on('draw', function () {
if (chart && chart.series && chart.series.length > 0) {
// Update the chart data only if series is initialized
chart.series[0].setData(chartData(table));
} else {
// If chart or chart series is not properly initialized, log an error
}
});
// Function to get chart data from DataTable
function chartData(table) {
var data = [];
table.rows().every(function () {
var row = this.data();
data.push({
name: row[0], // Assuming the first column is the name
y: parseFloat(row[1]) // Assuming the second column is the numeric value
});
});
return data;
}
}
// Function to initialize trend chart
function initializeTrendChart() {
// Your trend chart initialization code here
// Example:
var trendChart = Highcharts.chart("chart-A", {
chart: {
type: "column",
borderColor: 'lightgray',
borderWidth: 1,
marginTop: 50
},
tooltip: {
headerFormat: '{point.key}<br/>',
pointFormat: '{series.name}: <b>{point.y:.1f}%</b>'
},
legend: {
symbolRadius: 0,
itemStyle: {
color: '#000000',
fontSize: '16px'
}
},
colors: ['#003489', '#ED7D31', '#A5A5A5', '#FFC000', '#5B9BD5'],
credits: {
enabled: false
},
title: {
text: "test3"
},
xAxis: {
categories: categories,
labels: {
style: {
fontWeight: '600',
fontSize: '16px',
color: '#000000'
}
}
},
yAxis: {
title: false,
tickInterval: 10,
max: 60,
labels: {
formatter: function () {
return Highcharts.numberFormat(this.value, 0);
},
style: {
fontWeight: '600',
fontSize: '16px',
color: '#000000'
}
}
},
series: allSeriesData
});
}
// Button click event listeners
$('.usa-button').on('click', function () {
var buttonId = $(this).attr('id');
// Toggle chart visibility based on button click
if (buttonId === 'previous') {
$('#chart2').show();
$('#chart1').hide();
$('#chart3').hide();
initializeChart('demo-output2', '#example', 'test 2022');
} else if (buttonId === 'trend') {
$('#chart2').hide();
$('#chart1').hide();
$('#chart3').show();
initializeTrendChart(); // Reinitialize trend chart
} else {
// Default case, show chart1
$('#chart2').hide();
$('#chart1').show();
$('#chart3').hide();
initializeChart('demo-output', '#example1', 'test 2023');
}
// Highlight the active button
$('.usa-button').removeClass('active');
$(this).addClass('active');
});
// Set default highlight on 2023 button
$('#current').addClass('active');
}
});
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<link href="https://nightly.datatables.net/css/dataTables.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://nightly.datatables.net/js/dataTables.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<div class="ar-controls grid-row tablet:flex-justify-start">
<div class="tablet:grid-col-auto margin-bottom-205"><button id="current" class="usa-button usa-button--outline" title="Select to see related information below">one</button> <button id="previous" class="usa-button usa-button--outline" title="Select to see related information below">two</button> <button id="trend" class="usa-button usa-button--outline" title="Select to see related information below">three</button></div>
</div>
<div id="chart1">
<div id="demo-output" class="chart-display" style=" margin-bottom: 2em; height: 500px; border: solid 1px lightgray;"></div>
<table id="example1" class="display" style=" width: 100%;"><thead>
<tr>
<th scope="col">2023</th>
<th scope="col">Percent</th>
</tr>
</thead>
<tr>
<td scope="row">ABC</td>
<td>45.9%</td>
</tr>
<tr>
<td scope="row">DEF</td>
<td>22.0%</td>
</tr>
<tr>
<td scope="row">GHI</td>
<td>13.6%</td>
</tr>
</table>
</div>
<div id="chart2" style=" display: none;">
<div id="demo-output2" class="chart-display2" style=" margin-bottom: 2em; height: 680px; border: solid 1px lightgray;"></div>
<table id="example" class="display" style=" width: 100%;"><thead>
<tr>
<th scope="col">2022</th>
<th scope="col">Percent</th>
</tr>
</thead>
<tr>
<td>AAA</td>
<td>51.90%</td>
</tr>
<tr>
<td>BBB</td>
<td>18.60%</td>
</tr>
</table>
</div>
<div id="chart3" style=" display: none;">
<div id="chart-A" style=" width: 100%; height: 500px;"></div>
<table class="row-border stripe no-footer cell-border padding-top-5" id="example2" style=" width: 100%;"><thead>
<tr>
<th>Year</th>
<th>column1</th>
<th>column2</th>
<th>column3</th>
</tr>
</thead>
<tr>
<td scope="row" style=" text-align: left; white-space: nowrap;">FY19</td>
<td style=" text-align: left;">42.7%</td>
<td style=" text-align: left;">17.3%</td>
<td style=" text-align: left;">9.5%</td>
</tr>
<tr>
<td scope="row" style=" text-align: left;">FY20</td>
<td style=" text-align: left;">49.5%</td>
<td style=" text-align: left;">16.3%</td>
<td style=" text-align: left;">3.4%</td>
</tr>
</table>
</div>
</div>
To disabling hiding slices on pie chart you need to use series.point.events.legendItemClick function. Over there you can also update the point's color.
legendItemClick: function() {
this.update({
color: 'gray'
})
return false;
}
API references: https://api.highcharts.com/class-reference/Highcharts.Point#update