Compare commits

...
Author SHA1 Message Date
Claude Code 2bea03b3aa fix(charts): fix Bubble chart crash and correct example's time_range to a year with real data
Two issues surfaced while verifying #42328's live thumbnail-capture work
against this example chart:

1. Bubble/transformProps.ts set `xAxis.interval` directly from the
   xAxisLabelInterval control ('auto'/'0'), but xAxis.interval forces
   echarts' IntervalScale into a fixed-tick-spacing mode that expects a
   number. This crashed the axis "nice" tick calculation for every
   bubble_v2 chart -- not just this example, any bubble chart with the
   control at its default. The interval belongs nested under axisLabel,
   where it only controls how many labels are skipped, matching how
   every other echarts chart in this codebase (e.g. Timeseries) wires it.
   There was no existing test coverage for this file; added one.

2. Once the crash was fixed, the chart rendered with zero visible
   bubbles: the previous commit's `time_range` (2014, matching the
   convention used by sibling examples on this dataset) has zero
   non-null SP_DYN_LE00_IN (life expectancy) values in this particular
   dataset. The original legacy chart's own choice of 2011 was
   deliberate -- that year has real data for all three metrics used.
2026-08-14 14:05:06 -07:00
Claude Code 6a029736be fix(examples): migrate Life Expectancy VS Rural % example off the removed legacy bubble viz_type
PR #41714 removed the legacy nvd3 chart pipeline and documented that
saved nvd3 Bubble charts auto-migrate to the ECharts Bubble Chart
(bubble_v2). That auto-migration runs against existing rows in an
already-populated metadata database (superset/migrations/shared/migrate_viz/processors.py),
not against the example YAML fixtures loaded fresh by `superset load-examples` --
so this example chart was left with `viz_type: bubble`, which has had zero
registered plugin since #41714 landed. Every fresh install loading examples
got a broken chart on the "World Bank's Data" dashboard.

Migrated params to bubble_v2's shape (adhoc-metric x/y/size instead of
legacy sum__ column-name shorthand, dropped legacy-only fields), matching
the working bubble_v2 example in featured_charts/charts/Bubble.yaml.
Verified against ImportV1ChartSchema and a full `superset db upgrade`.

Audited all 103 example chart YAMLs across superset/examples/ for any
other viz_type without a currently-registered plugin; this was the only one.
2026-08-13 22:52:33 -07:00
3 changed files with 108 additions and 18 deletions
@@ -0,0 +1,70 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { SqlaFormData } from '@superset-ui/core';
import transformProps from './transformProps';
import { EchartsBubbleChartProps } from './types';
const baseFormData: SqlaFormData = {
datasource: '1__table',
viz_type: 'bubble_v2',
entity: 'customer_name',
x: 'price',
y: 'sales',
size: 'count',
};
const baseChartProps = {
width: 400,
height: 400,
hooks: {},
queriesData: [
{
data: [
{ customer_name: 'A', price: 10, sales: 100, count: 5 },
{ customer_name: 'B', price: 20, sales: 200, count: 8 },
],
},
],
theme: { colorText: '#000' },
};
test('nests xAxisLabelInterval under axisLabel rather than the axis itself', () => {
// Regression test: xAxis.interval forces echarts' IntervalScale into a
// fixed-tick-spacing mode that expects a number and crashes on the
// 'auto'/'0' strings this control actually produces (observed as an
// uncaught assertion deep in echarts' axis "nice" tick calculation,
// reproducing on every dashboard bubble chart). The interval belongs on
// axisLabel, where it only controls how many labels are skipped.
const { echartOptions } = transformProps({
...baseChartProps,
formData: baseFormData,
} as unknown as EchartsBubbleChartProps);
expect((echartOptions.xAxis as any).interval).toBeUndefined();
expect((echartOptions.xAxis as any).axisLabel.interval).toBe('auto');
});
test('honors an explicit xAxisLabelInterval override', () => {
const { echartOptions } = transformProps({
...baseChartProps,
formData: { ...baseFormData, xAxisLabelInterval: '0' },
} as unknown as EchartsBubbleChartProps);
expect((echartOptions.xAxis as any).axisLabel.interval).toBe('0');
});
@@ -212,13 +212,16 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
const echartOptions: EChartsCoreOption = {
series,
xAxis: {
axisLabel: { formatter: xAxisFormatter, rotate: xAxisLabelRotation },
axisLabel: {
formatter: xAxisFormatter,
rotate: xAxisLabelRotation,
interval: xAxisLabelInterval,
},
splitLine: {
lineStyle: {
type: 'dashed',
},
},
interval: xAxisLabelInterval,
scale: true,
name: bubbleXAxisTitle,
nameLocation: 'middle',
@@ -41,27 +41,44 @@ params:
filterOptionName: 2745eae5
operator: NOT IN
subject: country_code
compare_lag: '10'
compare_suffix: o10Y
country_fieldtype: cca3
color_scheme: supersetColors
entity: country_name
granularity_sqla: year
groupby: []
limit: 0
markup_type: markdown
legendOrientation: top
legendType: scroll
max_bubble_size: '50'
row_limit: 50000
opacity: 0.6
order_desc: true
row_limit: 500
series: region
show_bubbles: true
since: '2011-01-01'
size: sum__SP_POP_TOTL
time_range: '2014-01-01 : 2014-01-02'
until: '2011-01-02'
viz_type: bubble
x: sum__SP_RUR_TOTL_ZS
y: sum__SP_DYN_LE00_IN
show_legend: true
size:
aggregate: SUM
column:
column_name: SP_POP_TOTL
expressionType: SIMPLE
label: SUM(SP_POP_TOTL)
optionName: metric_size_life_expectancy_vs_rural
time_range: '2011-01-01 : 2011-01-02'
tooltipSizeFormat: SMART_NUMBER
truncateXAxis: true
viz_type: bubble_v2
x:
aggregate: SUM
column:
column_name: SP_RUR_TOTL_ZS
expressionType: SIMPLE
label: SUM(SP_RUR_TOTL_ZS)
optionName: metric_x_life_expectancy_vs_rural
y:
aggregate: SUM
column:
column_name: SP_DYN_LE00_IN
expressionType: SIMPLE
label: SUM(SP_DYN_LE00_IN)
optionName: metric_y_life_expectancy_vs_rural
query_context: null
slice_name: Life Expectancy VS Rural %
uuid: c18faec9-ec43-4d36-8b66-4c8b1372020f
version: 1.0.0
viz_type: bubble
viz_type: bubble_v2