diff --git a/package.json b/package.json index e016ae0c9..c9e6eaccb 100644 --- a/package.json +++ b/package.json @@ -67,8 +67,11 @@ "lint-fix": "eslint --fix ./", "prepublishOnly": "npm run build-lib && npm run dist", "screenshot": "DEBUG=app:* ./bin/screenshot.js", - "test": "torch --compile --renderer --recursive ./test/unit", - "test-live": "torch --compile --interactive --recursive ./test/unit/plugin/legend-spec.js", + "test": "npm run test-unit && npm run test-bug", + "test-bug": "torch --compile --renderer --recursive ./test/bug", + "test-bug-live": "torch --compile --interactive --recursive ./test/bug", + "test-unit": "torch --compile --renderer --recursive ./test/unit", + "test-unit-live": "torch --compile --interactive --recursive ./test/unit", "watch": "webpack --config webpack-dev.config.js" }, "pre-commit": { diff --git a/src/geom/base.js b/src/geom/base.js index d8587b5e3..39e7d1825 100644 --- a/src/geom/base.js +++ b/src/geom/base.js @@ -304,11 +304,13 @@ class Geom extends Base { const self = this; const xScale = self.getXScale(); const xField = xScale.field; - Util.each(mappedArray, itemArr => { - itemArr.sort((obj1, obj2) => { - return xScale.translate(obj1[FIELD_ORIGIN][xField]) - xScale.translate(obj2[FIELD_ORIGIN][xField]); + if (xScale.type !== 'identity' && xScale.values.length > 1) { + Util.each(mappedArray, itemArr => { + itemArr.sort((obj1, obj2) => { + return xScale.translate(obj1[FIELD_ORIGIN][xField]) - xScale.translate(obj2[FIELD_ORIGIN][xField]); + }); }); - }); + } self.set('hasSorted', true); self.set('dataArray', mappedArray); } diff --git a/src/geom/shape/interval.js b/src/geom/shape/interval.js index 0694cd4d2..d1b4270d9 100644 --- a/src/geom/shape/interval.js +++ b/src/geom/shape/interval.js @@ -81,11 +81,19 @@ Shape.registerShape('interval', 'rect', { const v1 = [ newPoints[1].x - x, newPoints[1].y - y ]; const v2 = [ newPoints[2].x - x, newPoints[2].y - y ]; - const startAngle = Vector2.angleTo(v, v1); - const endAngle = Vector2.angleTo(v, v2); + let startAngle = Vector2.angleTo(v, v1); + let endAngle = Vector2.angleTo(v, v2); const r0 = Vector2.length(v0); const r = Vector2.length(v1); + if (startAngle >= 1.5 * Math.PI) { + startAngle = startAngle - 2 * Math.PI; + } + + if (endAngle >= 1.5 * Math.PI) { + endAngle = endAngle - 2 * Math.PI; + } + return container.addShape('Sector', { className: 'interval', attrs: Util.mix({ @@ -93,7 +101,7 @@ Shape.registerShape('interval', 'rect', { y, r, r0, - startAngle: startAngle === Math.PI * 1.5 ? startAngle - Math.PI * 2 : startAngle, + startAngle, endAngle }, style) }); diff --git a/src/plugin/tooltip.js b/src/plugin/tooltip.js index dced9244c..1074ebc1b 100644 --- a/src/plugin/tooltip.js +++ b/src/plugin/tooltip.js @@ -250,8 +250,6 @@ class TooltipController { _setTooltip(point, items, tooltipMarkerCfg = {}) { const lastActive = this._lastActive; - const first = items[0]; - const title = first.title || first.name; const tooltip = this.tooltip; const cfg = this.cfg; @@ -285,11 +283,13 @@ class TooltipController { cfg.custom({ x: point.x, y: point.y, - title, + tooltip, items, tooltipMarkerCfg }); } else { + const first = items[0]; + const title = first.title || first.name; tooltip.setContent(title, items); } tooltip.setPosition(items); diff --git a/test/bug/issue-67-spec.js b/test/bug/issue-67-spec.js new file mode 100644 index 000000000..d989de273 --- /dev/null +++ b/test/bug/issue-67-spec.js @@ -0,0 +1,126 @@ +const expect = require('chai').expect; +const EventSimulate = require('event-simulate'); + +const F2 = require('../../src/core'); +require('../../src/geom/interval'); +require('../../src/coord/polar'); // 极坐标系 +require('../../src/geom/adjust/stack'); + +const canvas = document.createElement('canvas'); +canvas.width = 500; +canvas.height = 500; +canvas.id = 'getSnapRecords'; +canvas.style.position = 'fixed'; +canvas.style.top = 0; +canvas.style.left = 0; +document.body.appendChild(canvas); + +describe('getSnapRecords', () => { + let chart; + + it('自定义 color 的饼图', function(done) { + const data = [ + { uKey: '1', percent: 0.2771, const: 'const' }, + { uKey: '2', percent: 0.18083, const: 'const' }, + { uKey: '3', percent: 0.14108, const: 'const' }, + { uKey: '4', percent: 0.13868, const: 'const' }, + { uKey: '5', percent: 0.05662, const: 'const' }, + { uKey: '6', percent: 0.05523, const: 'const' }, + { uKey: '7', percent: 0.03355, const: 'const' }, + { uKey: '8', percent: 0.03079, const: 'const' }, + { uKey: '9', percent: 0.02864, const: 'const' }, + { uKey: '10', percent: 0.01879, const: 'const' }, + { uKey: '11', percent: 0.03869, const: 'const' } + ]; + chart = new F2.Chart({ + id: 'getSnapRecords', + width: 400, + height: 400 * 0.64, + pixelRatio: 2 + }); + chart.source(data); + chart.coord('polar', { + transposed: true, + inner: 0.6 + }); + chart.axis(false); + chart.interval().position('const*percent') + .color('percent', v => { + return `rgba( 255 ,0 ,0 , ${((v[1] - v[0]) * 3).toFixed(3)} )`; + }) + .adjust('stack') + .style({ + lineWidth: 1, + stroke: '#fff' + }); + chart.render(); + + let records; + canvas.onclick = ev => { + const point = chart.get('canvas').getPointByClient(ev.clientX, ev.clientY); + records = chart.getSnapRecords(point); + }; + + EventSimulate.simulate(canvas, 'click', { + clientX: 231, + clientY: 61 + }); + + setTimeout(function() { + expect(records.length).to.equal(1); + expect(records[0]._origin.uKey).to.equal('1'); + expect(records[0]._origin.percent).to.equal(0.2771); + done(); + }, 500); + }); + + it('嵌套饼图', function(done) { + chart.destroy(); + const data = [ + { a: '1', b: 0.2, c: '1' }, + { a: '2', b: 0.5, c: '1' }, + { a: '3', b: 0.4, c: '1' }, + { a: '1', b: 0.8, c: '2' }, + { a: '2', b: 0.5, c: '2' }, + { a: '3', b: 0.6, c: '2' } + ]; + chart = new F2.Chart({ + id: 'getSnapRecords', + width: 400, + height: 400 * 0.64, + pixelRatio: 2 + }); + chart.source(data); + chart.coord('polar', { + transposed: true, + inner: 0.6 + }); + chart.axis(false); + chart.interval().position('a*b') + .color('c') + .adjust('stack'); + chart.render(); + + let records; + + canvas.onclick = ev => { + const point = chart.get('canvas').getPointByClient(ev.clientX, ev.clientY); + records = chart.getSnapRecords(point); + }; + + EventSimulate.simulate(canvas, 'click', { + clientX: 277, + clientY: 71 + }); + + setTimeout(function() { + expect(records.length).to.equal(2); + expect(records[0]._origin.a).to.equal(records[1]._origin.a); + expect(records[0]._origin.b).to.equal(0.4); + expect(records[1]._origin.b).to.equal(0.6); + chart.destroy(); + document.body.removeChild(canvas); + done(); + }, 500); + }); +}); diff --git a/test/unit/geom/geom-spec.js b/test/unit/geom/geom-spec.js index 929901a2f..d3430e314 100644 --- a/test/unit/geom/geom-spec.js +++ b/test/unit/geom/geom-spec.js @@ -355,7 +355,8 @@ describe('test geom line', function() { const scaleA = new Scale.Linear({ field: 'a', min: 0, - max: 10 + max: 10, + values: [ 2, 4 ] }); const scaleB = new Scale.Linear({ field: 'b',