@@ -24,6 +24,7 @@ export class Axis extends Shape {
24
24
public ticksFontsize : number = 12 ;
25
25
public isDiscrete : boolean = true ;
26
26
public isInteger : boolean = false ;
27
+ public logScale : boolean = false ;
27
28
public isDate : boolean = false ;
28
29
29
30
public drawPath : Path2D ;
@@ -152,6 +153,30 @@ export class Axis extends Shape {
152
153
153
154
public toggleView ( ) : void { this . visible = ! this . visible }
154
155
156
+ private getLogBoundaries ( vector : number [ ] ) : [ number , number ] {
157
+ const positiveVector = vector . filter ( value => value > 0 ) ;
158
+ const min = Math . min ( ...positiveVector ) ;
159
+ const max = Math . max ( ...positiveVector ) ;
160
+ if ( max <= 0 ) {
161
+ this . logScale = false ;
162
+ return [ this . initMinValue , this . initMaxValue ]
163
+ }
164
+ if ( this . logScale ) {
165
+ return [
166
+ this . initMinValue > 0 ? Math . log10 ( this . initMinValue ) : Math . log10 ( min ) ,
167
+ this . initMaxValue > 0 ? Math . log10 ( this . initMaxValue ) : Math . log10 ( max )
168
+ ]
169
+ } else return [ 10 ** this . initMinValue , 10 ** this . initMaxValue ]
170
+ }
171
+
172
+ public switchLogScale ( vector : number [ ] ) : void {
173
+ if ( ! this . isDiscrete ) {
174
+ this . logScale = ! this . logScale ;
175
+ [ this . initMinValue , this . initMaxValue ] = this . getLogBoundaries ( vector ) ;
176
+ this . updateTicks ( ) ;
177
+ }
178
+ }
179
+
155
180
private discretePropertiesFromVector ( vector : any [ ] ) : void {
156
181
if ( vector ) {
157
182
if ( vector . length != 0 ) {
@@ -186,8 +211,8 @@ export class Axis extends Shape {
186
211
public resetScale ( ) : void {
187
212
this . minValue = this . initMinValue ;
188
213
this . maxValue = this . initMaxValue ;
189
- this . _previousMin = this . initMinValue ;
190
- this . _previousMax = this . initMaxValue ;
214
+ this . _previousMin = this . minValue ;
215
+ this . _previousMax = this . maxValue ;
191
216
this . updateTicks ( ) ;
192
217
}
193
218
@@ -251,13 +276,19 @@ export class Axis extends Shape {
251
276
}
252
277
253
278
public absoluteToRelative ( value : string | number ) : number {
254
- const numberedValue = this . stringToValue ( value ) ;
255
- return this . isVertical ? ( numberedValue - this . transformMatrix . f ) / this . transformMatrix . d : ( numberedValue - this . transformMatrix . e ) / this . transformMatrix . a
279
+ let numberedValue = this . stringToValue ( value ) ;
280
+ const projectedValue = this . isVertical
281
+ ? ( numberedValue - this . transformMatrix . f ) / this . transformMatrix . a
282
+ : ( numberedValue - this . transformMatrix . e ) / this . transformMatrix . a ;
283
+ return this . logScale ? 10 ** projectedValue : projectedValue ;
256
284
}
257
285
258
286
public relativeToAbsolute ( value : string | number ) : number {
259
- const numberedValue = this . stringToValue ( value ) ;
260
- return this . isVertical ? numberedValue * this . transformMatrix . d + this . transformMatrix . f : numberedValue * this . transformMatrix . a + this . transformMatrix . e
287
+ let numberedValue = this . stringToValue ( value ) ;
288
+ if ( this . logScale ) numberedValue = Math . log10 ( numberedValue ) ;
289
+ return this . isVertical
290
+ ? numberedValue * this . transformMatrix . d + this . transformMatrix . f
291
+ : numberedValue * this . transformMatrix . a + this . transformMatrix . e ;
261
292
}
262
293
263
294
public normedValue ( value : number ) : number { return value / this . interval }
@@ -311,7 +342,7 @@ export class Axis extends Shape {
311
342
private getTickIncrement ( ) : number {
312
343
const rawIncrement = this . isDiscrete ? 1 : Axis . nearestFive ( ( this . maxValue - this . minValue ) / this . nTicks ) ;
313
344
const logExponent = Math . floor ( Math . log10 ( rawIncrement ) ) ;
314
- if ( this . isInteger ) return this . integerTickIncrement ( rawIncrement , logExponent ) ;
345
+ if ( this . isInteger && ! this . logScale ) return this . integerTickIncrement ( rawIncrement , logExponent ) ;
315
346
return this . floatTickIncrement ( rawIncrement , logExponent ) ;
316
347
}
317
348
@@ -351,7 +382,7 @@ export class Axis extends Shape {
351
382
if ( ticks . slice ( 0 ) [ 0 ] < this . minValue ) ticks . splice ( 0 , 1 ) ;
352
383
if ( ticks . slice ( - 1 ) [ 0 ] >= this . maxValue ) ticks . splice ( - 1 , 1 ) ;
353
384
this . updateTickPrecision ( increment , ticks ) ;
354
- return ticks
385
+ return this . logScale ? ticks . map ( tick => 10 ** tick ) : ticks
355
386
}
356
387
357
388
public drawWhenIsVisible ( context : CanvasRenderingContext2D ) : void {
@@ -458,8 +489,7 @@ export class Axis extends Shape {
458
489
if ( count == tick && this . labels [ count ] ) {
459
490
text = this . labels [ count ] ;
460
491
count ++ ;
461
- }
462
- else text = '' ;
492
+ } else text = '' ;
463
493
}
464
494
ticksText . push ( this . computeTickText ( context , text , tickTextParams , point , pointHTMatrix ) ) ;
465
495
} )
@@ -497,7 +527,9 @@ export class Axis extends Shape {
497
527
}
498
528
499
529
protected drawTickPoint ( context : CanvasRenderingContext2D , tick : number , vertical : boolean , HTMatrix : DOMMatrix , color : string ) : Point {
500
- const center = new Vertex ( tick * Number ( ! vertical ) , tick * Number ( vertical ) ) . transform ( HTMatrix ) ;
530
+ const center = this . logScale ?
531
+ new Vertex ( Math . log10 ( tick ) * Number ( ! vertical ) , Math . log10 ( tick ) * Number ( vertical ) ) . transform ( HTMatrix ) :
532
+ new Vertex ( tick * Number ( ! vertical ) , tick * Number ( vertical ) ) . transform ( HTMatrix ) ;
501
533
const point = new Point ( center . x , center . y , SIZE_AXIS_END , this . tickMarker , this . tickOrientation , color ) ;
502
534
point . draw ( context ) ;
503
535
return point
@@ -514,7 +546,7 @@ export class Axis extends Shape {
514
546
}
515
547
516
548
private getValueToDrawMatrix ( ) : DOMMatrix {
517
- const scale = this . drawLength / this . interval ;
549
+ let scale = this . drawLength / this . interval ;
518
550
if ( this . isInverted ) {
519
551
return new DOMMatrix ( [
520
552
- scale , 0 , 0 , - scale ,
@@ -561,13 +593,18 @@ export class Axis extends Shape {
561
593
}
562
594
}
563
595
596
+ private restrictRubberBandTranslation ( downValue : number , currentValue : number ) : [ number , number ] {
597
+ if ( ! this . logScale || this . rubberBand . lastValues . x + currentValue - downValue > 0 || ! this . rubberBand . isTranslating ) return [ downValue , currentValue ]
598
+ return [ downValue , downValue - this . rubberBand . lastValues . x ]
599
+ }
600
+
564
601
public mouseMoveClickedArrow ( mouseCoords : Vertex ) : void {
565
602
const downValue = this . absoluteToRelative ( this . isVertical ? this . mouseClick . y : this . mouseClick . x ) ;
566
603
const currentValue = this . absoluteToRelative ( this . isVertical ? mouseCoords . y : mouseCoords . x ) ;
567
604
if ( ! this . rubberBand . isClicked ) {
568
605
this . rubberBand . minValue = Math . min ( downValue , currentValue ) ;
569
606
this . rubberBand . maxValue = Math . max ( downValue , currentValue ) ;
570
- } else this . rubberBand . mouseMove ( downValue , currentValue ) ;
607
+ } else this . rubberBand . mouseMove ( ... this . restrictRubberBandTranslation ( downValue , currentValue ) ) ;
571
608
}
572
609
573
610
public mouseMoveClickedTitle ( mouseCoords : Vertex ) : void { }
@@ -643,13 +680,13 @@ export class Axis extends Shape {
643
680
644
681
public updateScale ( viewPoint : Vertex , scaling : Vertex , translation : Vertex ) : void {
645
682
const HTMatrix = this . transformMatrix ;
646
- let center = ( viewPoint . x - HTMatrix . e ) / HTMatrix . a ;
683
+ let center = ( viewPoint . x - HTMatrix . e ) / HTMatrix . a ; ;
647
684
let offset = translation . x ;
648
- let scale = scaling . x ;
685
+ let scale = this . logScale ? 10 ** ( scaling . x - 1 ) : scaling . x ;
649
686
if ( this . isVertical ) {
650
687
center = ( viewPoint . y - HTMatrix . f ) / HTMatrix . d ;
651
688
offset = translation . y ;
652
- scale = scaling . y ;
689
+ scale = this . logScale ? 10 ** ( scaling . y - 1 ) : scaling . y ;
653
690
}
654
691
this . minValue = ( this . _previousMin - center ) / scale + center - offset / HTMatrix . a ;
655
692
this . maxValue = ( this . _previousMax - center ) / scale + center - offset / HTMatrix . a ;
0 commit comments