Permalink
Browse files

feat: support syncY property to unify multiple Y-axis data ranges. Re…

…lated to #258.
  • Loading branch information...
simaQ committed Aug 17, 2018
1 parent 3a12928 commit 854685e829b160583cf62ede0a9faf621a572e75
Showing with 119 additions and 128 deletions.
  1. +33 −105 demos/multiple-y-guide.html
  2. +43 −20 src/chart/chart.js
  3. +0 −1 test/bug/issue-257-spec.js
  4. +43 −2 test/unit/chart/chart-spec.js
@@ -12,111 +12,39 @@
<script src="./assets/jquery-3.2.1.min.js"></script>
<script src="../build/f2-all.js"></script>
<script>
var data = [
{ time: "周一", tem: 6.9, rain: 10 },
{ time: "周二", tem: 9.5, rain: 13 },
{ time: "周三", tem: 14.5, rain: 14 },
{ time: "周四", tem: 18.2, rain: 10 },
{ time: "周五", tem: 21.5, rain: 12 },
{ time: "周六", tem: 25.2, rain: 16 },
{ time: "周日", tem: 26.5, rain: 13 }
];
var chart = new F2.Chart({
id: "mountNode",
width: window.innerWidth,
height: window.innerWidth * 0.64,
pixelRatio: window.devicePixelRatio
});
chart.source(data, {
tem: {
tickCount: 5,
max: 30,
min: 0
},
rain: {
tickCount: 5,
min: 0,
max: 30
}
});
chart.animate({
'guide-line': {
appear: {
animation(shape, animateCfg) {
const attrs = shape.attr();
console.log(shape.get('index'));
const { x1, x2, y1, y2 } = attrs;
shape.attr('x2', x1);
shape.animate().to(F2.Util.mix({
attrs: {
x2
}
}, animateCfg));
},
duration: 1000,
delay: 1000
}
}
});
// 配置刻度文字大小,供PC端显示用(移动端可以使用默认值20px)
chart.axis("time", {
label: {
fontSize: 14
},
grid: null
});
chart.axis("tem", {
label: {
fontSize: 14
},
});
chart.axis("rain", {
label: {
fontSize: 14
}
});
chart.interval().position("time*tem");
chart
.line()
.position("time*rain")
.color("#5ed470")
.size(2)
.shape("smooth");
chart
.point()
.position("time*rain")
.color("#5ed470");
chart.guide().line({
start(xScale, yScales) {
let sum = 0;
// console.log(xScale, yScales);
const yScale = yScales[1];
yScale.values.forEach(v => (sum += 1 - v / 40));
// console.log(sum / yScale.values.length);
return ["0%", sum / yScale.values.length * 100];
},
end(xScale, yScales) {
let sum = 0;
const yScale = yScales[1];
yScale.values.forEach(v => (sum += 1 - v / 40));
return ["100%", sum / yScale.values.length * 100];
},
style: {
stroke: "#5ed470", // 线的颜色
lineDash: [0, 2, 2], // 虚线的设置
lineWidth: 1 // 线的宽度
} // 图形样式配置
});
chart.render();
console.log(chart.get('canvas'));
let data = [
{year: '2013',manage: 100,netAmount: 200,name: "经营活动产生现金流"},
{year: '2014',manage: 110,netAmount: 150,name: "经营活动产生现金流"},
{year: '2015',manage: 115,netAmount: 123,name: "经营活动产生现金流"},
{year: '2016',manage: 230,netAmount: 250,name: "经营活动产生现金流"},
{year: '2017',manage: 180,netAmount: 280,name: "经营活动产生现金流"},
{year: '2018',manage: 160,netAmount: 230,name: "经营活动产生现金流"},
{year: '2013',manage: 200,netAmount: 200,name: "投资活动产生现金流"},
{year: '2014',manage: 140,netAmount: 150,name: "投资活动产生现金流"},
{year: '2015',manage: 150,netAmount: 123,name: "投资活动产生现金流"},
{year: '2016',manage: 230,netAmount: 250,name: "投资活动产生现金流"},
{year: '2017',manage: 196,netAmount: 280,name: "投资活动产生现金流"},
{year: '2018',manage: 150,netAmount: 230,name: "投资活动产生现金流"},
{year: '2013',manage: 200,netAmount: 200,name: "筹资活动产生现金流"},
{year: '2014',manage: 370,netAmount: 150,name: "筹资活动产生现金流"},
{year: '2015',manage: 400,netAmount: 123,name: "筹资活动产生现金流"},
{year: '2016',manage: -450,netAmount: 250,name: "筹资活动产生现金流"},
{year: '2017',manage: 260,netAmount: 280,name: "筹资活动产生现金流"},
{year: '2018',manage: 140,netAmount: 230,name: "筹资活动产生现金流"}]
;
const chart = new F2.Chart({
id: 'mountNode',
syncY: true,
pixelRatio: window.devicePixelRatio
});
chart.source(data);
chart.axis('netAmount', false); // 隐藏
chart.interval().position('year*manage').color('name').adjust('stack');
chart.line().position('year*netAmount');
chart.render();
</script>
</body>
</html>
@@ -169,6 +169,29 @@ class Chart extends Base {
};
}

