@@ -42,9 +42,10 @@ const PALETTE = [
4242 "#8c564b" , "#e377c2" , "#7f7f7f" , "#bcbd22" , "#17becf" ,
4343] ;
4444
45- function formatSeriesData ( seriesData : Series [ ] ) {
45+ function formatSeriesData ( seriesData : Series [ ] , defaultType : string ) {
4646 return ( seriesData || [ ] ) . map ( ( series , index ) => {
4747 const color = series . color || PALETTE [ index % PALETTE . length ] ;
48+ const type = series . type || defaultType || "line" ;
4849
4950 let data : unknown ;
5051 if ( series . data && series . data . length > 0 ) {
@@ -62,19 +63,19 @@ function formatSeriesData(seriesData: Series[]) {
6263 data,
6364 borderColor : color ,
6465 backgroundColor : color + "33" ,
65- type : series . type || "line" ,
66+ type,
6667 fill : series . fill !== undefined ? series . fill : false ,
6768 tension : series . tension ?? 0.1 ,
6869 pointRadius : series . pointRadius !== undefined ? series . pointRadius : 3 ,
6970 pointHoverRadius : 5 ,
7071 borderWidth : series . borderWidth || 2 ,
7172 } ;
7273
73- if ( series . type === "scatter" ) {
74+ if ( type === "scatter" ) {
7475 dataset . showLine = false ;
7576 dataset . pointRadius = series . pointRadius || 5 ;
7677 }
77- if ( series . type === "bar" ) {
78+ if ( type === "bar" ) {
7879 dataset . backgroundColor = color + "80" ;
7980 }
8081 return dataset ;
@@ -146,31 +147,33 @@ function render({ model, el }: RenderProps<ChartModel>): () => void {
146147 return options ;
147148 }
148149
150+ function build ( ) : void {
151+ chart ?. destroy ( ) ;
152+ chart = new Chart ( canvas , {
153+ type : ( model . get ( "chart_type" ) || "line" ) as never ,
154+ data : { datasets : formatSeriesData ( model . get ( "series_data" ) , model . get ( "chart_type" ) ) as never } ,
155+ options : buildOptions ( ) as never ,
156+ } ) ;
157+ }
158+
149159 function createOrUpdate ( ) : void {
150- const datasets = formatSeriesData ( model . get ( "series_data" ) ) ;
151- const options = buildOptions ( ) ;
152160 if ( ! chart ) {
153- chart = new Chart ( canvas , {
154- type : ( model . get ( "chart_type" ) || "line" ) as never ,
155- data : { datasets : datasets as never } ,
156- options : options as never ,
157- } ) ;
161+ build ( ) ;
158162 } else {
159- chart . data = { datasets : datasets as never } ;
160- chart . options = options as never ;
163+ chart . data = { datasets : formatSeriesData ( model . get ( "series_data" ) , model . get ( "chart_type" ) ) as never } ;
164+ chart . options = buildOptions ( ) as never ;
161165 chart . update ( ) ;
162166 }
163167 }
164168
165- if ( ( model . get ( "series_data" ) || [ ] ) . length > 0 ) createOrUpdate ( ) ;
169+ if ( ( model . get ( "series_data" ) || [ ] ) . length > 0 ) build ( ) ;
166170
167171 // NOTE: register one listener per trait — the static-export model emitter does
168172 // not support space-separated event names (see core's onChanges docstring).
169173 onChanges (
170174 model ,
171175 [
172176 "series_data" ,
173- "chart_type" ,
174177 "chart_options" ,
175178 "animation_enabled" ,
176179 "tooltips_enabled" ,
@@ -182,6 +185,10 @@ function render({ model, el }: RenderProps<ChartModel>): () => void {
182185 createOrUpdate ,
183186 ) ;
184187
188+ // Switching the default series type requires a fresh chart — Chart.js won't
189+ // re-type existing datasets via update().
190+ onChanges ( model , [ "chart_type" ] , build ) ;
191+
185192 onChanges ( model , [ "width" , "height" ] , ( ) => {
186193 container . style . width = `${ model . get ( "width" ) } px` ;
187194 container . style . height = `${ model . get ( "height" ) } px` ;
0 commit comments