From 9b0169b3947c41e7478d46a9b1d809c958b8ab30 Mon Sep 17 00:00:00 2001 From: dxq613 Date: Mon, 4 Dec 2017 12:58:43 +0800 Subject: [PATCH] fix(chart): fixed bug of #15, getSnapRecords of pie --- src/chart/chart.js | 15 ++++++++++ src/geom/base.js | 66 +++++++++++++++++++++--------------------- src/util.js | 20 +++++++++++++ test/demos/area.js | 6 ++++ test/demos/interval.js | 7 +++++ test/demos/pie.js | 12 ++++++++ 6 files changed, 93 insertions(+), 33 deletions(-) diff --git a/src/chart/chart.js b/src/chart/chart.js index 3bf238f3e..6f39b9cb6 100644 --- a/src/chart/chart.js +++ b/src/chart/chart.js @@ -208,6 +208,21 @@ class Chart extends Base { }); } + /** + * 根据clientX, clientY获取画布上坐标 + * @param {Number} clientX 事件获取的窗口坐标 x + * @param {Number} clientY 事件获取的窗口坐标 y + * @return {Object} 对应的坐标 + */ + getPointByClient(clientX, clientY) { + const canvas = this.get('canvas'); + const bbox = canvas.getBoundingClientRect(); + return { + x: clientX - bbox.left, + y: clientY - bbox.top + }; + } + /** * 获取画布上坐标对应的数据值 * @param {Object} point 画布坐标的x,y的值 diff --git a/src/geom/base.js b/src/geom/base.js index 4ca3ab7b2..82c2c6096 100644 --- a/src/geom/base.js +++ b/src/geom/base.js @@ -7,6 +7,7 @@ const Util = require('../util'); const Base = require('../base'); const GROUP_ATTRS = [ 'color', 'size', 'shape' ]; const FIELD_ORIGIN = '_origin'; +const FIELD_ORIGIN_Y = '_originY'; const Global = require('../global'); const Attr = require('../attr/index'); const Shape = require('./shape/shape'); @@ -347,12 +348,15 @@ class Geom extends Base { _mapping(data) { const self = this; const attrs = self.get('attrs'); + const yField = self.getYScale().field; const mappedData = []; for (let i = 0; i < data.length; i++) { const record = data[i]; const newRecord = {}; newRecord[FIELD_ORIGIN] = record[FIELD_ORIGIN]; newRecord.points = record.points; + // 避免 + newRecord[FIELD_ORIGIN_Y] = record[yField]; for (const k in attrs) { if (attrs.hasOwnProperty(k)) { const attr = attrs[k]; @@ -584,17 +588,14 @@ class Geom extends Base { return this.get('adjust') === adjust; } - _getSnap(scale, item) { + _getSnap(scale, item, arr) { let i = 0; let values; const yField = this.getYScale().field; // 叠加的维度 if (this.hasAdjust('stack') && scale.field === yField) { - const dataArray = this.get('dataArray'); values = []; - dataArray.forEach(function(subArray) { - subArray.forEach(function(obj) { - values.push(obj[scale.field]); - }); + arr.forEach(function(obj) { + values.push(obj[FIELD_ORIGIN_Y]); }); for (; i < values.length; i++) { @@ -638,17 +639,16 @@ class Geom extends Base { /** * 根据画布坐标获取切割线对应数据集 * @param {Object} point 画布坐标的x,y的值 - * @param {String} [field] 指定逼近的字段 * @return {Array} 切割交点对应数据集 **/ - getSnapRecords(point, field) { + getSnapRecords(point) { const self = this; const coord = self.get('coord'); const xScale = self.getXScale(); const yScale = self.getYScale(); const xfield = xScale.field; - const yfield = yScale.field; + // const yfield = yScale.field; const invertPoint = coord.invertPoint(point); const dataArray = self.get('dataArray'); @@ -657,34 +657,34 @@ class Geom extends Base { this.set('hasSorted', true); } - const rst = []; + let rst = []; + const tmp = []; + let xValue = xScale.invert(invertPoint.x); + if (!xScale.isCategory) { + xValue = self._getSnap(xScale, xValue); + } + dataArray.forEach(function(data) { + data.forEach(function(obj) { + const originValue = Util.isNull(obj[FIELD_ORIGIN]) ? obj[xfield] : obj[FIELD_ORIGIN][xfield]; + if (self._isEqual(originValue, xValue, xScale)) { + tmp.push(obj); + } + }); + }); - if (field === yfield) { - let yData = yScale.invert(invertPoint.y); - if (!yScale.isCategory) { - yData = self._getSnap(yScale, yData); - } - dataArray.forEach(function(data) { - data.forEach(function(obj) { - if (Util.isArray(yData) ? Util.equalsArray(obj[yfield], yData) : obj[yfield] === yData) { - rst.push(obj); - } - }); + // 特别针对饼图做处理 + if (this.hasAdjust('stack') && coord.isPolar && coord.transposed && xScale.values.length === 1) { + let yValue = yScale.invert(invertPoint.y); + yValue = self._getSnap(yScale, yValue, tmp); + tmp.forEach(function(obj) { + if (Util.isArray(yValue) ? Util.Array.equals(obj[FIELD_ORIGIN_Y], yValue) : obj[FIELD_ORIGIN_Y] === yValue) { + rst.push(obj); + } }); } else { - let xData = xScale.invert(invertPoint.x); - if (!xScale.isCategory) { - xData = self._getSnap(xScale, xData); - } - dataArray.forEach(function(data) { - data.forEach(function(obj) { - const originValue = Util.isNull(obj[FIELD_ORIGIN]) ? obj[xfield] : obj[FIELD_ORIGIN][xfield]; - if (self._isEqual(originValue, xData, xScale)) { - rst.push(obj); - } - }); - }); + rst = tmp; } + return rst; } diff --git a/src/util.js b/src/util.js index 8d1c42f17..92c8698fd 100644 --- a/src/util.js +++ b/src/util.js @@ -339,6 +339,26 @@ Util.Array = { if (index !== -1) { arr.splice(index, 1); } + }, + equals(a1, a2) { + if (a1 === a2) { + return true; + } + if (!a1 || !a2) { + return false; + } + + if (a1.length !== a2.length) { + return false; + } + let rst = true; + for (let i = 0; i < a1.length; i++) { + if (a1[i] !== a2[i]) { + rst = false; + break; + } + } + return rst; } }; diff --git a/test/demos/area.js b/test/demos/area.js index 4c5ba2aa5..84d8afaf3 100644 --- a/test/demos/area.js +++ b/test/demos/area.js @@ -72,6 +72,12 @@ describe('area', () => { opacity: 0.6 }); chart.render(); + + canvas.onclick = function(ev) { + const point = chart.getPointByClient(ev.clientX, ev.clientY); + const records = chart.getSnapRecords(point, 'b'); + console.log(records); + }; }); describe('area stack', () => { diff --git a/test/demos/interval.js b/test/demos/interval.js index c7803b842..23a471f81 100644 --- a/test/demos/interval.js +++ b/test/demos/interval.js @@ -35,6 +35,7 @@ describe('interval', () => { }); chart.interval().position('city*tem').color('city'); chart.render(); + }); describe('range', () => { @@ -139,6 +140,12 @@ describe('interval', () => { .color('city') .adjust('stack'); chart.render(); + + canvas.onclick = function(ev) { + const point = chart.getPointByClient(ev.clientX, ev.clientY); + const records = chart.getSnapRecords(point, 'b'); + console.log(records); + }; }); describe('interval dodge', () => { diff --git a/test/demos/pie.js b/test/demos/pie.js index 523f51a5c..5069edb1b 100644 --- a/test/demos/pie.js +++ b/test/demos/pie.js @@ -52,6 +52,13 @@ describe('polar', () => { .color('c') .adjust('stack'); chart.render(); + + canvas.onclick = function(ev) { + const point = chart.getPointByClient(ev.clientX, ev.clientY); + const records = chart.getSnapRecords(point, 'b'); + console.log(records); + }; + }); describe('nest', () => { @@ -82,6 +89,11 @@ describe('polar', () => { .color('c') .adjust('stack'); chart.render(); + canvas.onclick = function(ev) { + const point = chart.getPointByClient(ev.clientX, ev.clientY); + const records = chart.getSnapRecords(point, 'b'); + console.log(records); + }; }); describe('rose', () => {