Permalink
Browse files

feat: add show() and hide() methods for Geometry instance.

  • Loading branch information...
simaQ committed Jun 11, 2018
1 parent 012c9fc commit 652ce741d44087bec8a00de79608ec2913ed34b8
Showing with 291 additions and 32 deletions.
  1. +166 −0 demos/legend-custom.html
  2. +17 −1 src/geom/base.js
  3. +32 −30 src/plugin/tooltip.js
  4. +32 −0 test/unit/geom/geom-enhance-spec.js
  5. +44 −1 test/unit/plugin/tooltip-spec.js
@@ -0,0 +1,166 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义图例</title>
<link rel="stylesheet" href="./assets/common.css">
</head>
<body>
<div>
<canvas id="mountNode" style="position: relative;">
</canvas>
</div>
<script src="./assets/jquery-3.2.1.min.js"></script>
<script src="./assets/lodash-4.17.4.min.js"></script>
<script src="../build/f2.js"></script>
<script>
const data = [
{ name: 'Jon Nicoll', score: 282, avgScore: 94 },
{ name: 'Aaron Maxwell', score: 208, avgScore: 41.6 },
{ name: 'Warren Clunes', score: 186, avgScore: 46.5 },
{ name: 'David Bolton', score: 184, avgScore: 30.67 },
{ name: 'Joel Robindon', score: 177, avgScore: 44.25 },
{ name: 'Kyle Buckley', score: 150, avgScore: 50 },
{ name: 'Jordan Lawrence', score: 148, avgScore: 24.67 },
{ name: 'Jack Carey', score: 138, avgScore: 34.5 },
{ name: 'Kuldeep Pegu', score: 130, avgScore: 32.5 },
{ name: 'Max Hillier', score: 128, avgScore: 32 },
{ name: 'Angus Le Lievre', score: 127, avgScore: 62.5 }
];
const legendItems = [
{ name: '个人分数', marker: 'square', fill: '#FACC14', checked: true },
{
name: '平均分数',
marker: function(x, y, r, ctx) {
ctx.lineWidth = 1;
ctx.strokeStyle = ctx.fillStyle;
ctx.moveTo(x - r - 3, y);
ctx.lineTo(x + r + 3, y);
ctx.stroke();
ctx.arc(x, y, r, 0, Math.PI * 2, false);
ctx.fill();
},
fill: '#000',
checked: true
}
];
function findLegendItem(name) {
let index;
for(let i = 0; i < legendItems.length; i++) {
if (legendItems[i].name === name) {
index = i;
break;
}
}
return index;
}
const chart = new F2.Chart({
id: 'mountNode',
width: window.innerWidth,
height: window.innerWidth > window.innerHeight ? window.innerHeight - 54 : window.innerWidth * 0.707,
pixelRatio: window.devicePixelRatio,
padding: [ 'auto', 'auto', 90, 'auto' ]
});
chart.source(data, {
score: {
tickInterval: 50,
alias: '个人分数'
},
avgScore: {
ticks: [ 0, 17, 33, 50, 67, 83, 100 ],
alias: '平均分数'
}
});
chart.axis('avgScore', {
grid: null
});
chart.axis('name', {
label: {
rotate: Math.PI / 3,
textAlign: 'start',
textBaseline: 'middle'
}
});
// 自定义图例内容以及交互行为
chart.legend({
custom: true,
items: legendItems,
onClick(ev) {
const item = ev.clickedItem;
const name = item.get('name');
const checked = item.get('checked');
const children = item.get('children');
if (checked) {
const markerFill = children[0].attr('fill');
const textFill = children[1].attr('fill');
children[0].set('_originColor', markerFill); // 缓存 marker 原来的颜色
children[1].set('_originColor', textFill); // 缓存文本原来的颜色
}
const geoms = chart.get('geoms');
const canvas = chart.get('canvas');
for (let i = 0; i < geoms.length; i++) {
const geom = geoms[i];
const container = geom.get('container');
if (geom.getYScale().alias === name)
if (!checked) {
// container.show();
geom.show();
children[0].attr('fill', children[0].get('_originColor'));
children[1].attr('fill', children[1].get('_originColor'));
} else {
// container.hide();
geom.hide();
children[0].attr('fill', '#bfbfbf'); // marker 置灰
children[1].attr('fill', '#bfbfbf'); // 文本置灰 置灰
}
item.set('checked', !checked);
legendItems[findLegendItem(name)].checked = !checked;
}
// canvas.draw();
}
});
// tooltip 和图例的联动
chart.tooltip({
showCrosshairs: true,
custom: true, // 自定义 tooltip 内容框
onChange: function(obj) {
const legend = chart.get('legendController').legends.top[0];
const tooltipItems = obj.items;
const legendItems = legend.items;
const map = {};
legendItems.map(function(item) {
map[item.name] = _.clone(item);
});
tooltipItems.map(function(item) {
var name = item.name;
var value = item.value;
if (map[name]) {
map[name].value = value;
}
});
legend.setItems(_.values(map));
},
onHide: function() {
var legend = chart.get('legendController').legends.top[0];
legend.setItems(legendItems);
}
});
chart.interval().position('name*score').color('#FACC14');
chart.line().position('name*avgScore').color('#000');
chart.point().position('name*avgScore').size(3).style({
fill: '#000',
stroke: '#fff',
lineWidth: 1
});
chart.render();
</script>
</body>
</html>
@@ -74,7 +74,8 @@ class Geom extends Base {
* 否则从最小值开始
* @type {Boolean}
*/
startOnZero: true
startOnZero: true,
visible: true
};
}

