@@ -46,35 +46,45 @@ sqlpage_chart = (() => {
4646 ] ) ,
4747 ) ;
4848
49- /** @typedef { { [name:string]: {data:{x:number,y:number}[], name:string} } } Series */
49+ /** @typedef { { [name:string]: {data:{x:number|string|Date ,y:number}[], name:string} } } Series */
5050
5151 /**
52- * @param {Series } series
53- * @returns {Series } */
52+ * Aligns series data points by their x-axis categories, ensuring all series have data points
53+ * for each unique category. Missing values are filled with zeros. Categories are sorted.
54+ *
55+ * @example
56+ * // Input series:
57+ * const series = [
58+ * { name: "A", data: [{x: "Jan", y: 10}, {x: "Mar", y: 30}] },
59+ * { name: "B", data: [{x: "Jan", y: 20}, {x: "Feb", y: 25}] }
60+ * ];
61+ *
62+ * // Output after align_categories:
63+ * // [
64+ * // { name: "A", data: [{x: "Feb", y: 0}, {x: "Jan", y: 10}, {x: "Mar", y: 30}] },
65+ * // { name: "B", data: [{x: "Feb", y: 25}, {x: "Jan", y: 20}, {x: "Mar", y: 0}] }
66+ * // ]
67+ *
68+ * @param {Series[string][] } series - Array of series objects, each containing name and data points
69+ * @returns {Series[string][] } Aligned series with consistent categories across all series
70+ */
5471 function align_categories ( series ) {
55- const new_series = series . map ( ( s ) => ( { name : s . name , data : [ ] } ) ) ;
56- let category = null ;
57- do {
58- category = null ;
59- series . forEach ( ( s , s_i ) => {
60- const point = s . data [ 0 ] ;
61- let new_point = { x : category , y : 0 } ;
62- if ( point ) {
63- if ( category == null ) category = point . x ;
64- if ( category === point . x ) {
65- new_point = s . data . shift ( ) ;
66- }
67- }
68- new_series [ s_i ] . data . push ( new_point ) ;
69- } ) ;
70- for ( const s of new_series ) {
71- s . data [ s . data . length - 1 ] . x = category ;
72- }
73- } while ( category != null ) ;
74- for ( const s of new_series ) {
75- s . data . pop ( ) ;
76- }
77- return new_series ;
72+ // Collect all unique categories
73+ const categories = new Set ( series . flatMap ( s => s . data . map ( p => p . x ) ) ) ;
74+ const sortedCategories = Array . from ( categories ) . sort ( ) ;
75+
76+ // Create a map of category -> value for each series
77+ return series . map ( s => {
78+ const valueMap = new Map ( s . data . map ( point => [ point . x , point . y ] ) ) ;
79+
80+ return {
81+ name : s . name ,
82+ data : sortedCategories . map ( category => ( {
83+ x : category ,
84+ y : valueMap . get ( category ) || 0
85+ } ) )
86+ } ;
87+ } ) ;
7888 }
7989
8090 /** @param {HTMLElement } c */
@@ -155,7 +165,7 @@ sqlpage_chart = (() => {
155165 ? ( _val , { seriesIndex, w } ) => w . config . series [ seriesIndex ] . name
156166 : data . type === "pie"
157167 ? ( value , { seriesIndex, w } ) =>
158- `${ w . config . labels [ seriesIndex ] } : ${ value . toFixed ( ) } %`
168+ `${ w . config . labels [ seriesIndex ] } : ${ value . toFixed ( ) } %`
159169 : ( value ) => value . toLocaleString ( ) ,
160170 } ,
161171 fill : {
@@ -235,6 +245,7 @@ sqlpage_chart = (() => {
235245 series,
236246 } ;
237247 if ( labels ) options . labels = labels ;
248+ console . log ( "Rendering chart" , options ) ;
238249 const chart = new ApexCharts ( chartContainer , options ) ;
239250 chart . render ( ) ;
240251 if ( window . charts ) window . charts . push ( chart ) ;
0 commit comments