@@ -80,6 +80,81 @@ describe("parseData", () => {
8080 const sampleData = JSON . stringify ( [ { y : [ 5 ] } ] ) ;
8181 expect ( parseData ( staticData , attributeData , sampleData ) ) . toEqual ( [ { type : "line" , x : [ 1 ] , y : [ 5 ] } ] ) ;
8282 } ) ;
83+
84+ describe ( "deep merge behavior" , ( ) => {
85+ it ( "deeply merges nested marker objects" , ( ) => {
86+ const staticData = JSON . stringify ( [
87+ { type : "bar" , marker : { color : "red" , size : 10 , line : { width : 2 } } }
88+ ] ) ;
89+ const attributeData = JSON . stringify ( [ { marker : { symbol : "circle" , line : { color : "blue" } } } ] ) ;
90+ expect ( parseData ( staticData , attributeData ) ) . toEqual ( [
91+ {
92+ type : "bar" ,
93+ marker : {
94+ color : "red" ,
95+ size : 10 ,
96+ symbol : "circle" ,
97+ line : { width : 2 , color : "blue" }
98+ }
99+ }
100+ ] ) ;
101+ } ) ;
102+
103+ it ( "deeply merges multiple traces with nested objects" , ( ) => {
104+ const staticData = JSON . stringify ( [
105+ { type : "scatter" , marker : { color : "red" } , line : { width : 2 } } ,
106+ { type : "bar" , marker : { size : 10 } }
107+ ] ) ;
108+ const attributeData = JSON . stringify ( [
109+ { marker : { symbol : "diamond" } , line : { dash : "dot" } } ,
110+ { marker : { color : "blue" } }
111+ ] ) ;
112+ expect ( parseData ( staticData , attributeData ) ) . toEqual ( [
113+ {
114+ type : "scatter" ,
115+ marker : { color : "red" , symbol : "diamond" } ,
116+ line : { width : 2 , dash : "dot" }
117+ } ,
118+ {
119+ type : "bar" ,
120+ marker : { size : 10 , color : "blue" }
121+ }
122+ ] ) ;
123+ } ) ;
124+
125+ it ( "attribute arrays replace static arrays (not concatenate)" , ( ) => {
126+ const staticData = JSON . stringify ( [ { x : [ 1 , 2 , 3 ] , y : [ 4 , 5 , 6 ] } ] ) ;
127+ const attributeData = JSON . stringify ( [ { x : [ 10 , 20 ] } ] ) ;
128+ expect ( parseData ( staticData , attributeData ) ) . toEqual ( [ { x : [ 10 , 20 ] , y : [ 4 , 5 , 6 ] } ] ) ;
129+ } ) ;
130+
131+ it ( "deeply merges font and other nested layout-like properties in traces" , ( ) => {
132+ const staticData = JSON . stringify ( [
133+ {
134+ type : "scatter" ,
135+ textfont : { family : "Arial" , size : 12 } ,
136+ hoverlabel : { bgcolor : "white" , font : { size : 10 } }
137+ }
138+ ] ) ;
139+ const attributeData = JSON . stringify ( [
140+ {
141+ textfont : { color : "black" } ,
142+ hoverlabel : { bordercolor : "gray" , font : { family : "Helvetica" } }
143+ }
144+ ] ) ;
145+ expect ( parseData ( staticData , attributeData ) ) . toEqual ( [
146+ {
147+ type : "scatter" ,
148+ textfont : { family : "Arial" , size : 12 , color : "black" } ,
149+ hoverlabel : {
150+ bgcolor : "white" ,
151+ bordercolor : "gray" ,
152+ font : { size : 10 , family : "Helvetica" }
153+ }
154+ }
155+ ] ) ;
156+ } ) ;
157+ } ) ;
83158} ) ;
84159
85160describe ( "parseLayout" , ( ) => {
@@ -102,6 +177,73 @@ describe("parseLayout", () => {
102177 const sampleLayout = JSON . stringify ( { title : "Sample" } ) ;
103178 expect ( parseLayout ( undefined , attributeLayout , sampleLayout ) ) . toEqual ( { title : "Attr" } ) ;
104179 } ) ;
180+
181+ describe ( "deep merge behavior" , ( ) => {
182+ it ( "deeply merges nested font objects" , ( ) => {
183+ const staticLayout = JSON . stringify ( {
184+ title : { text : "Chart Title" , font : { family : "Arial" , size : 16 } }
185+ } ) ;
186+ const attributeLayout = JSON . stringify ( {
187+ title : { font : { color : "blue" , weight : "bold" } }
188+ } ) ;
189+ expect ( parseLayout ( staticLayout , attributeLayout ) ) . toEqual ( {
190+ title : {
191+ text : "Chart Title" ,
192+ font : { family : "Arial" , size : 16 , color : "blue" , weight : "bold" }
193+ }
194+ } ) ;
195+ } ) ;
196+
197+ it ( "deeply merges xaxis and yaxis configurations" , ( ) => {
198+ const staticLayout = JSON . stringify ( {
199+ xaxis : { title : "X Axis" , tickfont : { size : 12 } , gridcolor : "lightgray" } ,
200+ yaxis : { title : "Y Axis" , showgrid : true }
201+ } ) ;
202+ const attributeLayout = JSON . stringify ( {
203+ xaxis : { tickfont : { color : "black" } , range : [ 0 , 100 ] } ,
204+ yaxis : { gridcolor : "gray" }
205+ } ) ;
206+ expect ( parseLayout ( staticLayout , attributeLayout ) ) . toEqual ( {
207+ xaxis : {
208+ title : "X Axis" ,
209+ tickfont : { size : 12 , color : "black" } ,
210+ gridcolor : "lightgray" ,
211+ range : [ 0 , 100 ]
212+ } ,
213+ yaxis : { title : "Y Axis" , showgrid : true , gridcolor : "gray" }
214+ } ) ;
215+ } ) ;
216+
217+ it ( "deeply merges legend configuration" , ( ) => {
218+ const staticLayout = JSON . stringify ( {
219+ legend : { x : 0.5 , y : 1 , font : { size : 10 } , bgcolor : "white" }
220+ } ) ;
221+ const attributeLayout = JSON . stringify ( {
222+ legend : { orientation : "h" , font : { family : "Helvetica" } }
223+ } ) ;
224+ expect ( parseLayout ( staticLayout , attributeLayout ) ) . toEqual ( {
225+ legend : {
226+ x : 0.5 ,
227+ y : 1 ,
228+ font : { size : 10 , family : "Helvetica" } ,
229+ bgcolor : "white" ,
230+ orientation : "h"
231+ }
232+ } ) ;
233+ } ) ;
234+
235+ it ( "attribute arrays replace static arrays in layout" , ( ) => {
236+ const staticLayout = JSON . stringify ( {
237+ annotations : [ { text : "Note 1" } , { text : "Note 2" } ]
238+ } ) ;
239+ const attributeLayout = JSON . stringify ( {
240+ annotations : [ { text : "New Note" } ]
241+ } ) ;
242+ expect ( parseLayout ( staticLayout , attributeLayout ) ) . toEqual ( {
243+ annotations : [ { text : "New Note" } ]
244+ } ) ;
245+ } ) ;
246+ } ) ;
105247} ) ;
106248
107249describe ( "parseConfig" , ( ) => {
0 commit comments