99
1010'use strict' ;
1111
12+ var isNumeric = require ( 'fast-isnumeric' ) ;
13+ var tinycolor = require ( 'tinycolor2' ) ;
14+
1215var Lib = require ( '../../lib' ) ;
1316var Color = require ( '../../components/color' ) ;
1417
@@ -23,6 +26,125 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
2326 return Lib . coerce ( traceIn , traceOut , attributes , attr , dflt ) ;
2427 }
2528
29+ function coerceEnumerated ( attributeDefinition , value , defaultValue ) {
30+ if ( attributeDefinition . coerceNumber ) value = + value ;
31+
32+ if ( attributeDefinition . values . indexOf ( value ) !== - 1 ) return value ;
33+
34+ return ( defaultValue !== undefined ) ?
35+ defaultValue :
36+ attributeDefinition . dflt ;
37+ }
38+
39+ function coerceString ( attributeDefinition , value , defaultValue ) {
40+ if ( typeof value === 'string' ) {
41+ if ( value || ! attributeDefinition . noBlank ) return value ;
42+ }
43+ else if ( typeof value === 'number' ) {
44+ if ( ! attributeDefinition . strict ) return String ( value ) ;
45+ }
46+
47+ return ( defaultValue !== undefined ) ?
48+ defaultValue :
49+ attributeDefinition . dflt ;
50+ }
51+
52+ function coerceNumber ( attributeDefinition , value , defaultValue ) {
53+ if ( isNumeric ( value ) ) {
54+ value = + value ;
55+
56+ var min = attributeDefinition . min ,
57+ max = attributeDefinition . max ,
58+ isOutOfBounds = ( min !== undefined && value < min ) ||
59+ ( max !== undefined && value > max ) ;
60+
61+ if ( ! isOutOfBounds ) return value ;
62+ }
63+
64+ return ( defaultValue !== undefined ) ?
65+ defaultValue :
66+ attributeDefinition . dflt ;
67+ }
68+
69+ function coerceColor ( attributeDefinition , value , defaultValue ) {
70+ if ( tinycolor ( value ) . isValid ( ) ) return value ;
71+
72+ return ( defaultValue !== undefined ) ?
73+ defaultValue :
74+ attributeDefinition . dflt ;
75+ }
76+
77+ function coerceFont ( attributeDefinition , value , defaultValue ) {
78+ value = value || { } ;
79+ defaultValue = defaultValue || { } ;
80+
81+ return {
82+ family : coerceString (
83+ attributeDefinition . family , value . family , defaultValue . family ) ,
84+ size : coerceNumber (
85+ attributeDefinition . size , value . size , defaultValue . size ) ,
86+ color : coerceColor (
87+ attributeDefinition . color , value . color , defaultValue . color )
88+ } ;
89+ }
90+
91+ function coerceArray ( attribute , coerceFunction , defaultValue , defaultValue2 ) {
92+ var attributeDefinition = attributes [ attribute ] ,
93+ arrayOk = attributeDefinition . arrayOk ,
94+ inValue = traceIn [ attribute ] ,
95+ inValueIsArray = Array . isArray ( inValue ) ,
96+ defaultValueIsArray = Array . isArray ( defaultValue ) ,
97+ outValue ,
98+ i ;
99+
100+ // Case: inValue and defaultValue not treated as arrays
101+ if ( ! arrayOk || ( ! inValueIsArray && ! defaultValueIsArray ) ) {
102+ outValue = coerceFunction (
103+ attributeDefinition , inValue , defaultValue ) ;
104+ traceOut [ attribute ] = outValue ;
105+ return outValue ;
106+ }
107+
108+ // Coerce into an array
109+ outValue = [ ] ;
110+
111+ // Case: defaultValue is an array and inValue isn't
112+ if ( ! inValueIsArray ) {
113+ for ( i = 0 ; i < defaultValue . length ; i ++ ) {
114+ outValue . push (
115+ coerceFunction (
116+ attributeDefinition , inValue , defaultValue [ i ] ) ) ;
117+ }
118+ }
119+
120+ // Case: inValue is an array and defaultValue isn't
121+ else if ( ! defaultValueIsArray ) {
122+ for ( i = 0 ; i < inValue . length ; i ++ ) {
123+ outValue . push (
124+ coerceFunction (
125+ attributeDefinition , inValue [ i ] , defaultValue ) ) ;
126+ }
127+ }
128+
129+ // Case: inValue and defaultValue are both arrays
130+ else {
131+ for ( i = 0 ; i < defaultValue . length ; i ++ ) {
132+ outValue . push (
133+ coerceFunction (
134+ attributeDefinition , inValue [ i ] , defaultValue [ i ] ) ) ;
135+ }
136+ for ( ; i < inValue . length ; i ++ ) {
137+ outValue . push (
138+ coerceFunction (
139+ attributeDefinition , inValue [ i ] , defaultValue2 ) ) ;
140+ }
141+ }
142+
143+ traceOut [ attribute ] = outValue ;
144+
145+ return outValue ;
146+ }
147+
26148 var len = handleXYDefaults ( traceIn , traceOut , coerce ) ;
27149 if ( ! len ) {
28150 traceOut . visible = false ;
@@ -33,7 +155,23 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
33155 coerce ( 'base' ) ;
34156 coerce ( 'offset' ) ;
35157 coerce ( 'width' ) ;
36- coerce ( 'text' ) ;
158+
159+ coerceArray ( 'text' , coerceString ) ;
160+
161+ var textPosition = coerceArray ( 'textposition' , coerceEnumerated ) ;
162+
163+ var hasBoth = Array . isArray ( textPosition ) || textPosition === 'auto' ,
164+ hasInside = hasBoth || textPosition === 'inside' ,
165+ hasOutside = hasBoth || textPosition === 'outside' ;
166+ if ( hasInside || hasOutside ) {
167+ var textFont = coerceArray ( 'textfont' , coerceFont , layout . font ) ;
168+ if ( hasInside ) {
169+ coerceArray ( 'insidetextfont' , coerceFont , textFont , layout . font ) ;
170+ }
171+ if ( hasOutside ) {
172+ coerceArray ( 'outsidetextfont' , coerceFont , textFont , layout . font ) ;
173+ }
174+ }
37175
38176 handleStyleDefaults ( traceIn , traceOut , coerce , defaultColor , layout ) ;
39177
0 commit comments