@@ -64,6 +64,122 @@ function renderTraceIcon(trace, prefix = 'Plot') {
6464 : PlotlyIcons . PlotLineIcon ;
6565}
6666
67+ function transpose ( originalArray ) {
68+ // if we want to transpose a uni dimensional array
69+ if ( originalArray . every ( a => ! Array . isArray ( a ) ) ) {
70+ return originalArray . map ( a => [ a ] ) ;
71+ }
72+
73+ let longestArrayItem = Array . isArray ( originalArray [ 0 ] )
74+ ? originalArray [ 0 ] . length
75+ : 1 ;
76+
77+ originalArray . forEach ( a => {
78+ // if it's not an array, it's a string
79+ const length = Array . isArray ( a ) ? a . length : 1 ;
80+ if ( length > longestArrayItem ) {
81+ longestArrayItem = length ;
82+ }
83+ } ) ;
84+
85+ const newArray = new Array ( longestArrayItem ) ;
86+
87+ for ( let outerIndex = 0 ; outerIndex < originalArray . length ; outerIndex ++ ) {
88+ if ( ! Array . isArray ( originalArray [ outerIndex ] ) ) {
89+ originalArray [ outerIndex ] = [ originalArray [ outerIndex ] ] ;
90+ }
91+
92+ for ( let innerIndex = 0 ; innerIndex < longestArrayItem ; innerIndex ++ ) {
93+ // ensure we have an array to push to
94+ if ( ! Array . isArray ( newArray [ innerIndex ] ) ) {
95+ newArray [ innerIndex ] = [ ] ;
96+ }
97+
98+ const value = originalArray [ outerIndex ] [ innerIndex ]
99+ ? originalArray [ outerIndex ] [ innerIndex ]
100+ : null ;
101+ newArray [ innerIndex ] . push ( value ) ;
102+ }
103+ }
104+
105+ return newArray ;
106+ }
107+
108+ const specialTableCase = ( traceType , srcAttributePath ) => {
109+ /* Just more user friendly
110+ * Table traces have many configuration options,
111+ * The below attributes can be 2d or 1d and will affect the plot differently
112+ * EX:
113+ * header.values = ['Jan', 'Feb', 'Mar'] => will put data in a row
114+ * header.values = [['Jan', 1], ['Feb', 2], ['Mar', 3]] => will create 3 columns
115+ * 1d arrays affect columns
116+ * 2d arrays affect rows within each column
117+ */
118+ return (
119+ traceType === 'table' &&
120+ [
121+ 'header.valuessrc' ,
122+ 'header.font.colorsrc' ,
123+ 'header.font.sizesrc' ,
124+ 'header.fill.colorsrc' ,
125+ 'columnwidthsrc' ,
126+ ] . some ( a => srcAttributePath . endsWith ( a ) )
127+ ) ;
128+ } ;
129+
130+ function maybeTransposeData ( data , srcAttributePath , traceType ) {
131+ if ( ! data || ( Array . isArray ( data ) && data . length === 0 ) ) {
132+ return null ;
133+ }
134+
135+ const isTransposable2DArray =
136+ srcAttributePath . endsWith ( 'zsrc' ) &&
137+ [
138+ 'contour' ,
139+ 'contourgl' ,
140+ 'heatmap' ,
141+ 'heatmapgl' ,
142+ 'surface' ,
143+ 'carpet' ,
144+ 'contourcarpet' ,
145+ ] . includes ( traceType ) ;
146+
147+ if ( isTransposable2DArray ) {
148+ return transpose ( data ) ;
149+ }
150+
151+ if (
152+ specialTableCase ( traceType , srcAttributePath ) &&
153+ Array . isArray ( data [ 0 ] ) &&
154+ data . length === 1
155+ ) {
156+ return data [ 0 ] ;
157+ }
158+
159+ return data ;
160+ }
161+
162+ function maybeAdjustSrc ( src , srcAttributePath , traceType , config ) {
163+ if ( ! src || ( Array . isArray ( src ) && src . length === 0 ) ) {
164+ return null ;
165+ }
166+
167+ if ( Array . isArray ( src ) ) {
168+ if ( src . length > 1 && config && config . joinSrcs ) {
169+ return config . joinSrcs ( src , traceType ) ;
170+ }
171+
172+ if (
173+ ( specialTableCase ( traceType , srcAttributePath ) && src . length === 1 ) ||
174+ src . length === 1
175+ ) {
176+ return src [ 0 ] ;
177+ }
178+ }
179+
180+ return src ;
181+ }
182+
67183export {
68184 axisIdToAxisName ,
69185 bem ,
@@ -96,11 +212,14 @@ export {
96212 isPlainObject ,
97213 localize ,
98214 localizeString ,
215+ maybeAdjustSrc ,
216+ maybeTransposeData ,
99217 plotlyTraceToCustomTrace ,
100218 renderTraceIcon ,
101219 unpackPlotProps ,
102220 walkObject ,
103221 tooLight ,
104222 striptags ,
105223 traceTypeToAxisType ,
224+ transpose ,
106225} ;
0 commit comments