1
1
import { Canvas , Direction , FillType , Matrix , Paint , Path , Style , createImage , releaseImage } from '@nativescript-community/ui-canvas' ;
2
- import { ImageSource , profile } from '@nativescript/core' ;
2
+ import { Color , ImageSource , profile } from '@nativescript/core' ;
3
3
import { ChartAnimator } from '../animation/ChartAnimator' ;
4
4
import { LineChart } from '../charts' ;
5
5
import { getEntryXValue } from '../data/BaseEntry' ;
@@ -124,6 +124,23 @@ export class LineChartRenderer extends LineRadarRenderer {
124
124
protected linePath = new Path ( ) ;
125
125
protected fillPath = new Path ( ) ;
126
126
127
+ /**
128
+ * cache for the circle bitmaps of all datasets
129
+ */
130
+ private mImageCaches = new Map < ILineDataSet , DataSetImageCache > ( ) ;
131
+
132
+ /**
133
+ * buffer for drawing the circles
134
+ */
135
+ private mCirclesBuffer : [ number , number ] ;
136
+
137
+ private get circlesBuffer ( ) {
138
+ if ( ! this . mCirclesBuffer ) {
139
+ this . mCirclesBuffer = Utils . createNativeArray ( 2 ) ;
140
+ }
141
+ return this . mCirclesBuffer ;
142
+ }
143
+
127
144
constructor ( chart : LineChart , animator : ChartAnimator , viewPortHandler : ViewPortHandler ) {
128
145
super ( animator , viewPortHandler ) ;
129
146
this . mChart = chart ;
@@ -137,7 +154,7 @@ export class LineChartRenderer extends LineRadarRenderer {
137
154
this . mCirclePaintInner . setColor ( 'white' ) ;
138
155
}
139
156
140
- public initBuffers ( ) { }
157
+ public initBuffers ( ) { }
141
158
142
159
@profile
143
160
public drawData ( c : Canvas ) {
@@ -539,12 +556,23 @@ export class LineChartRenderer extends LineRadarRenderer {
539
556
lastDrawnIndex -= 1 ;
540
557
}
541
558
}
559
+ let fillMin = drawFilled && useColorsForFill ? dataSet . getFillFormatter ( ) . getFillLinePosition ( dataSet , this . mChart ) : undefined ;
560
+ if ( fillMin !== undefined ) {
561
+ // to make things faster we wont transform the path again
562
+ // so we need get fillMin as pixel value
563
+ // let's use circlesBuffer for this
564
+ const circleBuffer = this . circlesBuffer ;
565
+ circleBuffer [ 0 ] = 0 ;
566
+ circleBuffer [ 1 ] = fillMin ;
567
+ trans . pointValuesToPixel ( circleBuffer ) ;
568
+ fillMin = circleBuffer [ 1 ] ;
569
+ }
542
570
colorsToBeDrawn . forEach ( ( color ) => {
543
571
this . linePath . setLines ( points , color . startIndex * 2 , color . nbItems * 2 ) ;
544
572
if ( drawFilled && useColorsForFill ) {
545
573
this . fillPath . reset ( ) ;
546
574
this . fillPath . addPath ( this . linePath ) ;
547
- this . drawFill ( c , dataSet , this . fillPath , null , points [ color . startIndex * 2 ] , points [ ( color . startIndex + color . nbItems - 1 ) * 2 ] , color ) ;
575
+ this . drawFill ( c , dataSet , this . fillPath , null , points [ color . startIndex * 2 ] , points [ ( color . startIndex + color . nbItems - 1 ) * 2 ] , color . color , fillMin ) ;
548
576
}
549
577
if ( drawLine ) {
550
578
this . mRenderPaint . setColor ( color . color ) ;
@@ -565,9 +593,10 @@ export class LineChartRenderer extends LineRadarRenderer {
565
593
}
566
594
}
567
595
568
- protected drawFill ( c : Canvas , dataSet : ILineDataSet , spline : Path , trans : Transformer , min : number , max : number , color ?) {
569
- const fillMin = dataSet . getFillFormatter ( ) . getFillLinePosition ( dataSet , this . mChart ) ;
570
-
596
+ protected drawFill ( c : Canvas , dataSet : ILineDataSet , spline : Path , trans : Transformer , min : number , max : number , color ?, fillMin ?: number ) {
597
+ if ( fillMin === undefined ) {
598
+ fillMin = dataSet . getFillFormatter ( ) . getFillLinePosition ( dataSet , this . mChart ) ;
599
+ }
571
600
spline . lineTo ( max , fillMin ) ;
572
601
spline . lineTo ( min , fillMin ) ;
573
602
spline . close ( ) ;
@@ -656,16 +685,6 @@ export class LineChartRenderer extends LineRadarRenderer {
656
685
this . drawCircles ( c ) ;
657
686
}
658
687
659
- /**
660
- * cache for the circle bitmaps of all datasets
661
- */
662
- private mImageCaches = new Map < ILineDataSet , DataSetImageCache > ( ) ;
663
-
664
- /**
665
- * buffer for drawing the circles
666
- */
667
- private mCirclesBuffer = Utils . createNativeArray ( 2 ) ;
668
-
669
688
@profile
670
689
protected drawCirclesForDataset ( c : Canvas , dataSet : LineDataSet ) {
671
690
this . mCirclePaintInner . setColor ( dataSet . getCircleHoleColor ( ) ) ;
@@ -699,36 +718,41 @@ export class LineChartRenderer extends LineRadarRenderer {
699
718
}
700
719
701
720
const boundsRangeCount = this . mXBounds . range + this . mXBounds . min ;
702
-
721
+ const circleBuffer = this . circlesBuffer ;
703
722
for ( let j = this . mXBounds . min ; j <= boundsRangeCount ; j ++ ) {
704
723
const e = dataSet . getEntryForIndex ( j ) ;
705
724
706
725
if ( e == null ) continue ;
707
726
708
- this . mCirclesBuffer [ 0 ] = getEntryXValue ( e , xKey , j ) ;
709
- this . mCirclesBuffer [ 1 ] = e [ yKey ] * phaseY ;
727
+ circleBuffer [ 0 ] = getEntryXValue ( e , xKey , j ) ;
728
+ circleBuffer [ 1 ] = e [ yKey ] * phaseY ;
710
729
711
- trans . pointValuesToPixel ( this . mCirclesBuffer ) ;
730
+ trans . pointValuesToPixel ( circleBuffer ) ;
731
+ // native buffer access is slow
732
+ const cx = circleBuffer [ 0 ] ;
733
+ const cy = circleBuffer [ 1 ] ;
712
734
713
- if ( ! this . mViewPortHandler . isInBoundsRight ( this . mCirclesBuffer [ 0 ] ) ) break ;
735
+ if ( ! this . mViewPortHandler . isInBoundsRight ( cx ) ) break ;
714
736
715
- if ( ! this . mViewPortHandler . isInBoundsLeft ( this . mCirclesBuffer [ 0 ] ) || ! this . mViewPortHandler . isInBoundsY ( this . mCirclesBuffer [ 1 ] ) ) continue ;
737
+ if ( ! this . mViewPortHandler . isInBoundsLeft ( cx ) || ! this . mViewPortHandler . isInBoundsY ( cy ) ) continue ;
716
738
717
739
const circleBitmap = imageCache . getBitmap ( j ) ;
718
740
719
741
if ( circleBitmap != null ) {
720
- c . drawBitmap ( circleBitmap , this . mCirclesBuffer [ 0 ] - circleRadius , this . mCirclesBuffer [ 1 ] - circleRadius , null ) ;
742
+ c . drawBitmap ( circleBitmap , cx - circleRadius , cy - circleRadius , null ) ;
721
743
}
722
744
}
723
745
}
724
746
725
747
protected drawCircles ( c : Canvas ) {
726
- this . mRenderPaint . setStyle ( Style . FILL ) ;
727
-
728
- this . mCirclesBuffer [ 0 ] = 0 ;
729
- this . mCirclesBuffer [ 1 ] = 0 ;
730
-
731
748
const dataSets = this . mChart . getLineData ( ) . getVisibleDataSets ( ) ;
749
+ if ( dataSets . some ( ( d ) => d . isDrawCirclesEnabled ( ) ) === false ) {
750
+ return ;
751
+ }
752
+ this . mRenderPaint . setStyle ( Style . FILL ) ;
753
+ const circleBuffer = this . circlesBuffer ;
754
+ circleBuffer [ 0 ] = 0 ;
755
+ circleBuffer [ 1 ] = 0 ;
732
756
733
757
for ( let i = 0 ; i < dataSets . length ; i ++ ) {
734
758
const dataSet = dataSets [ i ] ;
0 commit comments