@@ -182,6 +182,9 @@ if (!window.Chart) {
182182
183183 class Legend {
184184 constructor ( chart ) {
185+ this . legendHandler = this . legendHandler . bind ( this )
186+
187+ this . chart = chart
185188 this . ohlcEnabled = false
186189 this . percentEnabled = false
187190 this . linesEnabled = false
@@ -207,80 +210,12 @@ if (!window.Chart) {
207210
208211 this . makeLines ( chart )
209212
210- let legendItemFormat = ( num , decimal ) => num . toFixed ( decimal ) . toString ( ) . padStart ( 8 , ' ' )
211-
212- let shorthandFormat = ( num ) => {
213- const absNum = Math . abs ( num )
214- if ( absNum >= 1000000 ) {
215- return ( num / 1000000 ) . toFixed ( 1 ) + 'M' ;
216- } else if ( absNum >= 1000 ) {
217- return ( num / 1000 ) . toFixed ( 1 ) + 'K' ;
218- }
219- return num . toString ( ) . padStart ( 8 , ' ' ) ;
220- }
221-
222- chart . chart . subscribeCrosshairMove ( ( param ) => {
223- let options = chart . series . options ( )
224- if ( ! param . time ) {
225- this . candle . style . color = 'transparent'
226- this . candle . innerHTML = this . candle . innerHTML . replace ( options [ 'upColor' ] , '' ) . replace ( options [ 'downColor' ] , '' )
227- return
228- }
229- let data = param . seriesData . get ( chart . series ) ;
230- this . candle . style . color = ''
231- let str = '<span style="line-height: 1.8;">'
232- if ( data ) {
233- if ( this . ohlcEnabled ) {
234- str += `O ${ legendItemFormat ( data . open , chart . precision ) } `
235- str += `| H ${ legendItemFormat ( data . high , chart . precision ) } `
236- str += `| L ${ legendItemFormat ( data . low , chart . precision ) } `
237- str += `| C ${ legendItemFormat ( data . close , chart . precision ) } `
238- }
239-
240- if ( this . percentEnabled ) {
241- let percentMove = ( ( data . close - data . open ) / data . open ) * 100
242- let color = percentMove > 0 ? options [ 'upColor' ] : options [ 'downColor' ]
243- let percentStr = `${ percentMove >= 0 ? '+' : '' } ${ percentMove . toFixed ( 2 ) } %`
244-
245- if ( this . colorBasedOnCandle ) {
246- str += `| <span style="color: ${ color } ;">${ percentStr } </span>`
247- }
248- else {
249- str += '| ' + percentStr
250- }
251- }
252- let volumeData = param . seriesData . get ( chart . volumeSeries )
253- if ( volumeData ) {
254- str += this . ohlcEnabled ? `<br>V ${ shorthandFormat ( volumeData . value ) } ` : ''
255- }
256- }
257- this . candle . innerHTML = str + '</span>'
258-
259- this . lines . forEach ( ( line ) => {
260- if ( ! this . linesEnabled ) {
261- line . row . style . display = 'none'
262- return
263- }
264- line . row . style . display = 'flex'
265- if ( ! param . seriesData . get ( line . line . series ) ) return
266- let price = param . seriesData . get ( line . line . series ) . value
267-
268- if ( line . line . type === 'histogram' ) {
269- price = shorthandFormat ( price )
270- }
271- else {
272- price = legendItemFormat ( price , line . line . precision )
273- }
274- line . div . innerHTML = `<span style="color: ${ line . solid } ;">▨</span> ${ line . line . name } : ${ price } `
275- } )
276-
277-
278- } ) ;
213+ chart . chart . subscribeCrosshairMove ( this . legendHandler )
279214 }
280215
281216 toJSON ( ) {
282217 // Exclude the chart attribute from serialization
283- const { lines, ...serialized } = this ;
218+ const { lines, chart , ...serialized } = this ;
284219 return serialized ;
285220 }
286221
@@ -352,19 +287,108 @@ if (!window.Chart) {
352287 solid : line . color . startsWith ( 'rgba' ) ? line . color . replace ( / [ ^ , ] + (? = \) ) / , '1' ) : line . color
353288 }
354289 }
290+
291+ legendItemFormat ( num , decimal ) { return num . toFixed ( decimal ) . toString ( ) . padStart ( 8 , ' ' ) }
292+
293+ shorthandFormat ( num ) {
294+ const absNum = Math . abs ( num )
295+ if ( absNum >= 1000000 ) {
296+ return ( num / 1000000 ) . toFixed ( 1 ) + 'M' ;
297+ } else if ( absNum >= 1000 ) {
298+ return ( num / 1000 ) . toFixed ( 1 ) + 'K' ;
299+ }
300+ return num . toString ( ) . padStart ( 8 , ' ' ) ;
301+ }
302+
303+ legendHandler ( param ) {
304+ let options = this . chart . series . options ( )
305+
306+ if ( ! param . time ) {
307+ this . candle . style . color = 'transparent'
308+ this . candle . innerHTML = this . candle . innerHTML . replace ( options [ 'upColor' ] , '' ) . replace ( options [ 'downColor' ] , '' )
309+ return
310+ }
311+
312+ let usingPoint = ! param . point && param . time
313+
314+ let data , logical
315+
316+ if ( usingPoint ) {
317+ let coordinate = this . chart . chart . timeScale ( ) . timeToCoordinate ( param . time )
318+ logical = this . chart . chart . timeScale ( ) . coordinateToLogical ( coordinate )
319+ data = this . chart . series . dataByIndex ( logical )
320+ }
321+ else {
322+ data = param . seriesData . get ( this . chart . series ) ;
323+ }
324+
325+ this . candle . style . color = ''
326+ let str = '<span style="line-height: 1.8;">'
327+ if ( data ) {
328+ if ( this . ohlcEnabled ) {
329+ str += `O ${ this . legendItemFormat ( data . open , this . chart . precision ) } `
330+ str += `| H ${ this . legendItemFormat ( data . high , this . chart . precision ) } `
331+ str += `| L ${ this . legendItemFormat ( data . low , this . chart . precision ) } `
332+ str += `| C ${ this . legendItemFormat ( data . close , this . chart . precision ) } `
333+ }
334+
335+ if ( this . percentEnabled ) {
336+ let percentMove = ( ( data . close - data . open ) / data . open ) * 100
337+ let color = percentMove > 0 ? options [ 'upColor' ] : options [ 'downColor' ]
338+ let percentStr = `${ percentMove >= 0 ? '+' : '' } ${ percentMove . toFixed ( 2 ) } %`
339+
340+ if ( this . colorBasedOnCandle ) {
341+ str += `| <span style="color: ${ color } ;">${ percentStr } </span>`
342+ } else {
343+ str += '| ' + percentStr
344+ }
345+ }
346+ let volumeData = param . seriesData . get ( this . chart . volumeSeries )
347+ if ( volumeData ) {
348+ str += this . ohlcEnabled ? `<br>V ${ this . shorthandFormat ( volumeData . value ) } ` : ''
349+ }
350+ }
351+ this . candle . innerHTML = str + '</span>'
352+
353+ this . lines . forEach ( ( line ) => {
354+ if ( ! this . linesEnabled ) {
355+ line . row . style . display = 'none'
356+ return
357+ }
358+ line . row . style . display = 'flex'
359+
360+ let price
361+ if ( usingPoint ) {
362+ price = line . line . series . dataByIndex ( logical )
363+ }
364+ else {
365+ price = param . seriesData . get ( line . line . series )
366+ }
367+ if ( ! price ) return
368+ else price = price . value
369+
370+ if ( line . line . type === 'histogram' ) {
371+ price = this . shorthandFormat ( price )
372+ } else {
373+ price = this . legendItemFormat ( price , line . line . precision )
374+ }
375+ line . div . innerHTML = `<span style="color: ${ line . solid } ;">▨</span> ${ line . line . name } : ${ price } `
376+ } )
377+ }
355378 }
356379
357380 window . Legend = Legend
358381}
359382
360383function syncCharts ( childChart , parentChart ) {
361384
362- function crosshairHandler ( chart , series , point ) {
385+ function crosshairHandler ( chart , point ) {
363386 if ( ! point ) {
364- chart . clearCrosshairPosition ( )
387+ chart . chart . clearCrosshairPosition ( )
365388 return
366389 }
367- chart . setCrosshairPosition ( point . value || point . close , point . time , series ) ;
390+ chart . chart . setCrosshairPosition ( point . value || point . close , point . time , chart . series ) ;
391+ chart . legend . legendHandler ( point )
368392 }
369393
370394 function getPoint ( series , param ) {
@@ -376,10 +400,10 @@ function syncCharts(childChart, parentChart) {
376400 let setParentRange = ( timeRange ) => parentChart . chart . timeScale ( ) . setVisibleLogicalRange ( timeRange )
377401
378402 let setParentCrosshair = ( param ) => {
379- crosshairHandler ( parentChart . chart , parentChart . series , getPoint ( childChart . series , param ) )
403+ crosshairHandler ( parentChart , getPoint ( childChart . series , param ) )
380404 }
381405 let setChildCrosshair = ( param ) => {
382- crosshairHandler ( childChart . chart , childChart . series , getPoint ( parentChart . series , param ) )
406+ crosshairHandler ( childChart , getPoint ( parentChart . series , param ) )
383407 }
384408
385409 let selected = parentChart
0 commit comments