@@ -3,49 +3,79 @@ import { Path } from "../../svg/Path";
33import type { ChartYControl } from "../view/ChartYControl" ;
44import type { ChartXControl } from "../view/ChartXControl" ;
55import type { PlotOptions } from "./Plot" ;
6- import type { TimeData } from "../../domain/Kline" ;
6+ import type { PineData } from "../../domain/PineData" ;
7+ import type { Seg } from "../../svg/Seg" ;
78
89type Props = {
910 xc : ChartXControl ,
1011 yc : ChartYControl ,
11- tvar : TVar < unknown [ ] > ,
12+ tvar : TVar < PineData [ ] > ,
1213 name : string ,
1314 options : PlotOptions ;
14- plot1 : TimeData [ ] ;
15- plot2 : TimeData [ ] ;
15+ plot1 : PineData [ ] ;
16+ plot2 : PineData [ ] ;
1617 depth ?: number ;
1718}
1819
1920const PlotFill = ( props : Props ) => {
2021 const { xc, yc, tvar, name, depth, plot1, plot2, options } = props ;
2122
23+ const fillgaps = options . fillgaps ;
24+
25+ const r = xc . wBar < 2
26+ ? 0
27+ : Math . floor ( ( xc . wBar - 2 ) / 2 ) ;
28+
2229 function plot ( ) {
23- const path = new Path ( ) ;
24- const points_a = linePoints ( plot1 ) ;
25- const points_b = linePoints ( plot2 ) . reverse ( ) ;
26- const points = [ ...points_a , ...points_b ]
27-
28- for ( let i = 0 ; i < points . length ; i ++ ) {
29- const [ x , y ] = points [ i ]
30- if ( i === 0 ) {
31- path . moveto ( x , y )
30+ const segs : Seg [ ] = [ ] ;
31+ const points_a = collectPoints ( plot1 ) ;
32+ const points_b = collectPoints ( plot2 )
33+
34+ let shallStartNewFill = true
35+
36+ let unClosedPath : Path
37+ let lastCloseIndex = 0
38+ for ( let m = 0 ; m < points_a . length ; m ++ ) {
39+ const [ xa , ya ] = points_a [ m ]
40+ const [ xb , yb ] = points_b [ m ]
41+
42+ if ( xa === undefined || xb === undefined ) {
43+ if ( unClosedPath ) {
44+ for ( let n = m - 1 ; n > lastCloseIndex ; n -- ) {
45+ const [ xb , yb ] = points_b [ n ]
46+ unClosedPath . lineto ( xb , yb )
47+ }
48+
49+ unClosedPath . closepath ( )
50+ }
51+
52+ shallStartNewFill = true
53+
3254 } else {
33- path . lineto ( x , y )
55+ if ( shallStartNewFill ) {
56+ unClosedPath = new Path ( )
57+ segs . push ( unClosedPath )
58+
59+ unClosedPath . moveto ( xa , ya )
60+
61+ lastCloseIndex = m
62+ shallStartNewFill = false
63+
64+ } else {
65+ unClosedPath . lineto ( xa , ya )
66+ }
67+
3468 }
3569 }
3670
37- path . closepath ( )
38-
39- return { path }
71+ return { segs }
4072 }
4173
42- function linePoints ( datas : TimeData [ ] ) {
74+ function collectPoints ( datas : PineData [ ] ) {
4375 const points : number [ ] [ ] = [ ]
4476
45- // For those need connect from one bar to the next, use bar++ instead of
46- // bar += xc.nBarsCompressed to avoid uncontinuted line.
4777 for ( let bar = 1 ; bar <= xc . nBars ; bar ++ ) {
48- // use `undefiend ` to test if value has been set at least one time
78+ // use `undefined ` to test if value has been set at least one time
4979 let value : number
5080 const time = xc . tb ( bar )
5181 if ( tvar . occurred ( time ) ) {
@@ -55,28 +85,33 @@ const PlotFill = (props: Props) => {
5585
5686 // console.log(index, data)
5787
58- if ( typeof v === "number" && isNaN ( v ) === false ) {
88+ if ( typeof v === "number" && ! isNaN ( v ) ) {
5989 value = v ;
6090 }
6191 }
6292
63- if ( value !== undefined && isNaN ( value ) === false ) {
93+ if ( value !== undefined && ! isNaN ( value ) ) {
6494 const x = xc . xb ( bar )
6595 const y = yc . yv ( value )
6696
6797 if ( y !== undefined && ! isNaN ( y ) ) {
6898 points . push ( [ x , y ] )
6999 }
100+
101+ } else {
102+ if ( ! fillgaps ) {
103+ points . push ( [ undefined , undefined ] )
104+ }
70105 }
71106 }
72107
73108 return points
74109 }
75110
76- const { path } = plot ( ) ;
111+ const { segs } = plot ( ) ;
77112
78113 return (
79- path . render ( { style : { stroke : options . color , fill : options . color } } )
114+ segs . map ( ( seg , n ) => seg . render ( { key : 'seg-' + n , style : { stroke : undefined , fill : options . color } } ) )
80115 )
81116}
82117
0 commit comments