Skip to content

Commit 2f9c169

Browse files
committed
feat: axis iggnoreOffsets and barchart custom renderer
1 parent 942eab0 commit 2f9c169

12 files changed

+234
-128
lines changed

src/charting/buffer/BarBuffer.ts

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

45
export class BarBuffer extends AbstractBuffer<IBarDataSet> {
56
protected mDataSetIndex = 0;
@@ -49,15 +50,16 @@ export class BarBuffer extends AbstractBuffer<IBarDataSet> {
4950
public feed(data: IBarDataSet) {
5051
const size = data.getEntryCount() * this.phaseX;
5152
const barWidthHalf = this.mBarWidth / 2;
52-
53+
const xKey = data.xProperty;
54+
const yKey = data.yProperty;
5355
for (let i = 0; i < size; i++) {
5456
const e = data.getEntryForIndex(i);
5557
if (e == null) {
5658
continue;
5759
}
5860

59-
const x = e[data.xProperty];
60-
let y = e[data.yProperty];
61+
const x = getEntryXValue(e, xKey, i);
62+
let y = e[yKey];
6163
const vals = e.yVals;
6264

6365
if (!this.mContainsStacks || vals == null || vals.length === 0) {
@@ -66,11 +68,11 @@ export class BarBuffer extends AbstractBuffer<IBarDataSet> {
6668
let bottom, top;
6769

6870
if (this.mInverted) {
69-
bottom = y >= 0 ? y : (this.mYAxisMax <= 0 ? this.mYAxisMax : 0);
70-
top = y <= 0 ? y : (this.mYAxisMin >= 0 ? this.mYAxisMin : 0);
71+
bottom = y >= 0 ? y : this.mYAxisMax <= 0 ? this.mYAxisMax : 0;
72+
top = y <= 0 ? y : this.mYAxisMin >= 0 ? this.mYAxisMin : 0;
7173
} else {
72-
top = y >= 0 ? y : (this.mYAxisMax <= 0 ? this.mYAxisMax : 0);
73-
bottom = y <= 0 ? y : (this.mYAxisMin >= 0 ? this.mYAxisMin : 0);
74+
top = y >= 0 ? y : this.mYAxisMax <= 0 ? this.mYAxisMax : 0;
75+
bottom = y <= 0 ? y : this.mYAxisMin >= 0 ? this.mYAxisMin : 0;
7476
}
7577

7678
// multiply the height of the rect with the phase

src/charting/buffer/HorizontalBarBuffer.ts

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

45
export class HorizontalBarBuffer extends BarBuffer {
56
constructor(size: number, dataSetCount: number, containsStacks: boolean) {
@@ -9,27 +10,28 @@ export class HorizontalBarBuffer extends BarBuffer {
910
public feed(data: IBarDataSet) {
1011
const size = data.getEntryCount() * this.phaseX;
1112
const barWidthHalf = this.mBarWidth / 2;
12-
13+
const xKey = data.xProperty;
14+
const yKey = data.yProperty;
1315
for (let i = 0; i < size; i++) {
1416
const e = data.getEntryForIndex(i);
1517
if (e == null) {
1618
continue;
1719
}
1820

19-
const x = e[data.xProperty];
20-
let y = e[data.yProperty];
21+
const x = getEntryXValue(e, xKey, i);
22+
let y = e[yKey];
2123
const vals = e.yVals;
2224

2325
if (!this.mContainsStacks || vals == null) {
2426
const bottom = x - barWidthHalf;
2527
const top = x + barWidthHalf;
2628
let left, right;
2729
if (this.mInverted) {
28-
left = y >= 0 ? y : (this.mYAxisMax <= 0 ? this.mYAxisMax : 0);
29-
right = y <= 0 ? y : (this.mYAxisMin >= 0 ? this.mYAxisMin : 0);
30+
left = y >= 0 ? y : this.mYAxisMax <= 0 ? this.mYAxisMax : 0;
31+
right = y <= 0 ? y : this.mYAxisMin >= 0 ? this.mYAxisMin : 0;
3032
} else {
31-
right = y >= 0 ? y : (this.mYAxisMax <= 0 ? this.mYAxisMax : 0);
32-
left = y <= 0 ? y : (this.mYAxisMin >= 0 ? this.mYAxisMin : 0);
33+
right = y >= 0 ? y : this.mYAxisMax <= 0 ? this.mYAxisMax : 0;
34+
left = y <= 0 ? y : this.mYAxisMin >= 0 ? this.mYAxisMin : 0;
3335
}
3436

3537
// multiply the height of the rect with the phase

src/charting/charts/BarChart.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { BarDataSet } from '../data/BarDataSet';
88
import { BarHighlighter } from '../highlight/BarHighlighter';
99
import { Highlight } from '../highlight/Highlight';
1010
import { BarChartRenderer } from '../renderer/BarChartRenderer';
11-
import { RectF } from '@nativescript-community/ui-canvas';
11+
import { Canvas, Paint, RectF } from '@nativescript-community/ui-canvas';
1212
import { getEntryXValue } from '../data/BaseEntry';
1313

1414
const LOG_TAG = 'BarChart';
@@ -31,6 +31,8 @@ export class BarChart extends BarLineChartBase<Entry, BarDataSet, BarData> imple
3131
*/
3232
private mDrawBarShadow = false;
3333

34+
private mCustomBarRenderer: (c: Canvas, e: BarEntry, left: number, top: number, right: number, bottom: number, paint: Paint) => void;
35+
3436
protected init() {
3537
super.init();
3638

@@ -202,6 +204,19 @@ export class BarChart extends BarLineChartBase<Entry, BarDataSet, BarData> imple
202204
this.mFitBars = enabled;
203205
}
204206

207+
/**
208+
* set a custom bar renderer
209+
*/
210+
public setCustomBarRenderer(func: (c: Canvas, e: BarEntry, left: number, top: number, right: number, bottom: number, paint: Paint) => void) {
211+
this.mCustomBarRenderer = func;
212+
}
213+
/**
214+
* get the custom bar renderer
215+
*/
216+
public getCustomBarRenderer() {
217+
return this.mCustomBarRenderer;
218+
}
219+
205220
/**
206221
* Groups all BarDataSet objects this data object holds together by modifying the x-value of their entries.
207222
* Previously set x-values of entries will be overwritten. Leaves space between bars and groups as specified

src/charting/charts/Chart.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { IMarker } from '../components/IMarker';
1616
import { LegendRenderer } from '../renderer/LegendRenderer';
1717
import { IHighlighter } from '../highlight/IHighlighter';
1818
import { profile } from '@nativescript/core/profiling';
19-
import { ChartAnimator } from '../animation/ChartAnimator';
19+
import { ChartAnimator, EasingFunction } from '../animation/ChartAnimator';
2020
import { ViewPortJob } from '../jobs/ViewPortJob';
2121
import { ChartTouchListener } from '../listener/ChartTouchListener';
2222
import { layout } from '@nativescript/core/utils/utils';
@@ -800,7 +800,7 @@ export abstract class Chart<U extends Entry, D extends IDataSet<U>, T extends Ch
800800
* @param easingX a custom easing function to be used on the animation phase
801801
* @param easingY a custom easing function to be used on the animation phase
802802
*/
803-
public animateXY(durationMillisX, durationMillisY, easingX?, easingY?) {
803+
public animateXY(durationMillisX, durationMillisY, easingX?: EasingFunction, easingY?: EasingFunction) {
804804
this.mAnimator.animateXY(durationMillisX, durationMillisY, easingX, easingY);
805805
}
806806

@@ -813,7 +813,7 @@ export abstract class Chart<U extends Entry, D extends IDataSet<U>, T extends Ch
813813
* @param durationMillis
814814
* @param easing a custom easing function to be used on the animation phase
815815
*/
816-
public animateX(durationMillis, easing?) {
816+
public animateX(durationMillis, easing?: EasingFunction) {
817817
this.mAnimator.animateX(durationMillis, easing);
818818
}
819819

@@ -826,7 +826,7 @@ export abstract class Chart<U extends Entry, D extends IDataSet<U>, T extends Ch
826826
* @param durationMillis
827827
* @param easing a custom easing function to be used on the animation phase
828828
*/
829-
public animateY(durationMillis, easing?) {
829+
public animateY(durationMillis, easing?: EasingFunction) {
830830
this.mAnimator.animateY(durationMillis, easing);
831831
}
832832

src/charting/components/AxisBase.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ export abstract class AxisBase extends ComponentBase {
157157
* the total range of values this axis covers
158158
*/
159159
public mAxisRange = 0;
160+
/**
161+
* the total range of values this axis covers
162+
*/
163+
public mIgnoreOffsets = false;
160164

161165
/**
162166
* default constructor
@@ -203,6 +207,23 @@ export abstract class AxisBase extends ComponentBase {
203207
public isDrawAxisLineEnabled() {
204208
return this.mDrawAxisLine;
205209
}
210+
/**
211+
* Set this to true to draw axis ignoring viewport offsets
212+
*
213+
* @param enabled
214+
*/
215+
public setIgnoreOffsets(enabled) {
216+
this.mIgnoreOffsets = enabled;
217+
}
218+
219+
/**
220+
* Returns true if we draw axis ignoring viewport offsets
221+
*
222+
* @return
223+
*/
224+
public isIgnoringOffsets() {
225+
return this.mIgnoreOffsets;
226+
}
206227

207228
/**
208229
* Centers the axis labels instead of drawing them at their original position.
@@ -526,7 +547,7 @@ export abstract class AxisBase extends ComponentBase {
526547
* @param phase offset, in degrees (normally, use 0)
527548
*/
528549
public enableGridDashedLine(lineLength, spaceLength, phase) {
529-
this.mGridDashPathEffect = new DashPathEffect([lineLength, spaceLength],phase);
550+
this.mGridDashPathEffect = new DashPathEffect([lineLength, spaceLength], phase);
530551
}
531552
/**
532553
* Enables the grid line to be drawn in dashed mode, e.g. like this

src/charting/renderer/AxisRenderer.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ export abstract class AxisRenderer extends Renderer {
117117
// calculate the starting and entry polet of the y-labels (depending on
118118
// zoom / contentrect bounds)
119119
if (this.mViewPortHandler != null && this.mViewPortHandler.contentWidth() > 10 && !this.mViewPortHandler.isFullyZoomedOutY()) {
120-
121-
const p1 = this.mTrans.getValuesByTouchPoint(this.mViewPortHandler.contentLeft(), this.mViewPortHandler.contentTop());
122-
const p2 = this.mTrans.getValuesByTouchPoint(this.mViewPortHandler.contentLeft(), this.mViewPortHandler.contentBottom());
120+
const rect = this.mAxis.isIgnoringOffsets() ? this.mViewPortHandler.getChartRect() : this.mViewPortHandler.getContentRect();
121+
const p1 = this.mTrans.getValuesByTouchPoint(rect.left, rect.top);
122+
const p2 = this.mTrans.getValuesByTouchPoint(rect.left, rect.bottom);
123123

124124
if (!inverted) {
125125

src/charting/renderer/BarChartRenderer.ts

+14-9
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
138138
this.mRenderPaint.setColor(dataSet.getColor());
139139
}
140140

141+
const customRender = this.mChart.getCustomBarRenderer();
141142
for (let j = 0; j < buffer.size(); j += 4) {
142143
if (!this.mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) {
143144
continue;
@@ -146,17 +147,21 @@ export class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
146147
if (!this.mViewPortHandler.isInBoundsRight(buffer.buffer[j])) {
147148
break;
148149
}
150+
if (customRender) {
151+
const e = dataSet.getEntryForIndex(j / 4);
152+
customRender(c, e, buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], this.mRenderPaint);
153+
} else {
154+
if (!isSingleColor) {
155+
// Set the color for the currently drawn value. If the index
156+
// is out of bounds, reuse colors.
157+
this.mRenderPaint.setColor(dataSet.getColor(j / 4));
158+
}
149159

150-
if (!isSingleColor) {
151-
// Set the color for the currently drawn value. If the index
152-
// is out of bounds, reuse colors.
153-
this.mRenderPaint.setColor(dataSet.getColor(j / 4));
154-
}
155-
156-
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], this.mRenderPaint);
160+
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], this.mRenderPaint);
157161

158-
if (drawBorder) {
159-
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], this.mBarBorderPaint);
162+
if (drawBorder) {
163+
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], this.mBarBorderPaint);
164+
}
160165
}
161166
}
162167

0 commit comments

Comments
 (0)