11import * as React from 'react' ;
22import { ScatterChart , ScatterMarkerProps } from '@mui/x-charts/ScatterChart' ;
3+ import { ChartsTooltipContainer , useItemTooltip } from '@mui/x-charts/ChartsTooltip' ;
4+ import { styled } from '@mui/material/styles' ;
35import Stack from '@mui/material/Stack' ;
6+ import Box from '@mui/material/Box' ;
7+ import Divider from '@mui/material/Divider' ;
48import Typography from '@mui/material/Typography' ;
59import { useZAxis } from '@mui/x-charts-premium/hooks' ;
610import { irisData } from '../dataset/irisDataset' ;
@@ -9,6 +13,19 @@ const species = ['Setosa', 'Versicolor', 'Virginica'];
913const speciesColors = [ '#2e7d32' , '#ed6c02' , '#9c27b0' ] ;
1014const speciesPredictionColors = [ '#5aa35e' , '#be7f4b' , '#ba68c9' ] ;
1115
16+ const TooltipPaper = styled ( 'div' , {
17+ name : 'Tooltip' ,
18+ slot : 'Paper' ,
19+ } ) ( ( { theme } ) => {
20+ return {
21+ padding : theme . spacing ( 1 ) ,
22+ backgroundColor : ( theme . vars || theme ) . palette . background . paper ,
23+ color : ( theme . vars || theme ) . palette . text . primary ,
24+ borderRadius : ( theme . vars || theme ) . shape ?. borderRadius ,
25+ border : `solid ${ ( theme . vars || theme ) . palette . divider } 1px` ,
26+ } ;
27+ } ) ;
28+
1229function IrisMarker ( props : ScatterMarkerProps ) {
1330 const { x, y, color, size, isHighlighted, isFaded, dataIndex, ...other } = props ;
1431
@@ -51,6 +68,86 @@ function IrisAnnotation() {
5168 ) ;
5269}
5370
71+ function CustomTooltip ( ) {
72+ const item = useItemTooltip < 'scatter' > ( ) ;
73+
74+ function numberFormatter ( value : number | string | undefined ) {
75+ if ( typeof value === 'number' ) {
76+ return new Intl . NumberFormat ( 'en-US' ) . format ( value ) ;
77+ }
78+ return String ( value ) ;
79+ }
80+
81+ // Get the full data item from irisData using dataIndex from identifier
82+ const dataIndex = item ?. identifier . dataIndex ;
83+ const dataItem = dataIndex !== undefined ? irisData [ dataIndex ] : null ;
84+
85+ if ( ! item || ! dataItem ) {
86+ return null ;
87+ }
88+
89+ return (
90+ < ChartsTooltipContainer trigger = "item" >
91+ < TooltipPaper >
92+ < Box
93+ sx = { { display : 'flex' , flexDirection : 'row' , alignItems : 'center' , mb : 1 } }
94+ >
95+ < Box
96+ sx = { {
97+ width : 20 ,
98+ height : 20 ,
99+ backgroundColor : item ?. color ,
100+ borderRadius : 1 ,
101+ mr : 2 ,
102+ } }
103+ />
104+ < Typography sx = { { fontWeight : 600 } } > { dataItem . species } </ Typography >
105+ </ Box >
106+ < Divider sx = { { my : 1 } } />
107+ < Box sx = { { display : 'grid' , gridTemplateColumns : '1fr' , gap : 0.75 } } >
108+ < Box sx = { { display : 'flex' , justifyContent : 'space-between' } } >
109+ < Typography variant = "caption" > Sepal Length:</ Typography >
110+ < Typography variant = "caption" sx = { { fontWeight : 500 } } >
111+ { numberFormatter ( dataItem . sepalLength ) } cm
112+ </ Typography >
113+ </ Box >
114+ < Box sx = { { display : 'flex' , justifyContent : 'space-between' } } >
115+ < Typography variant = "caption" > Sepal Width:</ Typography >
116+ < Typography variant = "caption" sx = { { fontWeight : 500 } } >
117+ { numberFormatter ( dataItem . sepalWidth ) } cm
118+ </ Typography >
119+ </ Box >
120+ < Box sx = { { display : 'flex' , justifyContent : 'space-between' } } >
121+ < Typography variant = "caption" > Petal Length:</ Typography >
122+ < Typography variant = "caption" sx = { { fontWeight : 500 } } >
123+ { numberFormatter ( dataItem . petalLength ) } cm
124+ </ Typography >
125+ </ Box >
126+ < Box sx = { { display : 'flex' , justifyContent : 'space-between' } } >
127+ < Typography variant = "caption" > Petal Width:</ Typography >
128+ < Typography variant = "caption" sx = { { fontWeight : 500 } } >
129+ { numberFormatter ( dataItem . petalWidth ) } cm
130+ </ Typography >
131+ </ Box >
132+ < Divider sx = { { my : 0.5 } } />
133+ < Box sx = { { display : 'flex' , justifyContent : 'space-between' } } >
134+ < Typography variant = "caption" > Predicted:</ Typography >
135+ < Typography variant = "caption" sx = { { fontWeight : 500 } } >
136+ { dataItem . prediction }
137+ </ Typography >
138+ </ Box >
139+ < Box sx = { { display : 'flex' , justifyContent : 'space-between' } } >
140+ < Typography variant = "caption" > Confidence:</ Typography >
141+ < Typography variant = "caption" sx = { { fontWeight : 500 } } >
142+ { numberFormatter ( dataItem . confidence ) } %
143+ </ Typography >
144+ </ Box >
145+ </ Box >
146+ </ TooltipPaper >
147+ </ ChartsTooltipContainer >
148+ ) ;
149+ }
150+
54151export default function ScatterZAxis ( ) {
55152 return (
56153 < Stack sx = { { width : '100%' } } >
@@ -109,7 +206,7 @@ export default function ScatterZAxis() {
109206 } ,
110207 } ,
111208 ] }
112- slots = { { marker : IrisMarker } }
209+ slots = { { marker : IrisMarker , tooltip : CustomTooltip } }
113210 > </ ScatterChart >
114211 < IrisAnnotation />
115212 </ Stack >
0 commit comments