@@ -826,6 +827,21 @@ class Geom extends Base {
super.destroy();
}

_display(visible) {
this.set('visible', visible);
const container = this.get('container');
const canvas = container.get('canvas');
container.set('visible', visible);
canvas.draw();
}

show() {
this._display(true);
}

hide() {
this._display(false);
}
}

module.exports = Geom;
@@ -319,37 +319,39 @@ class TooltipController {
const coord = chart.get('coord');

Util.each(geoms, geom => {
const type = geom.get('type');
const records = geom.getSnapRecords(point);
Util.each(records, record => {
if (record.x && record.y) {
const { x, y, _origin, color } = record;
const tooltipItem = {
x,
y: Util.isArray(y) ? y[1] : y,
color: color || Global.defaultColor,
origin: _origin,
name: getTooltipName(geom, _origin),
value: getTooltipValue(geom, _origin),
title: getTooltipTitle(geom, _origin)
};
if (marker) {
tooltipItem.marker = Util.mix({
fill: color || Global.defaultColor
}, marker);
}
items.push(tooltipItem);

if ([ 'line', 'area', 'path' ].indexOf(type) !== -1) {
tooltipMarkerType = 'circle';
tooltipMarkerItems.push(tooltipItem);
} else if (type === 'interval' && coord.type === 'cartesian') {
tooltipMarkerType = 'rect';
tooltipItem.width = geom.getSize(record._origin);
tooltipMarkerItems.push(tooltipItem);
if (geom.get('visible')) {
const type = geom.get('type');
const records = geom.getSnapRecords(point);
Util.each(records, record => {
if (record.x && record.y) {
const { x, y, _origin, color } = record;
const tooltipItem = {
x,
y: Util.isArray(y) ? y[1] : y,
color: color || Global.defaultColor,
origin: _origin,
name: getTooltipName(geom, _origin),
value: getTooltipValue(geom, _origin),
title: getTooltipTitle(geom, _origin)
};
if (marker) {
tooltipItem.marker = Util.mix({
fill: color || Global.defaultColor
}, marker);
}
items.push(tooltipItem);

if ([ 'line', 'area', 'path' ].indexOf(type) !== -1) {
tooltipMarkerType = 'circle';
tooltipMarkerItems.push(tooltipItem);
} else if (type === 'interval' && coord.type === 'cartesian') {
tooltipMarkerType = 'rect';
tooltipItem.width = geom.getSize(record._origin);
tooltipMarkerItems.push(tooltipItem);
}
}
}
});
});
}
});

if (items.length) {
@@ -0,0 +1,32 @@
const expect = require('chai').expect;
const Geom = require('../../../src/geom/base');
const { Canvas } = require('../../../src/graphic/index');

const dom = document.createElement('canvas');
dom.width = 500;
dom.height = 500;
document.body.appendChild(dom);

const canvas = new Canvas({
el: dom,
width: 500,
height: 500
});

describe('Geom enhance', function() {
it('visible', function() {
const geom = new Geom({
container: canvas.addGroup()
});
expect(geom.get('visible')).to.be.true;
const container = geom.get('container');

geom.hide();
expect(geom.get('visible')).to.be.false;
expect(container.get('visible')).to.be.false;

geom.show();
expect(geom.get('visible')).to.be.true;
expect(container.get('visible')).to.be.true;
});
});
@@ -3,6 +3,7 @@ const { gestureSimulator } = require('../test-util');

const F2 = require('../../../src/core');
require('../../../src/geom/interval');
require('../../../src/geom/line');
require('../../../src/geom/adjust');

const Tooltip = require('../../../src/plugin/tooltip');
@@ -229,8 +230,50 @@ describe('Tooltip Plugin', function() {
});

expect(isHideCalled).to.be.true;
document.body.removeChild(canvas);
// document.body.removeChild(canvas);
done();
}, 500);
});

it('get tooltip items when one geom is hide', function() {
const data = [
{ name: 'Jon Nicoll', score: 282, avgScore: 94 },
{ name: 'Aaron Maxwell', score: 208, avgScore: 41.6 },
{ name: 'Warren Clunes', score: 186, avgScore: 46.5 },
{ name: 'David Bolton', score: 184, avgScore: 30.67 },
{ name: 'Joel Robindon', score: 177, avgScore: 44.25 },
{ name: 'Kyle Buckley', score: 150, avgScore: 50 },
{ name: 'Jordan Lawrence', score: 148, avgScore: 24.67 },
{ name: 'Jack Carey', score: 138, avgScore: 34.5 },
{ name: 'Kuldeep Pegu', score: 130, avgScore: 32.5 },
{ name: 'Max Hillier', score: 128, avgScore: 32 },
{ name: 'Angus Le Lievre', score: 127, avgScore: 62.5 }
];
const chart = new F2.Chart({
id: 'chart-tooltip',
width: 400,
height: 300,
plugins: Tooltip,
pixelRatio: 2
});

chart.source(data);
chart.interval().position('name*score');
const line = chart.line().position('name*avgScore');
chart.render();

line.hide();

const point = chart.getPosition({
name: 'Jordan Lawrence',
score: 148
});

chart.showTooltip(point);
const tooltipController = chart.get('tooltipController');
const tooltip = tooltipController.tooltip;
expect(tooltip.items.length).to.equal(1);
expect(tooltip.items[0].name).to.equal('score');
expect(tooltip.items[0].value).to.equal('148');
});
});

0 comments on commit 652ce74

Please sign in to comment.