Skip to content

Commit 82389a2

Browse files
committed
feat: Proper visualization of negative Y values for bar charts.
1 parent b26e2c7 commit 82389a2

File tree

5 files changed

+43
-31
lines changed

5 files changed

+43
-31
lines changed

demo/app/examples/NSChart.js

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ exports.onBarChartLoaded = function(args)
3939
chart.setScaleEnabled(true);
4040
chart.setDragEnabled(true);
4141
chart.getAxisRight().setEnabled(false);
42-
//chart.getAxisLeft().setInverted(true);
4342
// chart.setHardwareAccelerationEnabled(true);
4443

4544
const data = new Array(5).fill(0).map(function(v, i)

src/charting/buffer/BarBuffer.ts

+11-6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export class BarBuffer extends AbstractBuffer<IBarDataSet> {
1111
protected mBarWidth = 1;
1212

1313
protected mYAxisMin = 0;
14+
protected mYAxisMax = 0;
1415

1516
constructor(size: number, dataSetCount: number, containsStacks: boolean) {
1617
super(size);
@@ -34,6 +35,10 @@ export class BarBuffer extends AbstractBuffer<IBarDataSet> {
3435
this.mYAxisMin = min;
3536
}
3637

38+
public setYAxisMax(max: number) {
39+
this.mYAxisMax = max;
40+
}
41+
3742
protected addBar(left, top, right, bottom) {
3843
this.buffer[this.index++] = left;
3944
this.buffer[this.index++] = top;
@@ -61,11 +66,11 @@ export class BarBuffer extends AbstractBuffer<IBarDataSet> {
6166
let bottom, top;
6267

6368
if (this.mInverted) {
64-
bottom = y;
65-
top = y <= this.mYAxisMin ? y : this.mYAxisMin;
69+
bottom = y >= 0 ? y : (this.mYAxisMax <= 0 ? this.mYAxisMax : 0);
70+
top = y <= 0 ? y : (this.mYAxisMin >= 0 ? this.mYAxisMin : 0);
6671
} else {
67-
top = y;
68-
bottom = y <= this.mYAxisMin ? y : this.mYAxisMin;
72+
top = y >= 0 ? y : (this.mYAxisMax <= 0 ? this.mYAxisMax : 0);
73+
bottom = y <= 0 ? y : (this.mYAxisMin >= 0 ? this.mYAxisMin : 0);
6974
}
7075

7176
// multiply the height of the rect with the phase
@@ -105,10 +110,10 @@ export class BarBuffer extends AbstractBuffer<IBarDataSet> {
105110

106111
if (this.mInverted) {
107112
bottom = y >= yStart ? y : yStart;
108-
top = y <= this.mYAxisMin ? y : this.mYAxisMin;
113+
top = y <= yStart ? y : yStart;
109114
} else {
110115
top = y >= yStart ? y : yStart;
111-
bottom = y <= this.mYAxisMin ? y : this.mYAxisMin;
116+
bottom = y <= yStart ? y : yStart;
112117
}
113118

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

src/charting/buffer/HorizontalBarBuffer.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ export class HorizontalBarBuffer extends BarBuffer {
2525
const top = x + barWidthHalf;
2626
let left, right;
2727
if (this.mInverted) {
28-
left = y;
29-
right = y <= this.mYAxisMin ? y : this.mYAxisMin;
28+
left = y >= 0 ? y : (this.mYAxisMax <= 0 ? this.mYAxisMax : 0);
29+
right = y <= 0 ? y : (this.mYAxisMin >= 0 ? this.mYAxisMin : 0);
3030
} else {
31-
right = y;
32-
left = y <= this.mYAxisMin ? y : this.mYAxisMin;
31+
right = y >= 0 ? y : (this.mYAxisMax <= 0 ? this.mYAxisMax : 0);
32+
left = y <= 0 ? y : (this.mYAxisMin >= 0 ? this.mYAxisMin : 0);
3333
}
3434

3535
// multiply the height of the rect with the phase
@@ -63,10 +63,10 @@ export class HorizontalBarBuffer extends BarBuffer {
6363
let left, right;
6464
if (this.mInverted) {
6565
left = y >= yStart ? y : yStart;
66-
right = y <= this.mYAxisMin ? y : this.mYAxisMin;
66+
right = y <= yStart ? y : yStart;
6767
} else {
6868
right = y >= yStart ? y : yStart;
69-
left = y <= this.mYAxisMin ? y : this.mYAxisMin;
69+
left = y <= yStart ? y : yStart;
7070
}
7171

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

src/charting/renderer/BarChartRenderer.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ export class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
124124
buffer.setInverted(this.mChart.isInverted(dataSet.getAxisDependency()));
125125
buffer.setBarWidth(this.mChart.getBarData().getBarWidth());
126126
buffer.setYAxisMin(this.mChart.getAxis(dataSet.getAxisDependency()).getAxisMinimum());
127+
buffer.setYAxisMax(this.mChart.getAxis(dataSet.getAxisDependency()).getAxisMaximum());
127128

128129
buffer.feed(dataSet);
129130

@@ -226,23 +227,23 @@ export class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
226227
break;
227228
}
228229

229-
if (!this.mViewPortHandler.isInBoundsY(buffer.buffer[j + (isInverted ? 3 : 1)]) || !this.mViewPortHandler.isInBoundsLeft(x)) {
230-
continue;
231-
}
232-
233230
const entry = dataSet.getEntryForIndex(j / 4);
234231
const val = entry[yKey];
235232

233+
if (!this.mViewPortHandler.isInBoundsY(buffer.buffer[j + (val >= 0 ? 1 : 3)]) || !this.mViewPortHandler.isInBoundsLeft(x)) {
234+
continue;
235+
}
236+
236237
if (dataSet.isDrawValuesEnabled()) {
237-
this.drawValue(c, formatter.getBarLabel(entry, dataSet), x, isInverted ? (buffer.buffer[j + 3] - negOffset) : (buffer.buffer[j + 1] + posOffset),
238-
dataSet.getValueTextColor(j / 4));
238+
this.drawValue(c, formatter.getBarLabel(entry, dataSet), x, val >= 0 ?
239+
(buffer.buffer[j + 1] + posOffset) : (buffer.buffer[j + 3] + negOffset), dataSet.getValueTextColor(j / 4));
239240
}
240241

241242
if (entry.icon != null && dataSet.isDrawIconsEnabled()) {
242243
const icon = entry.icon;
243244

244245
let px = x;
245-
let py = isInverted ? (buffer.buffer[j + 3] - negOffset) : (buffer.buffer[j + 1] + posOffset);
246+
let py = val >= 0 ? (buffer.buffer[j + 1] + posOffset) : (buffer.buffer[j + 3] + negOffset);
246247

247248
px += iconsOffset.x;
248249
py += iconsOffset.y;
@@ -274,19 +275,20 @@ export class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
274275
break;
275276
}
276277

277-
if (!this.mViewPortHandler.isInBoundsY(buffer.buffer[bufferIndex + (isInverted ? 3 : 1)]) || !this.mViewPortHandler.isInBoundsLeft(x)) {
278+
if (!this.mViewPortHandler.isInBoundsY(buffer.buffer[bufferIndex + (entry[yKey] >= 0 ? 1 : 3)]) || !this.mViewPortHandler.isInBoundsLeft(x)) {
278279
continue;
279280
}
280281

281282
if (dataSet.isDrawValuesEnabled()) {
282-
this.drawValue(c, formatter.getBarLabel(entry, dataSet), x, isInverted ? (buffer.buffer[bufferIndex + 3] - negOffset) : (buffer.buffer[bufferIndex + 1] + posOffset), color);
283+
this.drawValue(c, formatter.getBarLabel(entry, dataSet), x, entry[yKey] >= 0 ?
284+
(buffer.buffer[bufferIndex + 1] + posOffset) : (buffer.buffer[bufferIndex + 3] + negOffset), color);
283285
}
284286

285287
if (entry.icon != null && dataSet.isDrawIconsEnabled()) {
286288
const icon = entry.icon;
287289

288290
let px = x;
289-
let py = isInverted ? (buffer.buffer[bufferIndex + 3] - negOffset) : (buffer.buffer[bufferIndex + 1] + posOffset);
291+
let py = entry[yKey] >= 0 ? (buffer.buffer[bufferIndex + 1] + posOffset) : (buffer.buffer[bufferIndex + 3] + negOffset);
290292

291293
px += iconsOffset.x;
292294
py += iconsOffset.y;

src/charting/renderer/HorizontalBarChartRenderer.ts

+14-8
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export class HorizontalBarChartRenderer extends BarChartRenderer {
8080
buffer.setInverted(this.mChart.isInverted(dataSet.getAxisDependency()));
8181
buffer.setBarWidth(this.mChart.getBarData().getBarWidth());
8282
buffer.setYAxisMin(this.mChart.getAxis(dataSet.getAxisDependency()).getAxisMinimum());
83+
buffer.setYAxisMax(this.mChart.getAxis(dataSet.getAxisDependency()).getAxisMaximum());
8384

8485
buffer.feed(dataSet);
8586

@@ -161,16 +162,17 @@ export class HorizontalBarChartRenderer extends BarChartRenderer {
161162
break;
162163
}
163164

164-
if (!this.mViewPortHandler.isInBoundsX(buffer.buffer[isInverted ? (j + 2) : j])) {
165+
const entry = dataSet.getEntryForIndex(j / 4);
166+
const val = entry[yKey];
167+
168+
if (!this.mViewPortHandler.isInBoundsX(buffer.buffer[j + (val >= 0 ? 0 : 2)])) {
165169
continue;
166170
}
167171

168172
if (!this.mViewPortHandler.isInBoundsBottom(buffer.buffer[j + 1])) {
169173
continue;
170174
}
171175

172-
const entry = dataSet.getEntryForIndex(j / 4);
173-
const val = entry[yKey];
174176
const formattedValue = formatter.getBarLabel(entry, dataSet);
175177

176178
// calculate the correct offset depending on the draw position of the value
@@ -184,13 +186,15 @@ export class HorizontalBarChartRenderer extends BarChartRenderer {
184186
}
185187

186188
if (dataSet.isDrawValuesEnabled()) {
187-
this.drawValue(c, formattedValue, isInverted ? (buffer.buffer[j] - negOffset) : (buffer.buffer[j + 2] + posOffset), y + halfTextHeight, dataSet.getValueTextColor(j / 2));
189+
this.drawValue(c, formattedValue,
190+
val >= 0 ? (buffer.buffer[j + 2] + posOffset) : (buffer.buffer[j + 0] + negOffset),
191+
y + halfTextHeight, dataSet.getValueTextColor(j / 2));
188192
}
189193

190194
if (entry.icon != null && dataSet.isDrawIconsEnabled()) {
191195
const icon = entry.icon;
192196

193-
let px = isInverted ? (buffer.buffer[j] - negOffset) : (buffer.buffer[j + 2] + posOffset);
197+
let px = val >= 0 ? (buffer.buffer[j + 2] + posOffset) : (buffer.buffer[j + 0] + negOffset);
194198
let py = y;
195199

196200
px += iconsOffset.x;
@@ -221,7 +225,7 @@ export class HorizontalBarChartRenderer extends BarChartRenderer {
221225
break;
222226
}
223227

224-
if (!this.mViewPortHandler.isInBoundsX(buffer.buffer[isInverted ? (bufferIndex + 2) : bufferIndex])) {
228+
if (!this.mViewPortHandler.isInBoundsX(buffer.buffer[bufferIndex + (entry[yKey] >= 0 ? 0 : 2)])) {
225229
continue;
226230
}
227231

@@ -242,13 +246,15 @@ export class HorizontalBarChartRenderer extends BarChartRenderer {
242246
}
243247

244248
if (dataSet.isDrawValuesEnabled()) {
245-
this.drawValue(c, formattedValue, isInverted ? (buffer.buffer[bufferIndex] - negOffset) : (buffer.buffer[bufferIndex + 2] + posOffset), buffer.buffer[bufferIndex + 1] + halfTextHeight, color);
249+
this.drawValue(c, formattedValue,
250+
entry[yKey] >= 0 ? (buffer.buffer[bufferIndex + 2] + posOffset) : (buffer.buffer[bufferIndex + 0] + negOffset),
251+
buffer.buffer[bufferIndex + 1] + halfTextHeight, color);
246252
}
247253

248254
if (entry.icon != null && dataSet.isDrawIconsEnabled()) {
249255
const icon = entry.icon;
250256

251-
let px = isInverted ? (buffer.buffer[bufferIndex] - negOffset) : (buffer.buffer[bufferIndex + 2] + posOffset);
257+
let px = entry[yKey] >= 0 ? (buffer.buffer[bufferIndex + 2] + posOffset) : (buffer.buffer[bufferIndex + 0] + negOffset);
252258
let py = buffer.buffer[bufferIndex + 1];
253259

254260
px += iconsOffset.x;

0 commit comments

Comments
 (0)