_syncYScales() {
const geoms = this.get('geoms');
const syncScales = [];
let min = [];
let max = [];
Util.each(geoms, geom => {
const yScale = geom.getYScale();
if (yScale.isLinear) {
syncScales.push(yScale);
min.push(yScale.min);
max.push(yScale.max);
}
});

min = Math.min.apply(null, min);
max = Math.max.apply(null, max);

Util.each(syncScales, scale => {
scale.min = min;
scale.max = max;
});
}

_getFieldsForLegend() {
const fields = [];
const geoms = this.get('geoms');
@@ -495,29 +518,29 @@ class Chart extends Base {
* @return {Chart} return the chart instance
*/
render() {
const self = this;
const canvas = self.get('canvas');
const geoms = self.get('geoms');
// processing the data
const canvas = this.get('canvas');
const geoms = this.get('geoms');
const data = this.get('data') || [];
const filteredData = this._execFilter(data);

const filteredData = this._execFilter(data); // filter data
this.set('filteredData', filteredData);
// init the coordinate instance
self._initCoord();
this._initCoord(); // initialization coordinate instance

Chart.plugins.notify(self, 'beforeGeomInit');
Chart.plugins.notify(this, 'beforeGeomInit');

// init all geometry instances
self._initGeoms(geoms);
// do some adjust for data
self._adjustScale();

Chart.plugins.notify(self, 'beforeGeomDraw');
self._renderAxis();
this._initGeoms(geoms); // init all geometry instances

const middlePlot = self.get('middlePlot');
if (self.get('limitInPlot') && !middlePlot.attr('clip')) {
const coord = self.get('coord');
this.get('syncY') && this._syncYScales();

this._adjustScale(); // do some adjust for data

Chart.plugins.notify(this, 'beforeGeomDraw');
this._renderAxis();

const middlePlot = this.get('middlePlot');
if (this.get('limitInPlot') && !middlePlot.attr('clip')) {
const coord = this.get('coord');
const clip = Helper.getClip(coord);
clip.set('canvas', middlePlot.get('canvas'));
middlePlot.attr('clip', clip);
@@ -528,12 +551,12 @@ class Chart extends Base {
geom.paint();
}

Chart.plugins.notify(self, 'afterGeomDraw');
Chart.plugins.notify(this, 'afterGeomDraw');
canvas.sort();
this.get('frontPlot').sort();
Chart.plugins.notify(self, 'beforeCanvasDraw');
Chart.plugins.notify(this, 'beforeCanvasDraw');
canvas.draw();
return self;
return this;
}

/**
@@ -44,7 +44,6 @@ describe('issue 257', () => {
const geomData = geom.get('dataArray')[0];

expect(geomData.length).to.equal(18);
console.log(geomData);
geomData.map((obj, index) => {
if (index < 3) {
expect(obj._originY).to.equal(200);
@@ -410,10 +410,51 @@ describe('chart test', () => {
it('destroy', function(done) {
setTimeout(function() {
chart.destroy();
expect(chart.destroyed).equal(true);
document.body.removeChild(canvas);
done();
}, 1500);
});
});

describe('syncY', function() {
const data = [
{ year: '2013', manage: 100, netAmount: 200, name: '经营活动产生现金流' },
{ year: '2014', manage: 110, netAmount: 150, name: '经营活动产生现金流' },
{ year: '2015', manage: 115, netAmount: 123, name: '经营活动产生现金流' },
{ year: '2016', manage: 230, netAmount: 250, name: '经营活动产生现金流' },
{ year: '2017', manage: 180, netAmount: 280, name: '经营活动产生现金流' },
{ year: '2018', manage: 160, netAmount: 230, name: '经营活动产生现金流' },
{ year: '2013', manage: 200, netAmount: 200, name: '投资活动产生现金流' },
{ year: '2014', manage: 140, netAmount: 150, name: '投资活动产生现金流' },
{ year: '2015', manage: 150, netAmount: 123, name: '投资活动产生现金流' },
{ year: '2016', manage: 230, netAmount: 250, name: '投资活动产生现金流' },
{ year: '2017', manage: 196, netAmount: 280, name: '投资活动产生现金流' },
{ year: '2018', manage: 150, netAmount: 230, name: '投资活动产生现金流' },
{ year: '2013', manage: 200, netAmount: 200, name: '筹资活动产生现金流' },
{ year: '2014', manage: 370, netAmount: 150, name: '筹资活动产生现金流' },
{ year: '2015', manage: 400, netAmount: 123, name: '筹资活动产生现金流' },
{ year: '2016', manage: -450, netAmount: 250, name: '筹资活动产生现金流' },
{ year: '2017', manage: 260, netAmount: 280, name: '筹资活动产生现金流' },
{ year: '2018', manage: 140, netAmount: 230, name: '筹资活动产生现金流' }
];

const chart = new Chart({
el: canvas,
syncY: true,
pixelRatio: window.devicePixelRatio
});

chart.source(data);
chart.axis('netAmount', false); // 隐藏

chart.interval().position('year*manage')
.color('name')
.adjust('stack');
chart.line().position('year*netAmount');
chart.render();

const yScales = chart.getYScales();
expect(yScales[0].min).to.equal(yScales[1].min);
expect(yScales[0].max).to.equal(yScales[1].max);
chart.destroy();
});
});

0 comments on commit 854685e

Please sign in to comment.