Skip to content

Commit

Permalink
feat: 算法优化
Browse files Browse the repository at this point in the history
  • Loading branch information
cycgit committed Aug 12, 2020
1 parent cff266f commit cd412e3
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 71 deletions.
77 changes: 25 additions & 52 deletions src/scale/linear-tick.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
const DDEFAULT_COUNT = 5; // 默认刻度值

export default cfg => {
const { min, max, tickCount, tickInterval } = cfg || {};
const count = tickCount || DDEFAULT_COUNT;

if (max === min || count === 1) {
return [];
const { min, max, tickCount, tickInterval } = cfg || {};
const count = tickCount && tickCount >= 2 ? tickCount : DDEFAULT_COUNT;

// 异常值处理
if (max === min) {
const interval = min / 2;
return [
fixedBase(min - interval, interval),
min,
fixedBase(min + interval, interval)
];
}

// 1.计算平均刻度间隔
const avgInterval = (max - min) / (count - 1);

// 2.转化成1~10的刻度间隔值
// 2.数据标准归一化 映射到[1-10]区间
const factor = getFactor(avgInterval);

// 3.获取满足tickCount的情况下,最优刻度值
const interval = tickInterval || getBestInterval({ tickCount: count, avgInterval, max, min, factor });
const minTickPosition = Math.ceil(Math.abs(min / interval));
const minTick = min > 0 ? minTickPosition * interval : -minTickPosition * interval;

let tickLength = 0;
// 4.获取最小刻度线
const minTick = fixedBase(Math.floor(min / interval) * interval, interval);

let tickLength = 0;
const ticks = [];
while (minTick + tickLength * interval < max) {
ticks.push(fixedBase(minTick + tickLength * interval, interval));
Expand Down Expand Up @@ -65,49 +74,20 @@ function getBestInterval({ tickCount, avgInterval, max, min, factor }) {
const calMax = max / factor;
const calMin = min / factor;

// 相似数
let similarityInterval;
let similarityIndex;
// 根据平均值推算最逼近刻度值
let similarityInterval = 1;
let similarityIndex = 0;

for (let index = 0; index < SNAP_COUNT_ARRAY.length; index++) {
const item = SNAP_COUNT_ARRAY[index];
const nextItem = SNAP_COUNT_ARRAY[index + 1];
if (index === 0 && item <= calInterval) {
similarityInterval = item;
similarityIndex = 0;
}

// last
if (index === SNAP_COUNT_ARRAY.length - 1 && item <= calInterval) {
if (calInterval <= item) {
similarityInterval = item;
similarityIndex = index;
}

if (index <= SNAP_COUNT_ARRAY.length - 2) {
if (calInterval >= item && calInterval < nextItem) {
// 取更加逼近的刻度
if (Math.abs(calInterval - item) > Math.abs(calInterval - nextItem)) {
similarityInterval = nextItem;
similarityIndex = index + 1;
} else {
similarityInterval = item;
similarityIndex = index;
}
}
break;
}
}

// 是否满足刻度需求
if (intervalIsVerify({ interval: similarityInterval, tickCount, max: calMax, min: calMin })) {
return fixedBase(similarityInterval * factor, factor);
}

// 最后一个接直接返回
if (similarityIndex === SNAP_COUNT_ARRAY.length - 1) {
return fixedBase(similarityInterval * factor, factor);
}

similarityIndex++;
// 刻度值校验,如果不满足,循环下去
while (similarityIndex < SNAP_COUNT_ARRAY.length) {
if (intervalIsVerify({ interval: SNAP_COUNT_ARRAY[similarityIndex], tickCount, max: calMax, min: calMin })) {
similarityInterval = SNAP_COUNT_ARRAY[similarityIndex];
Expand All @@ -121,17 +101,10 @@ function getBestInterval({ tickCount, avgInterval, max, min, factor }) {

// 刻度是否满足展示需求
function intervalIsVerify({ interval, tickCount, max, min }) {
const maxRange = max - min;

// 上下要预留间距
const maxTickPosition = Math.abs(max) % interval > 0 ? 1 : 0;
const minTickPosition = Math.abs(min) % interval > 0 ? 1 : 0;
const space = (maxTickPosition + minTickPosition) * interval;

if (interval * tickCount - maxRange - space >= 0) {
const minTick = Math.floor(min / interval) * interval;
if (minTick + tickCount * interval >= max) {
return true;
}

return false;
}

Expand Down
2 changes: 1 addition & 1 deletion test/bug/issue-179-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('issue 179', () => {
});
chart.repaint();
const yScale = chart.getYScales()[0];
expect(yScale.max).to.equal(160000);
expect(yScale.max).to.equal(120000);

const zeroPosition = chart.getPosition({
season: '第一季',
Expand Down
8 changes: 4 additions & 4 deletions test/unit/interaction/pan-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ describe('chart pan', function() {
expect(xScale.values).toEqual([ '6', '7', '8' ]);
});

it('with scrollbar', function() {
it('with scrollbar', function(done) {
chart.clear();
chart.registerPlugins(ScrollBar);
chart.source(data, {
Expand Down Expand Up @@ -332,11 +332,11 @@ describe('chart pan', function() {
interaction._doMove(120, 0);
const hBar = chart.get('_horizontalBar');
const highlightLine = hBar.get('children')[1];
expect(highlightLine.attr('x1')).toBeCloseTo(58.70168585526316, 2);
expect(highlightLine.attr('x2')).toBeCloseTo(242.8284333881579, 2);
expect(highlightLine.attr('x1')).toBeCloseTo(50.79789011101974, 2);
expect(highlightLine.attr('x2')).toBeCloseTo(239.75473504317432, 2);
chart.destroy();
document.body.removeChild(canvas);
// done();
done();
}, 300);
});
});
11 changes: 6 additions & 5 deletions test/unit/interaction/pinch-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('Pinch', function() {
chart.line().position('x1*y');
chart.render();

it('pinch start, process, end', function() {
it('pinch start, process, end', function(done) {
const pinch = new Pinch({
maxScale: 4,
minScale: 1
Expand Down Expand Up @@ -99,7 +99,7 @@ describe('Pinch', function() {
pinch.end(eventObj);
expect(pinch.currentPinchScaling).to.be.null;
expect(pinch.pinchCumulativeDelta).to.equal(0);
// done();
done();
}, 1000);
});
});
Expand Down Expand Up @@ -157,13 +157,14 @@ describe('chart pinch', function() {
interaction._doZoom(0.15, point, 'xy');

const limitRange = interaction.limitRange;

expect(limitRange).to.eql({
x1: {
min: 0,
max: 19
},
y: {
min: 3,
min: 0,
max: 20
}
});
Expand All @@ -172,13 +173,13 @@ describe('chart pinch', function() {
expect(xScale.max).to.equal(24.8);

const yScale = chart.getYScales()[0];
expect(yScale.min).to.equal(-4.6499999999999995);
expect(yScale.min).to.equal(-10.2);
expect(yScale.max).to.equal(26.8);

const xRange = interaction.xRange;
const yRange = interaction.yRange;
expect(xRange).to.eql([ 0.33157894736842103, 1.305263157894737 ]);
expect(yRange).to.eql([ -0.44999999999999996, 1.4000000000000001 ]);
expect(yRange).to.eql([ -0.51, 1.34 ]);
});

it('pinch x axis, and x field is a cat type', function(done) {
Expand Down
2 changes: 1 addition & 1 deletion test/unit/plugin/interval-label-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe('IntervalLabel', () => {

const labelShape = children[0];
expect(labelShape.get('attrs').text).toBe('浏览网站');
expect(labelShape.get('attrs').x).toBeCloseTo(210.9375, 3);
expect(labelShape.get('attrs').x).toBeCloseTo(248.125, 3);
expect(labelShape.get('attrs').y).toBeCloseTo(280, 3);
});

Expand Down
9 changes: 4 additions & 5 deletions test/unit/plugin/tooltip-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -405,22 +405,21 @@ describe('Tooltip crosshairs', function() {
expect(crosshairsShapeY).not.to.be.undefined;
expect(snapEqual(crosshairsShapeY.get('x'), 235.2777777777778)).to.be.true;

expect(snapEqual(crosshairsShapeX.get('y'), 204.848393875713)).to.be.true;
expect(snapEqual(crosshairsShapeX.get('y'), 204.726)).to.be.true;

expect(tooltip.xTipBox.y).to.equal(291);
expect(tooltip.xTipBox.content).to.equal('date:2018-04-26');
expect(snapEqual(tooltip.yTipBox.x, 21.6845703125)).to.be.true;
expect(tooltip.yTipBox.content).to.equal(10586);


chart.showTooltip({
x: point.x,
y: point.y + 20
});

expect(snapEqual(tooltipController.tooltip.crosshairsShapeX.get('y'), 224.848393875713)).to.be.true;
expect(snapEqual(tooltipController.tooltip.crosshairsShapeX.get('y'), 224.726)).to.be.true;
expect(snapEqual(tooltip.yTipBox.x, 18.34765625)).to.be.true;
expect(tooltip.yTipBox.content).to.equal(8365);
expect(tooltip.yTipBox.content).to.equal(8363);
});

it('show xTip and yTip, snap = false', () => {
Expand Down Expand Up @@ -470,7 +469,7 @@ describe('Tooltip crosshairs', function() {
expect(xTip).not.to.be.undefined;
expect(yTip).not.to.be.undefined;
expect(xTip.content).to.equal('2018-04-21');
expect(yTip.content).to.equal(29091);
expect(yTip.content).to.equal(29112);
expect(snapEqual(xTip.x, 85.99139404296875)).to.be.true;
expect(xTip.y).to.equal(276.5);
// expect(snapEqual(yTip.x, 29.06072998046875)).to.be.true;
Expand Down
24 changes: 21 additions & 3 deletions test/unit/scale/linear-tick-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ describe('linear-tick', function() {
min: -560,
max: -100
});
expect(tick).toEqual([ -640, -480, -320, -160, 0 ]);

expect(tick).toEqual([ -600, -480, -360, -240, -120, 0 ]);

});

Expand All @@ -45,13 +46,30 @@ describe('linear-tick', function() {
expect(tick).toEqual([ 0, 200, 400 ]);
});

it('max === min', function() {
it('[11, 50]', function() {
const tick = linearTick({
max: 50,
min: 11
});

expect(tick).toEqual([ 10, 20, 30, 40, 50 ]);
});

it('max === min 350', function() {
const tick = linearTick({
min: 350,
max: 350,
tickInterval: 200
});
expect(tick).toEqual([]);
expect(tick).toEqual([ 175, 350, 525 ]);
});

it('max === min 0.00000', function() {
const tick = linearTick({
min: 0.000005,
max: 0.000005
});
expect(tick).toEqual([ 0.0000025, 0.000005, 0.0000075 ]);
});

});

0 comments on commit cd412e3

Please sign in to comment.