11import { isNullOrUndef } from '../helpers' ;
22
3+ function minMaxDecimation ( data , availableWidth ) {
4+ let i , point , x , y , prevX , minIndex , maxIndex , minY , maxY ;
5+ const decimated = [ ] ;
6+
7+ const xMin = data [ 0 ] . x ;
8+ const xMax = data [ data . length - 1 ] . x ;
9+ const dx = xMax - xMin ;
10+
11+ for ( i = 0 ; i < data . length ; ++ i ) {
12+ point = data [ i ] ;
13+ x = ( point . x - xMin ) / dx * availableWidth ;
14+ y = point . y ;
15+ const truncX = x | 0 ;
16+
17+ if ( truncX === prevX ) {
18+ // Determine `minY` / `maxY` and `avgX` while we stay within same x-position
19+ if ( y < minY ) {
20+ minY = y ;
21+ minIndex = i ;
22+ } else if ( y > maxY ) {
23+ maxY = y ;
24+ maxIndex = i ;
25+ }
26+ } else {
27+ // Push up to 4 points, 3 for the last interval and the first point for this interval
28+ if ( minIndex && maxIndex ) {
29+ decimated . push ( data [ minIndex ] , data [ maxIndex ] ) ;
30+ }
31+ if ( i > 0 ) {
32+ // Last point in the previous interval
33+ decimated . push ( data [ i - 1 ] ) ;
34+ }
35+ decimated . push ( point ) ;
36+ prevX = truncX ;
37+ minY = maxY = y ;
38+ minIndex = maxIndex = i ;
39+ }
40+ }
41+
42+ return decimated ;
43+ }
44+
345export default {
446 id : 'decimation' ,
547
48+ defaults : {
49+ algorithm : 'min-max' ,
50+ enabled : false ,
51+ } ,
52+
653 beforeElementsUpdate : ( chart , args , options ) => {
754 if ( ! options . enabled ) {
855 return ;
@@ -16,7 +63,6 @@ export default {
1663 const availableWidth = chart . width - ( verticalAxisCount * 50 ) ;
1764
1865 chart . data . datasets . forEach ( ( dataset , datasetIndex ) => {
19- let i , point , x , y , prevX , minIndex , maxIndex , minY , maxY ;
2066 const { _originalDataKey} = dataset ;
2167 const meta = chart . getDatasetMeta ( datasetIndex ) ;
2268 const dataKey = ! isNullOrUndef ( _originalDataKey ) ? _originalDataKey : meta . controller . getDataKey ( ) ;
@@ -48,44 +94,16 @@ export default {
4894 return ;
4995 }
5096
51- const decimated = [ ] ;
52-
53- const xMin = data [ 0 ] . x ;
54- const xMax = data [ data . length - 1 ] . x ;
55- const dx = xMax - xMin ;
56-
57- for ( i = 0 ; i < data . length ; ++ i ) {
58- point = data [ i ] ;
59- x = ( point . x - xMin ) / dx * availableWidth ;
60- y = point . y ;
61- const truncX = x | 0 ;
62-
63- if ( truncX === prevX ) {
64- // Determine `minY` / `maxY` and `avgX` while we stay within same x-position
65- if ( y < minY ) {
66- minY = y ;
67- minIndex = i ;
68- } else if ( y > maxY ) {
69- maxY = y ;
70- maxIndex = i ;
71- }
72- } else {
73- // Push up to 4 points, 3 for the last interval and the first point for this interval
74- if ( minIndex && maxIndex ) {
75- decimated . push ( data [ minIndex ] , data [ maxIndex ] ) ;
76- }
77- if ( i > 0 ) {
78- // Last point in the previous interval
79- decimated . push ( data [ i - 1 ] ) ;
80- }
81- decimated . push ( point ) ;
82- prevX = truncX ;
83- minY = maxY = y ;
84- minIndex = maxIndex = i ;
85- }
97+ // Point the chart to the decimated data
98+ let decimated ;
99+ switch ( options . algorithm ) {
100+ case 'min-max' :
101+ decimated = minMaxDecimation ( data , availableWidth ) ;
102+ break ;
103+ default :
104+ throw new Error ( `Unsupported decimation algorithm '${ options . algorithm } '` ) ;
86105 }
87106
88- // Point the chart to the decimated data
89107 dataset . _decimated = decimated ;
90108 dataset . dataKey = '_decimated' ;
91109 } ) ;
0 commit comments