Skip to content

Commit

Permalink
fix: fix bug when get records in polar coordinate. Closed #83.
Browse files Browse the repository at this point in the history
  • Loading branch information
simaQ committed Apr 8, 2018
1 parent a873f4b commit 0d443a1
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 17 deletions.
24 changes: 14 additions & 10 deletions src/coord/polar.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const Base = require('./base');
const Vector2 = require('../graphic/util/vector2');
const Matrix = require('../graphic/util/matrix');

class Polar extends Base {
_initDefaultCfg() {
Expand Down Expand Up @@ -75,29 +76,32 @@ class Polar extends Base {

invertPoint(point) {
const self = this;
const center = self.center;
const transposed = self.transposed;
const { center, transposed, x, y } = self;
const xDim = transposed ? 'y' : 'x';
const yDim = transposed ? 'x' : 'y';
const x = self.x;
const y = self.y;

const startV = [ 1, 0 ];
const pointV = [ point.x - center.x, point.y - center.y ];
const m = [ 1, 0, 0, 1, 0, 0 ];
Matrix.rotate(m, m, x.start);

let startV = [ 1, 0 ];
Vector2.transformMat2d(startV, startV, m);
startV = [ startV[0], startV[1] ];

const pointV = [ point.x - center.x, point.y - center.y ];
if (Vector2.zero(pointV)) {
return {
x: 0,
y: 0
};
}

let theta = Vector2.angleTo(startV, pointV);
while (theta > x.end) {
theta = theta - 2 * Math.PI;
let theta = Vector2.angleTo(startV, pointV, x.end < x.start);
if (Math.abs(theta - Math.PI * 2) < 0.001) {
theta = 0;
}
const l = Vector2.length(pointV);
const percentX = (theta - x.start) / (x.end - x.start);
let percentX = theta / (x.end - x.start);
percentX = x.end - x.start > 0 ? percentX : -percentX;
const percentY = (l - y.start) / (y.end - y.start);
const rst = {};
rst[xDim] = percentX;
Expand Down
15 changes: 10 additions & 5 deletions src/geom/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -643,22 +643,27 @@ class Geom extends Base {
const coord = self.get('coord');
const xScale = self.getXScale();
const yScale = self.getYScale();

const xfield = xScale.field;
// const yfield = yScale.field;

const invertPoint = coord.invertPoint(point);
const dataArray = self.get('dataArray');
if (!this.get('hasSorted')) {
this._sort(dataArray);
}

let rst = [];
const tmp = [];
let xValue = xScale.invert(invertPoint.x);
const invertPoint = coord.invertPoint(point);
let invertPointX = invertPoint.x;
if (self.isInCircle() && !coord.transposed && invertPointX > (1 + xScale.rangeMax()) / 2) {
invertPointX = xScale.rangeMin(); // 极坐标下,scale 的 range 被做过特殊处理 see chart.js#L183
}

let xValue = xScale.invert(invertPointX);
if (!xScale.isCategory) {
xValue = self._getSnap(xScale, xValue);
}

const tmp = [];

dataArray.forEach(function(data) {
data.forEach(function(obj) {
const originValue = Util.isNil(obj[FIELD_ORIGIN]) ? obj[xfield] : obj[FIELD_ORIGIN][xfield];
Expand Down
185 changes: 185 additions & 0 deletions test/bug/issue-83-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
const expect = require('chai').expect;
const EventSimulate = require('event-simulate');

const F2 = require('../../src/core');
require('../../src/geom/line');
require('../../src/coord/polar'); // 极坐标系
require('../../src/component/axis/circle'); // 极坐标系
require('../../src/geom/adjust/stack');

const canvas = document.createElement('canvas');
canvas.width = 500;
canvas.height = 500;
canvas.id = 'radar';
canvas.style.position = 'fixed';
canvas.style.top = 0;
canvas.style.left = 0;
document.body.appendChild(canvas);

describe('issue 83', () => {
let chart;

it('radar', function(done) {
const data = [
{ item: 'Design', user: '用户 A', score: 70 },
{ item: 'Design', user: '用户 B', score: 30 },
{ item: 'Development', user: '用户 A', score: 60 },
{ item: 'Development', user: '用户 B', score: 70 },
{ item: 'Marketing', user: '用户 A', score: 50 },
{ item: 'Marketing', user: '用户 B', score: 60 },
{ item: 'Users', user: '用户 A', score: 40 },
{ item: 'Users', user: '用户 B', score: 50 },
{ item: 'Test', user: '用户 A', score: 60 },
{ item: 'Test', user: '用户 B', score: 70 },
{ item: 'Language', user: '用户 A', score: 70 },
{ item: 'Language', user: '用户 B', score: 50 },
{ item: 'Technology', user: '用户 A', score: 70 },
{ item: 'Technology', user: '用户 B', score: 40 },
{ item: 'Support', user: '用户 A', score: 60 },
{ item: 'Support', user: '用户 B', score: 40 }
];
chart = new F2.Chart({
id: 'radar',
width: 300,
height: 300,
pixelRatio: 2
});

chart.coord('polar');
chart.source(data, {
score: {
min: 0,
max: 120,
nice: false,
tickCount: 4
}
});
chart.axis('score', {
label(text, index, total) {
if (index === total - 1) {
return null;
}
return {
top: true
};
},
grid(text) {
if (text === '120') {
return {
lineDash: null
};
}
},
line: {
top: false
}
});
chart.line().position('item*score').color('user');
chart.render();

let records;
canvas.onclick = ev => {
records = chart.getSnapRecords({
x: ev.clientX,
y: ev.clientY
});
};

EventSimulate.simulate(canvas, 'click', {
clientX: 135,
clientY: 99
});

setTimeout(function() {
expect(records.length).to.equal(2);
expect(records[0]._origin.item).to.equal('Design');
expect(records[1]._origin.item).to.equal('Design');
done();
}, 500);
});

it('radar, set startAngle and endAngle', function(done) {
chart.destroy();
const data = [
{ item: 'Design', user: '用户 A', score: 70 },
{ item: 'Design', user: '用户 B', score: 30 },
{ item: 'Development', user: '用户 A', score: 60 },
{ item: 'Development', user: '用户 B', score: 70 },
{ item: 'Marketing', user: '用户 A', score: 50 },
{ item: 'Marketing', user: '用户 B', score: 60 },
{ item: 'Users', user: '用户 A', score: 40 },
{ item: 'Users', user: '用户 B', score: 50 },
{ item: 'Test', user: '用户 A', score: 60 },
{ item: 'Test', user: '用户 B', score: 70 },
{ item: 'Language', user: '用户 A', score: 70 },
{ item: 'Language', user: '用户 B', score: 50 },
{ item: 'Technology', user: '用户 A', score: 70 },
{ item: 'Technology', user: '用户 B', score: 40 },
{ item: 'Support', user: '用户 A', score: 60 },
{ item: 'Support', user: '用户 B', score: 40 }
];
chart = new F2.Chart({
id: 'radar',
width: 300,
height: 300,
pixelRatio: 2
});

chart.coord('polar', {
startAngle: 3 * Math.PI / 2,
endAngle: -Math.PI / 2
});
chart.source(data, {
score: {
min: 0,
max: 120,
nice: false,
tickCount: 4
}
});
chart.axis('score', {
label(text, index, total) {
if (index === total - 1) {
return null;
}
return {
top: true
};
},
grid(text) {
if (text === '120') {
return {
lineDash: null
};
}
},
line: {
top: false
}
});
chart.line().position('item*score').color('user');
chart.render();

let records;
canvas.onclick = ev => {
records = chart.getSnapRecords({
x: ev.clientX,
y: ev.clientY
});
};

EventSimulate.simulate(canvas, 'click', {
clientX: 192,
clientY: 132
});
setTimeout(function() {
expect(records.length).to.equal(2);
expect(records[0]._origin.item).to.equal('Technology');
expect(records[1]._origin.item).to.equal('Technology');
chart.destroy();
document.body.removeChild(canvas);
done();
}, 500);

});
});
5 changes: 3 additions & 2 deletions test/unit/coord/circle-spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const expect = require('chai').expect;
const Plot = require('../../../src/chart/plot');
const Coord = require('../../../src/coord/index');

const gMath = {
equal(v1, v2) {
return Math.abs(v1 - v2) < 0.001;
Expand Down Expand Up @@ -59,12 +60,12 @@ describe('coord circle', function() {
it('invertPoint', function() {
let p = { x: 200, y: 100 };
p = circle.invertPoint(p);
expect(p.x).to.be.equal(1);
expect(p.x).to.be.equal(0);
expect(p.y).to.be.equal(0);

p = { x: 200, y: 0 };
p = circle.invertPoint(p);
expect(p.x).to.be.equal(1);
expect(p.x).to.be.equal(0);
expect(p.y).to.be.equal(1);

p = { x: 50, y: 200 };
Expand Down

0 comments on commit 0d443a1

Please sign in to comment.