highcharts / highcharts/highcharts_flutter
HighchartsTreemapSeriesStatesOptions : inactive behavior not working as expected
- Dominant language
- Dart
- Stars
- 12
- Forks
- 3
- PR merge metrics
- No merged PRs in 30d
Description
### Expected behaviour
`HighchartsTreemapSeriesStatesOptions(
inactive: HighchartsSeriesStatesInactiveOptions(enabled: false
),)`
Expecting the inactive behavior to get disabled.
### Actual behaviour
Even after updating the enabled parameter to false, the inactive overlay is still not getting disabled.
### Version
1.1.2
### Affected devices/platforms
Web with Chrome
### Relevant log output
```shell
```
### Relevant code snippet
```dart
class TreemapNode {
final String id;
final String name;
final double? value;
final double? colorValue;
final List? children;
TreemapNode({
required this.id,
required this.name,
this.value,
this.colorValue,
this.children,
});
/// Flatten hierarchical data into Highcharts-compatible flat list
List> toFlatList({String? parentId}) {
final List> list = [];
list.add({
'id': id,
'name': name,
if (parentId != null) 'parent': parentId,
if (value != null) 'value': value,
if (colorValue != null) 'colorValue': colorValue,
});
if (children != null && children!.isNotEmpty) {
for (final child in children!) {
list.addAll(child.toFlatList(parentId: id));
}
}
return list;
}
}
final List treemapData = [
TreemapNode(
id: 'Technology',
name: 'Technology',
value: 305000000,
colorValue: 9.5,
children: [
TreemapNode(
id: 'MSFT', name: 'Microsoft Corp.', value: 2400000, colorValue: 3.8),
TreemapNode(
id: 'GOOGL', name: 'Alphabet Inc.', value: 1600000, colorValue: -1.5),
TreemapNode(
id: 'ADBE', name: 'Adobe Inc.', value: 220000, colorValue: 7.8),
TreemapNode(
id: 'NFLX', name: 'Netflix Inc.', value: 190000, colorValue: -1.8),
TreemapNode(
id: 'CRM', name: 'Salesforce Inc.', value: 200000, colorValue: 4.2),
TreemapNode(
id: 'AAPL', name: 'Apple Inc.', value: 2800000, colorValue: 5.2),
TreemapNode(
id: 'TSLA', name: 'Tesla Inc.', value: 800000, colorValue: 8.7),
TreemapNode(
id: 'NVDA', name: 'NVIDIA Corp.', value: 1200000, colorValue: 12.5),
TreemapNode(
id: 'WIN1', name: 'Big Winner Inc', value: 75000, colorValue: 14.2),
],
),
TreemapNode(
id: 'Financial',
name: 'Financial',
value: 205000000,
colorValue: 4.5,
children: [
TreemapNode(
id: 'JPM', name: 'JPMorgan Chase', value: 450000, colorValue: 1.2),
TreemapNode(
id: 'BAC', name: 'Bank of America', value: 280000, colorValue: -2.1),
TreemapNode(id: 'V', name: 'Visa Inc.', value: 480000, colorValue: 4.5),
TreemapNode(
id: 'MA', name: 'Mastercard Inc.', value: 340000, colorValue: 3.2),
],
),
TreemapNode(
id: 'Healthcare',
name: 'Healthcare',
value: 140500000,
colorValue: -1.3,
children: [
TreemapNode(
id: 'JNJ',
name: 'Johnson and Johnson',
value: 420000,
colorValue: -0.8),
TreemapNode(
id: 'UNH',
name: 'UnitedHealth Group',
value: 520000,
colorValue: 6.1),
],
),
TreemapNode(
id: 'Consumer',
name: 'Consumer',
value: 245000000,
colorValue: 24.5,
children: [
TreemapNode(
id: 'AMZN', name: 'Amazon.com Inc.', value: 1500000, colorValue: 2.1),
TreemapNode(id: 'HD', name: 'Home Depot', value: 350000, colorValue: 1.8),
TreemapNode(
id: 'WMT', name: 'Walmart Inc.', value: 420000, colorValue: 0.9),
TreemapNode(
id: 'PG', name: 'Procter and Gamble', value: 380000, colorValue: 2.3),
TreemapNode(
id: 'DIS', name: 'Walt Disney Co.', value: 180000, colorValue: -3.2),
],
),
TreemapNode(
id: 'Energy',
name: 'Energy',
value: -6.7,
colorValue: 12.5,
children: [
TreemapNode(
id: 'XOM', name: 'Exxon Mobil', value: 450000, colorValue: -4.3),
TreemapNode(
id: 'LOSS1', name: 'Big Loser Corp', value: 50000, colorValue: -8.5),
],
),
];
class SectorHeatmapChart extends StatelessWidget {
const SectorHeatmapChart({super.key});
@override
Widget build(BuildContext context) {
/// ✅ FIX 1 — Only add sectors at root and their children with parent set.
final List> flatData = [];
// Flatten data
for (var sector in treemapData) {
// Add sector itself (Level 1)
flatData.add({
'id': sector.id,
'name': sector.name,
'value': sector.value,
'colorValue': sector.colorValue,
});
// Add children (Level 2)
if (sector.children != null && sector.children!.isNotEmpty) {
for (final company in sector.children!) {
flatData.add({
'id': company.id,
'name': company.name,
'parent': sector.id,
'value': company.value,
// ✅ Don't add colorValue here — prevents sector-level blend
});
}
}
}
/// ✅ FIX 2 — Map the data to Highcharts options
final List dataPoints =
flatData.map((item) {
final double colorValue =
(item['colorValue']?.toDouble() ?? 0.0).clamp(-10.0, 10.0);
// Auto color based on colorValue
String color;
if (colorValue < 0) {
final intensity = (colorValue / -10.0).clamp(0.0, 1.0);
color =
'#${(255).toRadixString(16)}${(80 + (100 * (1 - intensity))).round().toRadixString(16)}${(80 + (100 * (1 - intensity))).round().toRadixString(16)}';
} else if (colorValue > 0) {
final intensity = (colorValue / 10.0).clamp(0.0, 1.0);
color =
'#${(50 + (100 * (1 - intensity))).round().toRadixString(16)}${(200).toRadixString(16)}${(50 + (100 * (1 - intensity))).round().toRadixString(16)}';
} else {
color = '#cccccc';
}
return HighchartsTreemapSeriesDataOptions(
id: item['id'],
name: item['name'],
parent: item['parent'],
value: item['value']?.toDouble(),
colorValue: colorValue,
color: color,
accessibility: HighchartsTreemapSeriesDataAccessibilityOptions(
enabled: true,
description:
'${item['name']}: Market Cap \$${item['value']?.toStringAsFixed(0)}M, Change ${colorValue.toStringAsFixed(1)}%',
),
);
}).toList();
final HighchartsTreemapSeriesOptions treemapOptions =
HighchartsTreemapSeriesOptions(
layoutAlgorithm: 'squarified',
allowDrillToNode: true,
allowTraversingTree: true,
interactByLeaf: false,
borderWidth: 0,
colorByPoint: true,
states: HighchartsTreemapSeriesStatesOptions(
inactive: HighchartsSeriesStatesInactiveOptions(enabled: false
// 👈 disables the grey overlay
),
normal: HighchartsSeriesStatesNormalOptions(),
hover: HighchartsTreemapSeriesStatesHoverOptions(enabled: true)),
levels: [
HighchartsTreemapSeriesLevelsOptions(
level: 1,
layoutAlgorithm: 'squarified',
borderWidth: 2,
borderColor: '#101010',
dataLabels: HighchartsTreemapSeriesLevelsDataLabelsOptions(
enabled: true,
allowOverlap: true,
color: '#FFFFFF',
),
),
HighchartsTreemapSeriesLevelsOptions(
level: 2,
layoutAlgorithm: 'squarified',
borderWidth: 0,
borderColor: '',
dataLabels: HighchartsTreemapSeriesLevelsDataLabelsOptions(
enabled: false,
allowOverlap: true,
color: '#FFFFFF',
),
),
],
);
return HighchartsChart(
HighchartsOptions(
chart: HighchartsChartOptions(type: 'treemap'),
colorAxis: [
HighchartsColorAxisOptions(
min: -10, max: 10, maxColor: "green", minColor: "red")
],
plotOptions: HighchartsPlotOptions(
treemap: HighchartsTreemapSeriesOptions(
states: HighchartsTreemapSeriesStatesOptions(
inactive: HighchartsSeriesStatesInactiveOptions(enabled: false
// 👈 disables the grey overlay
),
normal: HighchartsSeriesStatesNormalOptions(),
hover:
HighchartsTreemapSeriesStatesHoverOptions(enabled: true)),
),
),
tooltip: HighchartsTooltipOptions(
pointFormat: '{point.name}
'
'Market Cap: \${point.value:,.0f}M
'
'Performance: {point.colorValue:.1f}%',
backgroundColor: 'black',
borderColor: 'gray',
borderRadius: 5,
),
series: [
HighchartsTreemapSeries(
name: 'Market Data',
dataPoints: dataPoints,
options: treemapOptions,
),
],
),
javaScriptModules: const [
'https://code.highcharts.com/highcharts.js',
'https://code.highcharts.com/modules/treemap.js',
],
);
}
}
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the provided SectorHeatmapChart snippet and reproduce the inactive-state behavior in Chrome using version 1.1.2. Inspect how the treemap states are passed through HighchartsTreemapSeriesOptions and plotOptions; done means setting inactive.enabled to false removes the inactive overlay.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart, flutter
- Domain
- data-visualization, frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100