[charts] Add control to the axis highlight
The idea is to add an onXAxisInteraction that provides meaning full information about where the pointer is compared to x-axes.
Implementation
For now it's only trigger by pointerMove event. Which has a known limitation: It the developer has some logic that modifies the data the onXAxisInteraction will not be trigger by the modification.
For example, if the pointer moves over the last value of the x-axis. we call onXAxisInteraction with this data index.
When the last item get removed by some async call, the item does not exist anymore, and we end up in a weird situation.
A potential solution is to apply the same logic when updating axes: compute interaction values before/after the axis modification and trigger the onXAxisInteraction if needed (to explore)
DX
The onXAxisInteraction support multiple axes. That's not super useful for highlight that only accept one. But it will be usefull to control that axis tooltip.
The axis interaction contains both dataIndex and value. The usecases are the following:
- If axis has data, the dataIndex is the source of truth.
- If axis has no data (for example the y-axis on line chart, of any axis on scatter chart) the value is needed.
I'm not sure it's a good idea to have both. I'm thinking about only supporting the dataIndex, because axes without data are useless for the axis-tooltip. And the axis highlight is overcomplicated and wem behavior can be obtained by implementing the last demo of Custom components - Scales (Coordinate to value
)
Deploy preview: https://deploy-preview-17900--material-ui-x.netlify.app/
Updated pages:
Bundle size report
Total Size Change: 🔺+49KB(+0.37%) - Total Gzip Change: 🔺+15.7KB(+0.39%) Files: 122 total (0 added, 0 removed, 37 changed)
Show details for 100 more bundles (22 more not shown)
@mui/x-charts-pro/ChartContainerPro parsed: 🔺+3.88KB(+2.20%) gzip: 🔺+1.2KB(+2.16%) @mui/x-charts/ChartContainer parsed: 🔺+3.87KB(+2.64%) gzip: 🔺+1.08KB(+2.39%) @mui/x-charts/Gauge parsed: 🔺+3.76KB(+2.68%) gzip: 🔺+1.04KB(+2.37%) @mui/x-charts-pro/ChartDataProviderPro parsed: 🔺+3.75KB(+2.22%) gzip: 🔺+1.33KB(+2.50%) @mui/x-charts/ChartDataProvider parsed: 🔺+3.74KB(+2.68%) gzip: 🔺+1.11KB(+2.58%) @mui/x-charts-pro parsed: 🔺+2.4KB(+0.63%) gzip: 🔺+750B(+0.65%) @mui/x-charts parsed: 🔺+2.4KB(+0.79%) gzip: 🔺+755B(+0.83%) @mui/x-charts-pro/LineChartPro parsed: 🔺+2.34KB(+0.84%) gzip: 🔺+648B(+0.74%) @mui/x-charts/LineChart parsed: 🔺+2.34KB(+1.04%) gzip: 🔺+842B(+1.22%) @mui/x-charts/ScatterChart parsed: 🔺+2.15KB(+1.11%) gzip: 🔺+712B(+1.19%) @mui/x-charts-pro/BarChartPro parsed: 🔺+2.15KB(+0.78%) gzip: 🔺+617B(+0.72%) @mui/x-charts-pro/FunnelChart parsed: 🔺+2.15KB(+0.88%) gzip: 🔺+772B(+1.03%) @mui/x-charts-pro/ScatterChartPro parsed: 🔺+2.15KB(+0.80%) gzip: 🔺+736B(+0.87%) @mui/x-charts/BarChart parsed: 🔺+2.15KB(+1.03%) gzip: 🔺+622B(+0.96%) @mui/x-charts/SparkLineChart parsed: 🔺+2.07KB(+0.99%) gzip: 🔺+635B(+0.99%) @mui/x-charts-pro/PieChartPro parsed: 🔺+1.42KB(+0.61%) gzip: 🔺+490B(+0.68%) @mui/x-charts/PieChart parsed: 🔺+1.41KB(+0.72%) gzip: 🔺+436B(+0.72%) @mui/x-charts-pro/Heatmap parsed: 🔺+1.29KB(+0.56%) gzip: 🔺+386B(+0.54%) @mui/x-charts/RadarChart parsed: 🔺+1.28KB(+0.67%) gzip: 🔺+524B(+0.89%) @mui/x-charts-pro/RadarChartPro parsed: 🔺+1.28KB(+0.63%) gzip: 🔺+719B(+1.14%) @mui/x-charts/ChartsAxisHighlight parsed: 🔺+778B(+1.27%) gzip: 🔺+205B(+0.95%) @mui/x-charts/ChartsTooltip parsed: 🔺+226B(+0.29%) gzip: 🔺+71B(+0.27%) @mui/x-charts-pro/ChartsToolbarPro parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts-pro/ChartZoomSlider parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsAxis parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsClipPath parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsGrid parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsLabel parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsLegend parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsLocalizationProvider parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsOverlay parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsReferenceLine parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsSurface parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsText parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsXAxis parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/ChartsYAxis parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-charts/Toolbar parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-data-grid parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-data-grid-premium parsed: 0B(0.00%) gzip: ▼-1B(0.00%) @mui/x-data-grid-premium/DataGridPremium parsed: 0B(0.00%) gzip: ▼-2B(0.00%) @mui/x-data-grid-pro parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-data-grid-pro/DataGridPro parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-data-grid/DataGrid parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/AdapterDateFns parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/AdapterDateFnsJalali parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/AdapterDayjs parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/AdapterLuxon parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/AdapterMoment parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/AdapterMomentHijri parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/AdapterMomentJalaali parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/DateRangeCalendar parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/DateRangePicker parsed: 0B(0.00%) gzip: ▼-3B(-0.01%) @mui/x-date-pickers-pro/DateRangePickerDay parsed: 0B(0.00%) gzip: 🔺+3B(+0.04%) @mui/x-date-pickers-pro/DateRangePickerDay2 parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/DateTimeRangePicker parsed: 0B(0.00%) gzip: ▼-1B(0.00%) @mui/x-date-pickers-pro/DesktopDateRangePicker parsed: 0B(0.00%) gzip: ▼-1B(0.00%) @mui/x-date-pickers-pro/DesktopDateTimeRangePicker parsed: 0B(0.00%) gzip: ▼-1B(0.00%) @mui/x-date-pickers-pro/DesktopTimeRangePicker parsed: 0B(0.00%) gzip: ▼-1B(0.00%) @mui/x-date-pickers-pro/LocalizationProvider parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/MobileDateRangePicker parsed: 0B(0.00%) gzip: ▼-3B(-0.01%) @mui/x-date-pickers-pro/MobileDateTimeRangePicker parsed: 0B(0.00%) gzip: ▼-1B(0.00%) @mui/x-date-pickers-pro/MobileTimeRangePicker parsed: 0B(0.00%) gzip: ▼-1B(0.00%) @mui/x-date-pickers-pro/MultiInputDateRangeField parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/MultiInputDateTimeRangeField parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/MultiInputTimeRangeField parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/PickersRangeCalendarHeader parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/SingleInputDateRangeField parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/SingleInputDateTimeRangeField parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/SingleInputTimeRangeField parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers-pro/StaticDateRangePicker parsed: 0B(0.00%) gzip: ▼-1B(0.00%) @mui/x-date-pickers-pro/TimeRangePicker parsed: 0B(0.00%) gzip: ▼-1B(0.00%) @mui/x-date-pickers/AdapterDateFns parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/AdapterDateFnsBase parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/AdapterDateFnsJalali parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/AdapterDayjs parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/AdapterLuxon parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/AdapterMoment parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/AdapterMomentHijri parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/AdapterMomentJalaali parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/DateCalendar parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/DateField parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/DatePicker parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/DateTimeField parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/DateTimePicker parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/DayCalendarSkeleton parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/DesktopDatePicker parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/DesktopDateTimePicker parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/DesktopTimePicker parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/DigitalClock parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/LocalizationProvider parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/MobileDatePicker parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/MobileDateTimePicker parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/MobileTimePicker parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/MonthCalendar parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/MultiSectionDigitalClock parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/PickerDay2 parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/PickersActionBar parsed: 0B(0.00%) gzip: 0B(0.00%) @mui/x-date-pickers/PickersCalendarHeader parsed: 0B(0.00%) gzip: 0B(0.00%)
Generated by :no_entry_sign: dangerJS against b149f2ae3f9c917b02c38eeb4b0fe6c7baa8aceb
CodSpeed Performance Report
Merging #17900 will degrade performances by 11.34%
Comparing alexfauquette:test-axis-highlight (b149f2a) with master (ed7604e)
Summary
❌ 1 regressions
✅ 9 untouched benchmarks
:warning: Please fix the performance issues or acknowledge them on CodSpeed.
Benchmarks breakdown
| Benchmark | BASE |
HEAD |
Change | |
|---|---|---|---|---|
| ❌ | ScatterChartPro with big data amount |
393.6 ms | 444 ms | -11.34% |
I think I would rather have a more generic api, like onAxisHighlightChange and highlightedAxes, where the identifier actually includes the axis dimension as a part of it.
We could do it, if we restrict ourself to axes with a data attribute. Otherwise the devs will receive a bunch of update to ignore. Each time the pointe rmoves along the y-axis on a line chart, there is an update 🙈
This pull request has conflicts, please resolve those before we can evaluate the pull request.
Based on feedback, I went with the following DX
- The
highlightedAxis={{ direction, axisId, dataIndex}}which is less flexible but already cover 99% of the usecases. It make sure only axes the adataproperty can be hihlighted. - The callback is now
onAxisInteraction({ direction, axisId, dataIndex}[]). It's also only taking care of axes withdataattribute.
The callback is get an array, because I plan to use the same one for the tooltip control. And the tooltip is able to support multiple axes so we will need to get an access to all of them
This pull request has conflicts, please resolve those before we can evaluate the pull request.
This pull request has conflicts, please resolve those before we can evaluate the pull request.
This pull request has conflicts, please resolve those before we can evaluate the pull request.