@@ -3,8 +3,8 @@ import { select as d3Select, Selection } from 'd3-selection'
33import { asyncIntervalEvaluate , intervalEvaluate } from '../evaluate-datum.js'
44import { infinity , color } from '../utils.mjs'
55
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'
88import { IntervalSamplerResult } from '../samplers/types.js'
99
1010function clampRange ( minWidthHeight : number , vLo : number , vHi : number , gLo : number , gHi : number ) {
@@ -39,7 +39,7 @@ export function createPathD(
3939 xScale : FunctionPlotScale ,
4040 yScale : FunctionPlotScale ,
4141 minWidthHeight : number ,
42- points : Array < [ Interval , Interval ] > ,
42+ points : Array < [ TInterval , TInterval ] > ,
4343 closed : boolean
4444) {
4545 let path = ''
@@ -75,54 +75,67 @@ export function createPathD(
7575 return path
7676}
7777
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
8185
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+ }
9495
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 )
97106
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 )
100109
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' )
110112
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 ] } `
120130 }
131+ selection . attr ( k , val )
121132 }
133+ }
122134
123- innerSelection . exit ( ) . remove ( )
124- } )
135+ innerSelection . exit ( ) . remove ( )
125136 }
137+ }
126138
127- return plotLine
139+ export function interval ( options : any ) {
140+ return new Interval ( options )
128141}
0 commit comments