@@ -13,6 +13,7 @@ import annotations from './helpers/annotations.js'
13
13
import mousetip from './tip.js'
14
14
import helpers from './helpers/index.js'
15
15
import datumDefaults from './datum-defaults.js'
16
+ import datumValidation from './datum-validation.js'
16
17
import globals from './globals.mjs'
17
18
18
19
export interface ChartMetaMargin {
@@ -156,6 +157,8 @@ export class Chart extends EventEmitter.EventEmitter {
156
157
*/
157
158
plot ( ) {
158
159
this . emit ( 'before:plot' )
160
+ this . setDefaultOptions ( )
161
+ this . validateOptions ( )
159
162
this . buildInternalVars ( )
160
163
this . render ( )
161
164
this . emit ( 'after:plot' )
@@ -182,6 +185,31 @@ export class Chart extends EventEmitter.EventEmitter {
182
185
return cachedInstance
183
186
}
184
187
188
+ private setDefaultOptions ( ) {
189
+ this . options . x = this . options . x || { }
190
+ this . options . x . type = this . options . x . type || 'linear'
191
+
192
+ this . options . y = this . options . y || { }
193
+ this . options . y . type = this . options . y . type || 'linear'
194
+
195
+ for ( let d of this . options . data ) {
196
+ datumDefaults ( d )
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Validate options provides best effort runtime validation of the options.
202
+ */
203
+ private validateOptions ( ) {
204
+ try {
205
+ for ( let datum of this . options . data ) {
206
+ datumValidation ( datum )
207
+ }
208
+ } catch ( e ) {
209
+ throw new Error ( `detected invalid options: ${ e } ` , e )
210
+ }
211
+ }
212
+
185
213
private buildInternalVars ( ) {
186
214
const margin = ( this . meta . margin = { left : 40 , right : 20 , top : 20 , bottom : 20 } )
187
215
// if there's a title make the top margin bigger
@@ -215,13 +243,7 @@ export class Chart extends EventEmitter.EventEmitter {
215
243
return ( self . meta . height * xDiff ) / self . meta . width
216
244
}
217
245
218
- this . options . x = this . options . x || { }
219
- this . options . x . type = this . options . x . type || 'linear'
220
-
221
- this . options . y = this . options . y || { }
222
- this . options . y . type = this . options . y . type || 'linear'
223
-
224
- const xDomain = ( this . meta . xDomain = ( function ( axis : FunctionPlotOptionsAxis ) {
246
+ const xDomain = ( function ( axis : FunctionPlotOptionsAxis ) : [ number , number ] {
225
247
if ( axis . domain ) {
226
248
return axis . domain
227
249
}
@@ -232,9 +254,10 @@ export class Chart extends EventEmitter.EventEmitter {
232
254
return [ 1 , 10 ]
233
255
}
234
256
throw Error ( 'axis type ' + axis . type + ' unsupported' )
235
- } ) ( this . options . x ) )
257
+ } ) ( this . options . x )
258
+ this . meta . xDomain = xDomain
236
259
237
- const yDomain = ( this . meta . yDomain = ( function ( axis : FunctionPlotOptionsAxis ) {
260
+ const yDomain = ( function ( axis : FunctionPlotOptionsAxis ) : [ number , number ] {
238
261
if ( axis . domain ) {
239
262
return axis . domain
240
263
}
@@ -245,7 +268,8 @@ export class Chart extends EventEmitter.EventEmitter {
245
268
return [ 1 , 10 ]
246
269
}
247
270
throw Error ( 'axis type ' + axis . type + ' unsupported' )
248
- } ) ( this . options . y ) )
271
+ } ) ( this . options . y )
272
+ this . meta . yDomain = yDomain
249
273
250
274
if ( ! this . meta . xScale ) {
251
275
this . meta . xScale = getD3Scale ( this . options . x . type ) ( )
@@ -544,7 +568,7 @@ export class Chart extends EventEmitter.EventEmitter {
544
568
. selectAll ( ':scope > g.graph' )
545
569
. data (
546
570
( d : FunctionPlotOptions ) => {
547
- return d . data . map ( datumDefaults )
571
+ return d . data
548
572
} ,
549
573
( d : any ) => {
550
574
// The key is the function set or other value that uniquely identifies the datum.
0 commit comments