@@ -2,6 +2,14 @@ import * as util from './util'
22
33export enum System { None , Cartesian , Geographic , Complex } ;
44
5+ export class DirectionMarker {
6+ constructor (
7+ public x : number ,
8+ public y : number ,
9+ public angle : number )
10+ { }
11+ }
12+
513export class PlotlyData {
614 constructor (
715 public traces : any [ ] ,
@@ -10,12 +18,14 @@ export class PlotlyData {
1018 public colorId : number )
1119 { }
1220
21+ public directions : DirectionMarker [ ] = [ ] ;
22+
1323 static empty ( colorId : number ) {
1424 return new PlotlyData ( [ ] , System . None , new util . LonInterval ( 0 , 0 ) , colorId ) ;
1525 }
1626}
1727
18- function createTrace ( xs : number [ ] | undefined , ys : number [ ] , system : System ) : any {
28+ function createTrace ( xs : number [ ] , ys : number [ ] , system : System ) : any {
1929 return system === System . Geographic
2030 ? {
2131 lon : xs === undefined ? Array . from ( Array ( ys . length ) . keys ( ) ) : xs ,
@@ -26,6 +36,17 @@ function createTrace(xs: number[] | undefined, ys: number[], system: System): an
2636 } ;
2737}
2838
39+ function direction ( xs : number [ ] , ys : number [ ] , reversed : boolean , system : System ) : DirectionMarker | undefined {
40+ const isGeographic = system === System . Geographic ;
41+ const s = ! reversed ? util . firstSegment ( xs , ys , isGeographic ) : util . rFirstSegment ( xs , ys , isGeographic ) ;
42+ if ( s === undefined )
43+ return undefined ;
44+ const a = util . azimuth ( s . xs [ 0 ] , s . ys [ 0 ] , s . xs [ 1 ] , s . ys [ 1 ] , isGeographic ) ;
45+ if ( a === undefined )
46+ return undefined ;
47+ return new DirectionMarker ( s . xs [ 0 ] , s . ys [ 0 ] , a ) ;
48+ }
49+
2950export class Drawable {
3051 toPlotly ( colorId : number ) : PlotlyData {
3152 return PlotlyData . empty ( colorId ) ;
@@ -36,7 +57,7 @@ export enum PlotStyle { LinesAndMarkers, Lines, Markers, Bars };
3657
3758export class Plot extends Drawable {
3859 constructor (
39- public readonly xs : number [ ] | undefined ,
60+ public readonly xs : number [ ] ,
4061 public readonly ys : number [ ] ,
4162 public readonly system : System ,
4263 public plotStyle : PlotStyle = PlotStyle . LinesAndMarkers ) {
@@ -62,6 +83,12 @@ export class Plot extends Drawable {
6283 trace . mode = "lines+markers" ;
6384 }
6485 result . traces = [ trace ] ;
86+ if ( this . plotStyle === PlotStyle . Lines || this . plotStyle === PlotStyle . LinesAndMarkers ) {
87+ const dir = direction ( this . xs , this . ys , false , this . system ) ;
88+ if ( dir !== undefined ) {
89+ result . directions . push ( dir ) ;
90+ }
91+ }
6592 }
6693 if ( this . system === System . Geographic )
6794 result . lonInterval = util . LonInterval . fromPoints ( this . xs ) ;
@@ -122,13 +149,21 @@ export class Ring extends Drawable {
122149 constructor (
123150 public readonly xs : number [ ] ,
124151 public readonly ys : number [ ] ,
152+ public readonly reversed : boolean ,
125153 public readonly system : System ,
126154 private readonly _isBox : boolean = false ) {
127155 super ( ) ;
128- // naiively close the ring
129- if ( xs . length > 0 && ys . length > 0 ) {
130- this . xs . push ( xs [ 0 ] ) ;
131- this . ys . push ( ys [ 0 ] ) ;
156+ // close the ring
157+ if ( ys . length >= 2 ) {
158+ // TODO: In geographic this may not detect the same points
159+ if ( xs [ 0 ] != xs [ xs . length - 1 ] || ys [ 0 ] != ys [ ys . length - 1 ] ) {
160+ this . xs . push ( xs [ 0 ] ) ;
161+ this . ys . push ( ys [ 0 ] ) ;
162+ }
163+ }
164+ if ( reversed ) {
165+ this . xs . reverse ( ) ;
166+ this . ys . reverse ( ) ;
132167 }
133168 }
134169 toPlotly ( colorId : number ) : PlotlyData {
@@ -149,8 +184,15 @@ export class Ring extends Drawable {
149184 mode : this . _isBox ? "lines" : "lines+markers" ,
150185 fill : 'toself'
151186 } ] ;
152- if ( this . system === System . Geographic )
187+ if ( this . system === System . Geographic ) {
153188 result . lonInterval = util . LonInterval . fromPoints ( this . xs ) ;
189+ }
190+ if ( this . ys . length > 0 ) {
191+ const dir = direction ( this . xs , this . ys , this . reversed , this . system ) ;
192+ if ( dir !== undefined ) {
193+ result . directions . push ( dir ) ;
194+ }
195+ }
154196 return result ;
155197 }
156198} ;
@@ -171,6 +213,7 @@ export class Polygon extends Drawable {
171213 result . traces [ 0 ] . y . push ( null ) ;
172214 result . traces [ 0 ] . x = result . traces [ 0 ] . x . concat ( d . traces [ 0 ] . x ) ;
173215 result . traces [ 0 ] . y = result . traces [ 0 ] . y . concat ( d . traces [ 0 ] . y ) ;
216+ result . directions = result . directions . concat ( d . directions ) ;
174217 }
175218 } else {
176219 // geographic has to be treated separately because typical way of dealing with holes does not work
@@ -193,6 +236,7 @@ export class Polygon extends Drawable {
193236 result . traces [ 1 ] . lon = result . traces [ 1 ] . lon . concat ( d . traces [ 0 ] . lon ) ;
194237 result . traces [ 1 ] . lat = result . traces [ 1 ] . lat . concat ( d . traces [ 0 ] . lat ) ;
195238 closeHoles = true ;
239+ result . directions = result . directions . concat ( d . directions ) ;
196240 }
197241 if ( closeHoles ) {
198242 result . traces [ 0 ] . lon . push ( result . traces [ 0 ] . lon [ 0 ] ) ;
0 commit comments