@@ -8,7 +8,9 @@ import { Canvas } from './canvas';
8
8
export const enum Sizing {
9
9
LabelHeight = 18 ,
10
10
RulerWidth = 1 ,
11
+ LineWidth = 1 ,
11
12
Easing = 200 ,
13
+ SplitSpacing = 3 ,
12
14
}
13
15
14
16
const rulers = 4 ;
@@ -18,6 +20,7 @@ export class FrameCanvas extends Canvas {
18
20
private paths : [ Path2D , string ] [ ] = [ ] ;
19
21
private ease ?: { raf : number ; dx : number } ;
20
22
private rmSettingListener = this . settings . onChange ( ( ) => this . redraw ( ) ) ;
23
+ private metricRanges = this . getMetricYRanges ( ) ;
21
24
22
25
/**
23
26
* Redraws the max values
@@ -29,10 +32,7 @@ export class FrameCanvas extends Canvas {
29
32
easeLength += this . ease . dx ;
30
33
}
31
34
32
- this . paths = this . settings . enabledMetrics . map ( metric => [
33
- this . createMetricPath ( metric ) ,
34
- this . settings . metricColor ( metric ) ,
35
- ] ) ;
35
+ this . paths = this . createMetricPaths ( ) ;
36
36
37
37
if ( ! shouldEase ) {
38
38
this . drawGraph ( ) ;
@@ -74,6 +74,7 @@ export class FrameCanvas extends Canvas {
74
74
75
75
protected redraw ( ) {
76
76
this . rulers = this . createRulers ( ) ;
77
+ this . metricRanges = this . getMetricYRanges ( ) ;
77
78
this . updateMetrics ( false ) ;
78
79
}
79
80
@@ -107,43 +108,68 @@ export class FrameCanvas extends Canvas {
107
108
108
109
private createRulers ( ) {
109
110
const path = new Path2D ( ) ;
110
- const { width, height } = this ;
111
- const step = ( height - Sizing . RulerWidth ) / rulers ;
112
-
113
- let y = step ;
114
- for ( let i = 0 ; i < rulers ; i ++ ) {
115
- const targetY = Math . floor ( y ) + Sizing . RulerWidth / 2 ;
116
- path . moveTo ( 0 , targetY ) ;
117
- path . lineTo ( width , targetY ) ;
118
- y += step ;
111
+
112
+ const ranges = this . settings . value . splitCharts ? this . getMetricYRanges ( ) : [ [ 0 , this . height ] ] ;
113
+ for ( const [ y1 , y2 ] of ranges ) {
114
+ const step = ( y2 - y1 ) / rulers ;
115
+ let y = y1 + step ;
116
+ for ( let i = 0 ; i < rulers ; i ++ ) {
117
+ const targetY = Math . floor ( y ) - Sizing . RulerWidth / 2 ;
118
+ path . moveTo ( 0 , targetY ) ;
119
+ path . lineTo ( this . width , targetY ) ;
120
+ y += step ;
121
+ }
119
122
}
120
123
121
124
return path ;
122
125
}
123
126
124
- private createMetricPath ( { maxY, metrics } : Metric ) {
125
- const { width, height } = this ;
127
+ private getMetricYRanges ( ) : [ number , number ] [ ] {
128
+ const metrics = this . settings . enabledMetrics ;
129
+ if ( ! this . settings . value . splitCharts ) {
130
+ return metrics . map ( ( ) => [ 0 , this . height ] ) ;
131
+ }
132
+
133
+ const yStep = this . height / metrics . length ;
134
+ return metrics . map ( ( _ , i ) => [
135
+ Math . ceil ( yStep * i + ( i > 0 ? Sizing . SplitSpacing / 2 : 0 ) ) ,
136
+ Math . floor ( yStep * ( i + 1 ) - ( i < metrics . length - 1 ? Sizing . SplitSpacing / 2 : 0 ) ) ,
137
+ ] ) ;
138
+ }
139
+
140
+ private createMetricPaths ( ) : [ Path2D , string ] [ ] {
141
+ return this . settings . enabledMetrics . map ( ( metric , i ) => [
142
+ this . createMetricPath ( metric , this . metricRanges [ i ] [ 0 ] , this . metricRanges [ i ] [ 1 ] ) ,
143
+ this . settings . metricColor ( metric ) ,
144
+ ] ) ;
145
+ }
146
+
147
+ private createMetricPath ( { maxY, metrics } : Metric , y1 : number , y2 : number ) {
148
+ const width = this . width ;
149
+ const lineBaseY = y2 - Sizing . LineWidth / 2 ;
126
150
const stepSize = width / this . settings . steps ;
127
151
const path = new Path2D ( ) ;
128
152
129
153
if ( metrics . length === 0 ) {
130
- path . moveTo ( 0 , height - 1 ) ;
131
- path . lineTo ( width , height - 1 ) ;
154
+ path . moveTo ( 0 , lineBaseY ) ;
155
+ path . lineTo ( width , lineBaseY ) ;
132
156
return path ;
133
157
}
134
158
135
159
let x = width ;
136
- path . moveTo ( x , height * ( 1 - metrics [ metrics . length - 1 ] / maxY ) ) ;
160
+ path . moveTo ( x , getY ( y1 , lineBaseY , 1 - metrics [ metrics . length - 1 ] / maxY ) ) ;
137
161
138
162
for ( let i = metrics . length - 2 ; i >= 0 ; i -- ) {
139
163
x -= stepSize ;
140
- path . lineTo ( x , height * ( 1 - metrics [ i ] / maxY ) ) ;
164
+ path . lineTo ( x , getY ( y1 , lineBaseY , 1 - metrics [ i ] / maxY ) ) ;
141
165
}
142
166
143
- path . lineTo ( x - stepSize , height - 1 ) ;
144
- path . lineTo ( - stepSize , height - 1 ) ;
145
- path . lineTo ( - stepSize , height + 2 ) ;
146
- path . lineTo ( width , height + 2 ) ;
167
+ path . lineTo ( x - stepSize , lineBaseY ) ;
168
+ path . lineTo ( - stepSize , lineBaseY ) ;
169
+ path . lineTo ( width , lineBaseY ) ;
147
170
return path ;
148
171
}
149
172
}
173
+
174
+ const getY = ( y1 : number , y2 : number , value : number ) =>
175
+ y1 + ( y2 - y1 ) * Math . max ( 0 , Math . min ( 1 , value ) ) ;
0 commit comments