@@ -3,8 +3,8 @@ import { select as d3Select, Selection } from 'd3-selection'
3
3
import { asyncIntervalEvaluate , intervalEvaluate } from '../evaluate-datum.js'
4
4
import { infinity , color } from '../utils.mjs'
5
5
6
- import { Chart } from '../index .js'
7
- import { Interval , FunctionPlotDatum , FunctionPlotScale , LinearFunction } from '../types.js'
6
+ import { Mark } from './mark .js'
7
+ import { Interval as TInterval , FunctionPlotDatum , FunctionPlotScale } from '../types.js'
8
8
import { IntervalSamplerResult } from '../samplers/types.js'
9
9
10
10
function clampRange ( minWidthHeight : number , vLo : number , vHi : number , gLo : number , gHi : number ) {
@@ -39,7 +39,7 @@ export function createPathD(
39
39
xScale : FunctionPlotScale ,
40
40
yScale : FunctionPlotScale ,
41
41
minWidthHeight : number ,
42
- points : Array < [ Interval , Interval ] > ,
42
+ points : Array < [ TInterval , TInterval ] > ,
43
43
closed : boolean
44
44
) {
45
45
let path = ''
@@ -75,54 +75,67 @@ export function createPathD(
75
75
return path
76
76
}
77
77
78
- export default function interval ( chart : Chart ) {
79
- const xScale = chart . meta . xScale
80
- const yScale = chart . meta . yScale
78
+ export class Interval extends Mark {
79
+ fn ?: any
80
+ closed : boolean
81
+ fnType : string
82
+ sampler : string
83
+ range ?: [ number , number ]
84
+ nSamples : number
81
85
82
- function plotLine ( selection : Selection < any , FunctionPlotDatum , any , any > ) {
83
- selection . each ( async function ( d ) {
84
- const el = ( ( plotLine as any ) . el = d3Select ( this ) )
85
- const index = d . index
86
- const closed = d . closed
87
- let evaluatedData : IntervalSamplerResult
88
- if ( d . fnType === 'linear' && typeof ( d as LinearFunction ) . fn === 'string' && d . sampler === 'asyncInterval' ) {
89
- evaluatedData = await asyncIntervalEvaluate ( chart , d )
90
- } else {
91
- evaluatedData = intervalEvaluate ( chart , d )
92
- }
93
- const innerSelection = el . selectAll ( ':scope > path.line' ) . data ( evaluatedData )
86
+ constructor ( options : any ) {
87
+ super ( options )
88
+ this . fn = options . fn
89
+ this . fnType = options . fnType || 'linear'
90
+ this . sampler = options . sampler || 'interval'
91
+ this . closed = options . closed
92
+ this . range = options . range
93
+ this . nSamples = options . nSamples
94
+ }
94
95
95
- // the min height/width of the rects drawn by the path generator
96
- const minWidthHeight = Math . max ( ( evaluatedData [ 0 ] as any ) . scaledDx , 1 )
96
+ async render ( selection : Selection < any , FunctionPlotDatum , any , any > ) {
97
+ const index = this . index
98
+ const closed = this . closed
99
+ let evaluatedData : IntervalSamplerResult
100
+ if ( this . fnType === 'linear' && typeof this . fn === 'string' && this . sampler === 'asyncInterval' ) {
101
+ evaluatedData = await asyncIntervalEvaluate ( this . chart , this as any )
102
+ } else {
103
+ evaluatedData = intervalEvaluate ( this . chart , this as any )
104
+ }
105
+ const innerSelection = selection . selectAll ( ':scope > path.line' ) . data ( evaluatedData )
97
106
98
- const cls = `line line- ${ index } `
99
- const innerSelectionEnter = innerSelection . enter ( ) . append ( 'path' ) . attr ( 'class' , cls ) . attr ( 'fill' , 'none' )
107
+ // the min height/width of the rects drawn by the path generator
108
+ const minWidthHeight = Math . max ( ( evaluatedData [ 0 ] as any ) . scaledDx , 1 )
100
109
101
- // enter + update
102
- const selection = innerSelection
103
- . merge ( innerSelectionEnter )
104
- . attr ( 'stroke-width' , minWidthHeight )
105
- . attr ( 'stroke' , color ( d , index ) as any )
106
- . attr ( 'opacity' , closed ? 0.5 : 1 )
107
- . attr ( 'd' , function ( d : Array < [ Interval , Interval ] > ) {
108
- return createPathD ( xScale , yScale , minWidthHeight , d , closed )
109
- } )
110
+ const cls = `line line-${ index } `
111
+ const innerSelectionEnter = innerSelection . enter ( ) . append ( 'path' ) . attr ( 'class' , cls ) . attr ( 'fill' , 'none' )
110
112
111
- if ( d . attr ) {
112
- for ( const k in d . attr ) {
113
- // If the attribute to modify is class then append the default class
114
- // or otherwise the d3 selection won't work.
115
- let val = d . attr [ k ]
116
- if ( k === 'class' ) {
117
- val = `${ cls } ${ d . attr [ k ] } `
118
- }
119
- selection . attr ( k , val )
113
+ // enter + update
114
+ innerSelection
115
+ . merge ( innerSelectionEnter )
116
+ . attr ( 'stroke-width' , minWidthHeight )
117
+ . attr ( 'stroke' , color ( this , index ) as any )
118
+ . attr ( 'opacity' , closed ? 0.5 : 1 )
119
+ . attr ( 'd' , ( d : Array < [ TInterval , TInterval ] > ) => {
120
+ return createPathD ( this . chart . meta . xScale , this . chart . meta . yScale , minWidthHeight , d , closed )
121
+ } )
122
+
123
+ if ( this . attr ) {
124
+ for ( const k in this . attr ) {
125
+ // If the attribute to modify is class then append the default class
126
+ // or otherwise the d3 selection won't work.
127
+ let val = this . attr [ k ]
128
+ if ( k === 'class' ) {
129
+ val = `${ cls } ${ this . attr [ k ] } `
120
130
}
131
+ selection . attr ( k , val )
121
132
}
133
+ }
122
134
123
- innerSelection . exit ( ) . remove ( )
124
- } )
135
+ innerSelection . exit ( ) . remove ( )
125
136
}
137
+ }
126
138
127
- return plotLine
139
+ export function interval ( options : any ) {
140
+ return new Interval ( options )
128
141
}
0 commit comments