Skip to content

Commit 5837a60

Browse files
committed
fix: improved performances for big data
1 parent 1e8e3d9 commit 5837a60

24 files changed

+183
-148
lines changed

src/charting/buffer/BarBuffer.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { AbstractBuffer } from './AbstractBuffer';
22
import { IBarDataSet } from '../interfaces/datasets/IBarDataSet';
3-
import { getEntryXValue } from '../data/BaseEntry';
43

54
export class BarBuffer extends AbstractBuffer<IBarDataSet> {
65
protected mDataSetIndex = 0;
@@ -50,15 +49,14 @@ export class BarBuffer extends AbstractBuffer<IBarDataSet> {
5049
public feed(data: IBarDataSet) {
5150
const size = data.getEntryCount() * this.phaseX;
5251
const barWidthHalf = this.mBarWidth / 2;
53-
const xKey = data.xProperty;
5452
const yKey = data.yProperty;
5553
for (let i = 0; i < size; i++) {
5654
const e = data.getEntryForIndex(i);
5755
if (e == null) {
5856
continue;
5957
}
6058

61-
const x = getEntryXValue(e, xKey, i);
59+
const x = data.getEntryXValue(e, i);
6260
let y = e[yKey];
6361
const vals = e.yVals;
6462

src/charting/buffer/HorizontalBarBuffer.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { BarBuffer } from './BarBuffer';
22
import { IBarDataSet } from '../interfaces/datasets/IBarDataSet';
3-
import { getEntryXValue } from '../data/BaseEntry';
43

54
export class HorizontalBarBuffer extends BarBuffer {
65
constructor(size: number, dataSetCount: number, containsStacks: boolean) {
@@ -10,15 +9,14 @@ export class HorizontalBarBuffer extends BarBuffer {
109
public feed(data: IBarDataSet) {
1110
const size = data.getEntryCount() * this.phaseX;
1211
const barWidthHalf = this.mBarWidth / 2;
13-
const xKey = data.xProperty;
1412
const yKey = data.yProperty;
1513
for (let i = 0; i < size; i++) {
1614
const e = data.getEntryForIndex(i);
1715
if (e == null) {
1816
continue;
1917
}
2018

21-
const x = getEntryXValue(e, xKey, i);
19+
const x = data.getEntryXValue(e, i);
2220
let y = e[yKey];
2321
const vals = e.yVals;
2422

src/charting/charts/BarChart.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { BarHighlighter } from '../highlight/BarHighlighter';
99
import { Highlight } from '../highlight/Highlight';
1010
import { BarChartRenderer } from '../renderer/BarChartRenderer';
1111
import { Canvas, Paint, RectF } from '@nativescript-community/ui-canvas';
12-
import { getEntryXValue } from '../data/BaseEntry';
1312
import { IBarDataSet } from '../interfaces/datasets/IBarDataSet';
1413
import { Color } from '@nativescript/core';
1514
import { BaseCustomRenderer } from '../renderer/DataRenderer';
@@ -117,7 +116,7 @@ export class BarChart extends BarLineChartBase<Entry, BarDataSet, BarData> imple
117116
const xKey = set.xProperty;
118117
const yKey = set.yProperty;
119118

120-
const x = getEntryXValue(e, xKey, index);
119+
const x = set.getEntryXValue(e, index);
121120
const y = e[yKey];
122121

123122
const barWidth = this.mData.getBarWidth();

src/charting/charts/HorizontalBarChart.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { HorizontalViewPortHandler } from '../utils/HorizontalViewPortHandler';
1515
import { TransformerHorizontalBarChart } from '../utils/TransformerHorizontalBarChart';
1616
import { CLog, CLogTypes, Utils } from '../utils/Utils';
1717
import { RectF } from '@nativescript-community/ui-canvas';
18-
import { getEntryXValue } from '../data/BaseEntry';
1918
import { Trace } from '@nativescript/core';
2019

2120
const LOG_TAG = 'HorizontalBarChart';
@@ -130,7 +129,7 @@ export class HorizontalBarChart extends BarChart {
130129
const xKey = set.xProperty;
131130
const yKey = set.yProperty;
132131

133-
const x = getEntryXValue(e, xKey, index);
132+
const x = set.getEntryXValue(e, index);
134133
const y = e[yKey];
135134

136135
const barWidth = this.mData.getBarWidth();

src/charting/data/BaseDataSet.ts

+15
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,25 @@ export abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
131131
this.yProperty = yProperty;
132132
}
133133

134+
if (this.xProperty === undefined || this.xProperty === null) {
135+
this.getEntryXValue = function (e: T, entryIndex: number) {
136+
return entryIndex;
137+
};
138+
} else {
139+
this.getEntryXValue = (e: T, entryIndex: number) => e[this.xProperty];
140+
}
141+
134142
this.mValueColors.push('black');
135143
this.mLabel = label;
136144
}
137145

146+
public getEntryXValue(e: T, entryIndex: number) {
147+
if (this.xProperty === undefined || this.xProperty === null) {
148+
return entryIndex;
149+
}
150+
return e[this.xProperty];
151+
}
152+
138153
/**
139154
* Use this method to tell the data set that the underlying data has changed.
140155
*/

src/charting/data/BaseEntry.ts

-7
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,3 @@ export interface BaseEntry {
99
data?: any;
1010
[k: string]: any;
1111
}
12-
13-
export function getEntryXValue(e: BaseEntry, xKey: string, entryIndex: number) {
14-
if (xKey === undefined || xKey === null) {
15-
return entryIndex;
16-
}
17-
return e[xKey];
18-
}

src/charting/data/ChartData.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Entry } from './Entry';
2-
import { getEntryXValue } from './BaseEntry';
32
import { AxisDependency } from '../components/YAxis';
43
import { IValueFormatter } from '../formatter/IValueFormatter';
54
import { Highlight } from '../highlight/Highlight';
@@ -432,7 +431,7 @@ export abstract class ChartData<U extends Entry, T extends IDataSet<U>> {
432431
protected calcMinMaxForEntry(set: IDataSet<Entry>, e: Entry, entryIndex: number, axis: AxisDependency) {
433432
const xKey = set.xProperty;
434433
const yKey = set.yProperty;
435-
const xValue = getEntryXValue(e, xKey, entryIndex);
434+
const xValue = set.getEntryXValue(e, entryIndex);
436435
const yValue = e[yKey];
437436
if (this.mYMax < yValue) this.mYMax = yValue;
438437
if (this.mYMin > yValue) this.mYMin = yValue;

src/charting/data/DataSet.ts

+28-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { ObservableArray } from '@nativescript/core';
22
import { Entry } from './Entry';
33
import { BaseDataSet } from './BaseDataSet';
4-
import { getEntryXValue } from './BaseEntry';
54
import { Utils } from '../utils/Utils';
65

76
/**
@@ -59,6 +58,7 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
5958
constructor(values, label, xProperty?, yProperty?) {
6059
super(label, xProperty, yProperty);
6160
this.mValues = values;
61+
this.updateGetEntryForIndex();
6262
}
6363

6464
toString() {
@@ -67,7 +67,7 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
6767

6868
init() {
6969
if (this.mValues == null) this.mValues = [];
70-
70+
this.updateGetEntryForIndex();
7171
if (this.mValues.length > 0) {
7272
for (let index = 0, e: T; index < this.mValues.length; index++) {
7373
e = this.getEntryForIndex(index);
@@ -131,7 +131,7 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
131131
this.calcMinMaxForEntry(e, index);
132132
}
133133
} else {
134-
const x = getEntryXValue(e, this.xProperty, index);
134+
const x = this.getEntryXValue(e, index);
135135
if (x < this.mXMin) this.mXMin = x;
136136

137137
if (x > this.mXMax) this.mXMax = x;
@@ -169,6 +169,7 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
169169
*/
170170
public setValues(values) {
171171
this.mValues = values;
172+
this.updateGetEntryForIndex();
172173
this.notifyDataSetChanged();
173174
}
174175

@@ -256,6 +257,19 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
256257
return null;
257258
}
258259

260+
protected updateGetEntryForIndex() {
261+
const internalValues = this.getInternalValues();
262+
if (internalValues instanceof ObservableArray) {
263+
this.getEntryForIndex = function (index) {
264+
return internalValues.getItem(index);
265+
};
266+
} else {
267+
this.getEntryForIndex = function (index) {
268+
return internalValues[index];
269+
};
270+
}
271+
}
272+
259273
public getEntryForIndex(index) {
260274
return this.getInternalValues() instanceof ObservableArray ? (this.getInternalValues() as ObservableArray<T>).getItem(index) : this.getInternalValues()[index];
261275
}
@@ -267,15 +281,14 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
267281
let low = 0;
268282
let high = values.length - 1;
269283
let closest = high;
270-
const xKey = this.xProperty;
271284
const yKey = this.yProperty;
272285
let m: number, e: T, e1: T;
273286
while (low < high) {
274287
m = Math.floor((low + high) / 2);
275288
e = Utils.getArrayItem(values, m);
276289
e1 = Utils.getArrayItem(values, m + 1);
277-
const d1 = getEntryXValue(e, xKey, m) - xValue,
278-
d2 = getEntryXValue(e1, xKey, m + 1) - xValue,
290+
const d1 = this.getEntryXValue(e, m) - xValue,
291+
d2 = this.getEntryXValue(e1, m + 1) - xValue,
279292
ad1 = Math.abs(d1),
280293
ad2 = Math.abs(d2);
281294

@@ -304,7 +317,7 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
304317

305318
if (closest !== -1) {
306319
let e = Utils.getArrayItem(values, closest);
307-
const closestXValue = getEntryXValue(e, xKey, closest);
320+
const closestXValue = this.getEntryXValue(e, closest);
308321
if (rounding === Rounding.UP) {
309322
// If rounding up, and found x-value is lower than specified x, and we can go upper...
310323
if (closestXValue < xValue && closest < values.length - 1) {
@@ -321,7 +334,7 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
321334
if (closest >= 1 && !isNaN(closestToY)) {
322335
e = Utils.getArrayItem(values, closest - 1);
323336
if (e) {
324-
xValue = getEntryXValue(e, xKey, closest - 1);
337+
xValue = this.getEntryXValue(e, closest - 1);
325338
while (closest > 0 && xValue === closestXValue) closest -= 1;
326339

327340
let closestYValue = Utils.getArrayItem(values, closest)[yKey];
@@ -334,7 +347,7 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
334347

335348
e = Utils.getArrayItem(values, closest);
336349
if (!e) break;
337-
xValue = getEntryXValue(e, xKey, closest);
350+
xValue = this.getEntryXValue(e, closest);
338351

339352
if (xValue !== closestXValue) break;
340353

@@ -364,17 +377,17 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
364377
while (low <= high) {
365378
m = Math.floor((high + low) / 2);
366379
e = Utils.getArrayItem(values, m);
367-
mXValue = getEntryXValue(e, xKey, m);
380+
mXValue = this.getEntryXValue(e, m);
368381
// if we have a match
369382
if (xValue === mXValue) {
370-
while (m > 0 && getEntryXValue(Utils.getArrayItem(values, m - 1), xKey, m - 1) === xValue) m--;
383+
while (m > 0 && this.getEntryXValue(Utils.getArrayItem(values, m - 1), m - 1) === xValue) m--;
371384

372385
high = values.length;
373386

374387
// loop over all "equal" entries
375388
for (; m < high; m++) {
376389
e = Utils.getArrayItem(values, m);
377-
mXValue = getEntryXValue(e, xKey, m);
390+
mXValue = this.getEntryXValue(e, m);
378391
if (mXValue === xValue) {
379392
entries.push(e);
380393
} else {
@@ -398,22 +411,21 @@ export abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
398411
let low = 0;
399412
let high = values.length - 1;
400413

401-
const xKey = this.xProperty;
402414
let entry: T, mXValue;
403415
while (low <= high) {
404416
let m = Math.floor((high + low) / 2);
405417
entry = Utils.getArrayItem(values, m);
406-
mXValue = getEntryXValue(entry, xKey, m);
418+
mXValue = this.getEntryXValue(entry, m);
407419
// if we have a match
408420
if (xValue === mXValue) {
409-
while (m > 0 && getEntryXValue(Utils.getArrayItem(values, m - 1), xKey, m - 1) === xValue) m--;
421+
while (m > 0 && this.getEntryXValue(Utils.getArrayItem(values, m - 1), m - 1) === xValue) m--;
410422

411423
high = values.length;
412424

413425
// loop over all "equal" entries
414426
for (; m < high; m++) {
415427
entry = Utils.getArrayItem(values, m);
416-
mXValue = getEntryXValue(entry, xKey, m);
428+
mXValue = this.getEntryXValue(entry, m);
417429
if (mXValue === xValue) {
418430
entries.push({ entry, index: m });
419431
} else {

src/charting/data/LineDataSet.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { DashPathEffect } from '@nativescript-community/ui-canvas';
2+
import { ObservableArray, profile } from '@nativescript/core';
23
import { Color } from '@nativescript/core/color';
34
import { createLTTB } from 'downsample/methods/LTTB';
45
import { DefaultFillFormatter } from '../formatter/DefaultFillFormatter';
@@ -90,6 +91,7 @@ export class LineDataSet extends LineRadarDataSet<Entry> implements ILineDataSet
9091

9192
protected mFilteredValues: Entry[] = null;
9293
protected mFilterFunction;
94+
@profile
9395
public applyFiltering(scaleX: number) {
9496
if (this.mMaxFilterNumber > 0 && this.mValues.length / scaleX > this.mMaxFilterNumber) {
9597
const filterCount = Math.round(this.mMaxFilterNumber * scaleX);
@@ -105,6 +107,7 @@ export class LineDataSet extends LineRadarDataSet<Entry> implements ILineDataSet
105107
} else if (this.mFilteredValues) {
106108
this.mFilteredValues = null;
107109
}
110+
this.updateGetEntryForIndex();
108111
}
109112

110113
mIgnoreFiltered = false;
@@ -116,10 +119,11 @@ export class LineDataSet extends LineRadarDataSet<Entry> implements ILineDataSet
116119
}
117120
setIgnoreFiltered(value) {
118121
this.mIgnoreFiltered = value;
122+
this.updateGetEntryForIndex();
119123
}
120124
setValues(values) {
121-
super.setValues(values);
122125
this.mFilteredValues = null;
126+
super.setValues(values);
123127
}
124128
isFiltered() {
125129
return !!this.mFilteredValues;

src/charting/highlight/BarHighlighter.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { Highlight } from './Highlight';
33
import { BarData } from '../data/BarData';
44
import { BarDataProvider } from '../interfaces/dataprovider/BarDataProvider';
55
import { IBarDataSet } from '../interfaces/datasets/IBarDataSet';
6-
import { getEntryXValue } from '../data/BaseEntry';
76

87
export class BarHighlighter extends ChartHighlighter<BarDataProvider> {
98
constructor(chart: BarDataProvider) {
@@ -52,15 +51,14 @@ export class BarHighlighter extends ChartHighlighter<BarDataProvider> {
5251

5352
const ranges = entry.ranges;
5453
if (ranges.length > 0) {
55-
const xKey = set.xProperty;
5654
const yKey = set.yProperty;
5755
const stackIndex = this.getClosestStackIndex(ranges, yVal);
5856
const pixels = this.mChart.getTransformer(set.getAxisDependency()).getPixelForValues(high.x, ranges[stackIndex][1]);
5957

6058
//MPPointD.recycleInstance(pixels);
6159

6260
return {
63-
x: getEntryXValue(entry, xKey, index),
61+
x: set.getEntryXValue(entry, index),
6462
y: entry[yKey],
6563
xPx: pixels.x,
6664
yPx: pixels.y,

src/charting/highlight/ChartHighlighter.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { AxisDependency } from '../components/YAxis';
55
import { Rounding } from '../data/DataSet';
66
import { IDataSet } from '../interfaces/datasets/IDataSet';
77
import { Entry } from '../data/Entry';
8-
import { getEntryXValue } from '../data/BaseEntry';
98
import { LineDataSet } from '../data/LineDataSet';
109

1110
export class ChartHighlighter<T extends BarLineScatterCandleBubbleDataProvider> implements IHighlighter {
@@ -133,7 +132,6 @@ export class ChartHighlighter<T extends BarLineScatterCandleBubbleDataProvider>
133132
* @return
134133
*/
135134
protected buildHighlights(set: IDataSet<Entry>, dataSetIndex, xVal, rounding) {
136-
const xKey = set.xProperty;
137135
const yKey = set.yProperty;
138136
const highlights: Highlight[] = [];
139137

@@ -144,15 +142,15 @@ export class ChartHighlighter<T extends BarLineScatterCandleBubbleDataProvider>
144142
const closest = set.getEntryAndIndexForXValue(xVal, NaN, rounding);
145143
if (closest !== null) {
146144
//noinspection unchecked
147-
entries = set.getEntriesAndIndexesForXValue(getEntryXValue(closest.entry, xKey, closest.index));
145+
entries = set.getEntriesAndIndexesForXValue(set.getEntryXValue(closest.entry, closest.index));
148146
}
149147
}
150148
if (entries.length === 0) return highlights;
151149

152150
for (const r of entries) {
153151
const e = r.entry;
154152
let index = r.index;
155-
const xVal = getEntryXValue(e, xKey, r.index);
153+
const xVal = set.getEntryXValue(e, r.index);
156154
const pixels = this.mChart.getTransformer(set.getAxisDependency()).getPixelForValues(xVal, e[yKey]);
157155
if ((set as any).isFiltered && (set as LineDataSet).isFiltered()) {
158156
(set as LineDataSet).setIgnoreFiltered(true);

0 commit comments

Comments
 (0)