Skip to content

Commit 8a7ce83

Browse files
Chart: fix visibility algorithm for candlestick points (T1304112) (DevExpress#30821)
1 parent 5a2d8ed commit 8a7ce83

File tree

2 files changed

+53
-35
lines changed

2 files changed

+53
-35
lines changed

packages/devextreme/js/viz/series/points/candlestick_point.js

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ const _round = _math.round;
1111
const DEFAULT_FINANCIAL_TRACKER_MARGIN = 2;
1212

1313
export default _extend({}, barPoint, {
14-
_calculateVisibility: symbolPoint._calculateVisibility,
15-
1614
_getContinuousPoints: function(openCoord, closeCoord) {
1715
const that = this;
1816
const x = that.x;
@@ -265,19 +263,23 @@ export default _extend({}, barPoint, {
265263
},
266264

267265
_translate: function() {
268-
const that = this;
269-
const rotated = that._options.rotated;
270-
const valTranslator = that._getValTranslator();
271-
const x = that._getArgTranslator().translate(that.argument);
266+
const valTranslator = this._getValTranslator();
267+
const x = this._getArgTranslator().translate(this.argument);
272268

273-
that.vx = that.vy = that.x = x === null ? x : x + (that.xCorrection || 0);
274-
that.openY = that.openValue !== null ? valTranslator.translate(that.openValue) : null;
275-
that.highY = valTranslator.translate(that.highValue);
276-
that.lowY = valTranslator.translate(that.lowValue);
277-
that.closeY = that.closeValue !== null ? valTranslator.translate(that.closeValue) : null;
269+
this.vx = this.vy = this.x = x === null ? x : x + (this.xCorrection || 0);
270+
this.openY = this.openValue !== null ? valTranslator.translate(this.openValue) : null;
271+
this.highY = valTranslator.translate(this.highValue);
272+
this.lowY = valTranslator.translate(this.lowValue);
273+
this.closeY = this.closeValue !== null ? valTranslator.translate(this.closeValue) : null;
278274

279-
const centerValue = _min(that.lowY, that.highY) + _abs(that.lowY - that.highY) / 2;
280-
that._calculateVisibility(!rotated ? that.x : centerValue, !rotated ? centerValue : that.x);
275+
const minValue = Math.min(this.lowY, this.highY);
276+
const height = Math.abs(this.lowY - this.highY);
277+
278+
if(this._options.rotated) {
279+
this._calculateVisibility(minValue, this.x, height, 0);
280+
} else {
281+
this._calculateVisibility(this.x, minValue, 0, height);
282+
}
281283
},
282284

283285
getCrosshairData: function(x, y) {

packages/devextreme/testing/tests/DevExpress.viz.core.series/financialPoint.tests.js

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -462,13 +462,13 @@ QUnit.test('Negative. LowValue', function(assert) {
462462
assert.strictEqual(result, false);
463463
});
464464

465-
QUnit.module('Check point in visible area', {
465+
QUnit.module('Check point in visible area (T1304112)', {
466466
beforeEach: function() {
467467
const that = this;
468468

469469
const visibleArea = [0, 100, 1000, 1100];
470470
const translateXData = { 1: -10, 2: visibleArea[0], 3: 50, 4: visibleArea[1], 5: 110 };
471-
const translateYData = { 1: 990, 2: visibleArea[2], 3: 1010, 4: 1040, 5: 1050, 6: 1090, 7: visibleArea[3], 8: 1110 };
471+
const translateYData = { 0: 980, 1: 990, 2: visibleArea[2], 3: 1010, 4: 1040, 5: 1050, 6: 1090, 7: visibleArea[3], 8: 1110, 9: 1120 };
472472

473473
this.options = {
474474
widgetType: 'chart',
@@ -535,38 +535,46 @@ QUnit.test('Point is visible on the right border', function(assert) {
535535
});
536536

537537
QUnit.test('Point is invisible on the top', function(assert) {
538-
this.point = createPoint(this.series, { argument: 3, openValue: 7, closeValue: 8, highValue: 8, lowValue: 7 }, this.options);
538+
this.point = createPoint(this.series, { argument: 3, openValue: 8, closeValue: 9, highValue: 9, lowValue: 8 }, this.options);
539539
this.point.translate();
540540

541-
assert.ok(!this.point.isInVisibleArea());
541+
assert.strictEqual(this.point.isInVisibleArea(), false);
542542
});
543543

544544
QUnit.test('Point is visible on the top border', function(assert) {
545-
this.point = createPoint(this.series, { argument: 3, openValue: 6, closeValue: 8, highValue: 8, lowValue: 6 }, this.options);
546-
this.point.translate();
545+
const point = createPoint(this.series, { argument: 3, openValue: 6, closeValue: 8, highValue: 8, lowValue: 6 }, this.options);
546+
const point2 = createPoint(this.series, { argument: 3, openValue: 7, closeValue: 8, highValue: 8, lowValue: 7 }, this.options);
547547

548-
assert.ok(this.point.isInVisibleArea());
548+
point.translate();
549+
point2.translate();
550+
551+
assert.strictEqual(point.isInVisibleArea(), true, 'Point is visible if center of point is inside visible area');
552+
assert.strictEqual(point2.isInVisibleArea(), true, 'Point is visible if lowValue is inside visible area');
549553
});
550554

551555
QUnit.test('Point is invisible on the bottom', function(assert) {
552-
this.point = createPoint(this.series, { argument: 3, openValue: 1, closeValue: 2, highValue: 2, lowValue: 1 }, this.options);
556+
this.point = createPoint(this.series, { argument: 3, openValue: 0, closeValue: 1, highValue: 1, lowValue: 0 }, this.options);
553557
this.point.translate();
554558

555559
assert.ok(!this.point.isInVisibleArea());
556560
});
557561

558562
QUnit.test('Point is visible on the bottom border', function(assert) {
559-
this.point = createPoint(this.series, { argument: 3, openValue: 1, closeValue: 3, highValue: 3, lowValue: 1 }, this.options);
560-
this.point.translate();
563+
const point = createPoint(this.series, { argument: 3, openValue: 1, closeValue: 3, highValue: 3, lowValue: 1 }, this.options);
564+
const point2 = createPoint(this.series, { argument: 3, openValue: 1, closeValue: 2, highValue: 2, lowValue: 1 }, this.options);
561565

562-
assert.ok(this.point.isInVisibleArea());
566+
point.translate();
567+
point2.translate();
568+
569+
assert.strictEqual(point.isInVisibleArea(), true, 'Point is visible if center of point is inside visible area');
570+
assert.strictEqual(point2.isInVisibleArea(), true, 'Point is visible if highValue is inside visible area');
563571
});
564572

565-
QUnit.module('Check point in visible area. Rotated.', {
573+
QUnit.module('Check point in visible area (T1304112). Rotated.', {
566574
beforeEach: function() {
567575
const that = this;
568576
const visibleArea = [0, 100, 0, 100];
569-
const translateXData = { 1: -10, 2: visibleArea[0], 3: 10, 4: 40, 5: 50, 6: 90, 7: visibleArea[1], 8: 110 };
577+
const translateXData = { 0: -20, 1: -10, 2: visibleArea[0], 3: 10, 4: 40, 5: 50, 6: 90, 7: visibleArea[1], 8: 110, 9: 120 };
570578
const translateYData = { 1: -10, 2: visibleArea[2], 3: 50, 4: visibleArea[3], 5: 110 };
571579

572580
this.options = {
@@ -635,31 +643,39 @@ QUnit.test('Point is visible on the right border', function(assert) {
635643
});
636644

637645
QUnit.test('Point is invisible on the top', function(assert) {
638-
this.point = createPoint(this.series, { argument: 3, openValue: 7, closeValue: 8, highValue: 8, lowValue: 7 }, this.options);
646+
this.point = createPoint(this.series, { argument: 3, openValue: 8, closeValue: 9, highValue: 9, lowValue: 8 }, this.options);
639647
this.point.translate();
640648

641-
assert.ok(!this.point.isInVisibleArea());
649+
assert.strictEqual(this.point.isInVisibleArea(), false);
642650
});
643651

644652
QUnit.test('Point is visible on the top border', function(assert) {
645-
this.point = createPoint(this.series, { argument: 3, openValue: 6, closeValue: 8, highValue: 8, lowValue: 6 }, this.options);
646-
this.point.translate();
653+
const point = createPoint(this.series, { argument: 3, openValue: 6, closeValue: 8, highValue: 8, lowValue: 6 }, this.options);
654+
const point2 = createPoint(this.series, { argument: 3, openValue: 7, closeValue: 8, highValue: 8, lowValue: 7 }, this.options);
647655

648-
assert.ok(this.point.isInVisibleArea());
656+
point.translate();
657+
point2.translate();
658+
659+
assert.strictEqual(point.isInVisibleArea(), true, 'Point is visible if center of point is inside visible area');
660+
assert.strictEqual(point2.isInVisibleArea(), true, 'Point is visible if lowValue is inside visible area');
649661
});
650662

651663
QUnit.test('Point is invisible on the bottom', function(assert) {
652-
this.point = createPoint(this.series, { argument: 3, openValue: 1, closeValue: 2, highValue: 2, lowValue: 1 }, this.options);
664+
this.point = createPoint(this.series, { argument: 3, openValue: 0, closeValue: 1, highValue: 1, lowValue: 0 }, this.options);
653665
this.point.translate();
654666

655667
assert.ok(!this.point.isInVisibleArea());
656668
});
657669

658670
QUnit.test('Point is visible on the bottom border', function(assert) {
659-
this.point = createPoint(this.series, { argument: 3, openValue: 1, closeValue: 3, highValue: 3, lowValue: 1 }, this.options);
660-
this.point.translate();
671+
const point = createPoint(this.series, { argument: 3, openValue: 1, closeValue: 3, highValue: 3, lowValue: 1 }, this.options);
672+
const point2 = createPoint(this.series, { argument: 3, openValue: 1, closeValue: 2, highValue: 2, lowValue: 1 }, this.options);
661673

662-
assert.ok(this.point.isInVisibleArea());
674+
point.translate();
675+
point2.translate();
676+
677+
assert.strictEqual(point.isInVisibleArea(), true, 'Point is visible if center of point is inside visible area');
678+
assert.strictEqual(point2.isInVisibleArea(), true, 'Point is visible if highValue is inside visible area');
663679
});
664680

665681
QUnit.module('Draw point. Candlestick', {

0 commit comments

Comments
 (0)