UNPKG

light-chart

Version:

Charts for mobile visualization.

626 lines (568 loc) 18.4 kB
const expect = require('chai').expect; 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'); const Legend = require('../../../src/plugin/legend'); const canvas = document.createElement('canvas'); canvas.width = 500; canvas.height = 500; canvas.id = 'chart-tooltip'; canvas.style.position = 'fixed'; canvas.style.top = 0; canvas.style.left = 0; document.body.appendChild(canvas); function snapEqual(v1, v2) { return Math.abs(v1 - v2) < 0.01; } describe('Tooltip Plugin', function() { let chart; let tooltipController; let tooltip; let data = [ { day: '周一', value: 300 }, { day: '周二', value: 400 }, { day: '周三', value: 350 }, { day: '周四', value: 500 }, { day: '周五', value: 490 }, { day: '周六', value: 600 }, { day: '周日', value: 900 } ]; it('Register Tooltip plugin', function() { chart = new F2.Chart({ id: 'chart-tooltip', width: 400, height: 300, plugins: Tooltip, pixelRatio: 2 }); tooltipController = chart.get('tooltipController'); expect(tooltipController).not.to.be.empty; }); it('chart.tooltip() config', function() { chart.tooltip(false); tooltipController = chart.get('tooltipController'); expect(tooltipController.enable).to.be.false; expect(tooltipController.cfg).to.eql({}); chart.tooltip(true, { triggerOn: 'mousemove', triggerOff: 'mouseleave' }); expect(tooltipController.enable).to.be.true; expect(tooltipController.cfg).to.eql({ triggerOn: 'mousemove', triggerOff: 'mouseleave' }); chart.tooltip({ triggerOn: 'mousemove', triggerOff: 'mouseleave', showTitle: true }); expect(tooltipController.enable).to.be.true; expect(tooltipController.cfg).to.eql({ triggerOn: 'mousemove', triggerOff: 'mouseleave', showTitle: true }); }); it('chart.showToolip(point)', function() { chart.source(data, { day: { range: [ 0, 1 ] } }); chart.line().position('day*value'); chart.render(); tooltipController = chart.get('tooltipController'); tooltip = tooltipController.tooltip; expect(tooltip.items).to.be.undefined; const point = { x: 163, y: 276 }; chart.showTooltip(point); expect(tooltip.items.length).to.equal(1); expect(tooltip.items[0].name).to.equal('value'); expect(tooltip.items[0].value).to.equal('350'); expect(tooltip.items[0].title).to.equal('周三'); expect(tooltip.markerGroup.get('visible')).to.be.true; expect(tooltip.container.titleShape.attr('text')).to.equal(tooltip.title); const firstPoint = chart.getPosition({ day: '周一', value: 300 }); chart.showTooltip(firstPoint); expect(tooltip.items[0].name).to.equal('value'); expect(tooltip.items[0].value).to.equal('300'); expect(tooltip.items[0].title).to.equal('周一'); expect(snapEqual(tooltip.container.x, 44.17999267578125)).to.be.true; expect(snapEqual(tooltip.container.y, -7)).to.be.true; const lastPoint = chart.getPosition({ day: '周日', value: 300 }); chart.showTooltip(lastPoint); expect(tooltip.items[0].name).to.equal('value'); expect(tooltip.items[0].value).to.equal('900'); expect(tooltip.items[0].title).to.equal('周日'); // expect(snapEqual(tooltip.container.x, 313.0880584716797)).to.be.true; expect(snapEqual(tooltip.container.y, -7)).to.be.true; }); it('chart.hideTooltip()', function() { chart.hideTooltip(); expect(tooltip.markerGroup.get('visible')).to.be.false; }); it('clear', function() { chart.clear(); tooltipController = chart.get('tooltipController'); tooltip = tooltipController.tooltip; const { prePoint, _lastActive } = tooltipController; expect(tooltip).to.be.null; expect(prePoint).to.be.null; expect(_lastActive).to.be.null; chart.destroy(); }); it('dodge column chart', function() { data = [ { name: 'London', 月份: 'Jan.', 月均降雨量: 18.9 }, { name: 'London', 月份: 'Feb.', 月均降雨量: 28.8 }, { name: 'London', 月份: 'Mar.', 月均降雨量: 39.3 }, { name: 'Berlin', 月份: 'Jan.', 月均降雨量: 12.4 }, { name: 'Berlin', 月份: 'Feb.', 月均降雨量: 23.2 }, { name: 'Berlin', 月份: 'Mar.', 月均降雨量: 34.5 } ]; chart = new F2.Chart({ id: 'chart-tooltip', plugins: Tooltip, pixelRatio: 2 }); chart.source(data); chart.interval().position('月份*月均降雨量') .color('name') .adjust({ type: 'dodge', marginRatio: 0.05 // 设置分组间柱子的间距 }); chart.render(); tooltipController = chart.get('tooltipController'); tooltip = tooltipController.tooltip; chart.showTooltip({ x: 163, y: 276 }); expect(tooltip.items.length).to.equal(2); expect(tooltip.items[0].name).to.equal('London'); expect(tooltip.items[1].name).to.equal('Berlin'); expect(tooltip.items[0].value).to.equal('28.8'); expect(tooltip.items[1].value).to.equal('23.2'); expect(tooltip.items[0].title).to.equal('Feb.'); expect(tooltip.items[1].title).to.equal('Feb.'); expect(tooltip.markerGroup.get('visible')).to.be.true; // expect(snapEqual(tooltip.container.x, 126.502067565918)).to.be.true; }); it('custom tooltip', function(done) { data = [ { label: 'Mon.', type: 'series1', value: 2800 }, { label: 'Mon.', type: 'series2', value: 2260 }, { label: 'Tue.', type: 'series1', value: 1800 }, { label: 'Tue.', type: 'series2', value: 1300 }, { label: 'Wed.', type: 'series1', value: 950 }, { label: 'Wed.', type: 'series2', value: 900 }, { label: 'Thu.', type: 'series1', value: 500 }, { label: 'Thu.', type: 'series2', value: 390 }, { label: 'Fri.', type: 'series1', value: 170 }, { label: 'Fri.', type: 'series2', value: 100 } ]; chart = new F2.Chart({ id: 'chart-tooltip', width: 400, height: 300, plugins: [ Tooltip, Legend ], pixelRatio: 2 }); chart.source(data.reverse(), { value: { tickInterval: 750, formatter(val) { return val + '%'; } } }); chart.coord({ transposed: true }); let isShowCalled = false; let isChangeCalled = false; let isHideCalled = false; // let isCustomCalled = false; const tooltipValue = []; // 配置 tooltip chart.tooltip({ triggerOn: 'touchmove', showTitle: true, onShow() { isShowCalled = true; }, custom: true, onChange(obj) { const legend = chart.get('legendController').legends.top[0]; const tooltipItems = obj.items; const legendItems = legend.items; const map = {}; legendItems.map(item => { map[item.name] = F2.Util.mix({}, item); return item; }); tooltipItems.map(item => { const { name, value } = item; if (map[name]) { map[name].value = (value); } tooltipValue.push(value); return item; }); legend.setItems(Object.values(map)); isChangeCalled = true; }, onHide() { const legend = chart.get('legendController').legends.top[0]; legend.setItems(chart.getLegendItems().country); isHideCalled = true; } }); chart.axis('label', { line: F2.Global._defaultAxis.line, grid: null }); chart.axis('value', { line: null, grid: F2.Global._defaultAxis.grid, label(text, index, total) { const textCfg = {}; if (index === 0) { textCfg.textAlign = 'left'; } if (index === total - 1) { textCfg.textAlign = 'right'; } return textCfg; } }); chart.interval() .position('label*value') .color('type') .adjust({ type: 'dodge', marginRatio: 1 / 32 }); chart.render(); const legend = chart.get('legendController').legends.top[0]; expect(legend.itemsGroup.get('children')[0].get('children').length).to.equal(2); gestureSimulator(canvas, 'touchmove', { clientX: 375, clientY: 174 }); expect(isShowCalled).to.be.true; expect(isChangeCalled).to.be.true; // expect(isCustomCalled).to.be.true; expect(legend.itemsGroup.get('children')[0].get('children').length).to.equal(3); expect(tooltipValue.length).to.equal(2); expect(tooltipValue[0]).to.equal('900%'); expect(tooltipValue[1]).to.equal('950%'); setTimeout(function() { gestureSimulator(canvas, 'touchmove', { clientX: 59, clientY: 295 }); expect(isHideCalled).to.be.true; // 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'); chart.destroy(); }); }); describe('Tooltip crosshairs', function() { const data = [ { date: '2018-04-21', steps: 59 }, { date: '2018-04-22', steps: 2515 }, { date: '2018-04-23', steps: 6524 }, { date: '2018-04-24', steps: 26044 }, { date: '2018-04-25', steps: 29763 }, { date: '2018-04-26', steps: 10586 }, { date: '2018-04-27', steps: 14758 }, { date: '2018-04-29', steps: 549 }, { date: '2018-04-30', steps: 21 } ]; let chart = new F2.Chart({ id: 'chart-tooltip', width: 400, height: 300, plugins: Tooltip, padding: [ 'auto', 'auto', 0, 0 ], pixelRatio: 2 }); chart.source(data, { date: { tickCount: 3 } }); chart.line().position('date*steps'); it('chart.tooltip() with xy crosshairs.', () => { chart.tooltip({ showYTip: true, showXTip: true, yTip(val) { return parseInt(val); }, xTip(val) { return 'date:' + val; }, crosshairsType: 'xy', crosshairsStyle: { lineDash: [ 2 ], stroke: '#1890ff' } }); chart.render(); const point = chart.getPosition({ date: '2018-04-26', steps: 10586 }); chart.showTooltip(point); const tooltipController = chart.get('tooltipController'); const tooltip = tooltipController.tooltip; const { crosshairsShapeX, crosshairsShapeY } = tooltip; expect(crosshairsShapeX).not.to.be.undefined; expect(crosshairsShapeY).not.to.be.undefined; expect(snapEqual(crosshairsShapeY.get('x'), 235.2777777777778)).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.726)).to.be.true; expect(snapEqual(tooltip.yTipBox.x, 18.34765625)).to.be.true; expect(tooltip.yTipBox.content).to.equal(8363); }); it('show xTip and yTip, snap = false', () => { chart.destroy(); chart = new F2.Chart({ id: 'chart-tooltip', width: 400, height: 300, plugins: Tooltip, pixelRatio: 2 }); chart.source(data, { date: { tickCount: 3, range: [ 0, 1 ] } }); chart.line().position('date*steps'); chart.tooltip({ showXTip: true, showYTip: true, showTooltipMarker: false, crosshairsType: 'xy', yTip(val) { return { text: Math.round(val) }; } }); chart.render(); const point = chart.getPosition({ date: '2018-04-21', steps: 59 }); chart.showTooltip({ x: point.x, y: point.y - 230 }); const tooltipController = chart.get('tooltipController'); const tooltip = tooltipController.tooltip; const { xTipBox: xTip, yTipBox: yTip } = tooltip; 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(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; expect(yTip.y).to.equal(39); chart.showTooltip(chart.getPosition({ date: '2018-04-30', steps: 21 })); expect(tooltip.xTipBox.content).to.equal('2018-04-30'); expect(tooltip.yTipBox.content).to.equal(21); expect(snapEqual(tooltip.xTipBox.x, 349.30859375)).to.be.true; expect(tooltip.xTipBox.y).to.equal(276.5); expect(snapEqual(tooltip.yTipBox.x, 38.62615966796875)).to.be.true; expect(tooltip.yTipBox.y).to.equal(258.5); chart.hideTooltip(); expect(tooltip.xTipBox.container.get('visible')).to.be.false; expect(tooltip.yTipBox.container.get('visible')).to.be.false; }); it('show xTip and yTip, snap = true', () => { chart.destroy(); chart = new F2.Chart({ id: 'chart-tooltip', width: 400, height: 300, plugins: Tooltip, pixelRatio: 2 }); chart.source(data, { date: { tickCount: 3, range: [ 0, 1 ] } }); chart.line().position('date*steps'); chart.tooltip({ showXTip: true, showYTip: true, showTooltipMarker: false, snap: true, crosshairsType: 'xy', yTip(val) { return { text: Math.round(val) }; } }); chart.render(); const point = chart.getPosition({ date: '2018-04-21', steps: 59 }); chart.showTooltip({ x: point.x, y: point.y - 230 }); const tooltipController = chart.get('tooltipController'); const tooltip = tooltipController.tooltip; const { xTipBox: xTip, yTipBox: yTip, crosshairsShapeX } = tooltip; 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(59); expect(crosshairsShapeX.get('y')).to.equal(point.y); }); it('show yTip in transposed coordinate', () => { chart.destroy(); chart = new F2.Chart({ id: 'chart-tooltip', width: 400, height: 300, plugins: Tooltip, pixelRatio: 2 }); chart.source(data); chart.coord({ transposed: true }); chart.interval().position('date*steps'); chart.tooltip({ showYTip: true }); chart.render(); const point = chart.getPosition({ date: '2018-04-22', steps: 2515 }); chart.showTooltip(point); const tooltipController = chart.get('tooltipController'); const tooltip = tooltipController.tooltip; const { xTipBox: xTip, yTipBox: yTip } = tooltip; expect(xTip).be.undefined; expect(yTip).not.to.be.undefined; expect(yTip.content).to.equal('2018-04-22'); // expect(snapEqual(yTip.x, 39.068572998046875)).to.be.true; expect(snapEqual(yTip.y, 227.91666666666669)).to.be.true; }); it('show xTip, yTip in transposed coordinate, snap = false', () => { chart.destroy(); chart = new F2.Chart({ id: 'chart-tooltip', width: 400, height: 300, plugins: Tooltip, pixelRatio: 2 }); chart.source(data); chart.coord({ transposed: true }); chart.interval().position('date*steps'); chart.tooltip({ showYTip: true, showXTip: true, xTip(val) { return parseInt(val); } }); chart.render(); const point = chart.getPosition({ date: '2018-04-22', steps: 2515 }); chart.showTooltip(point); const tooltipController = chart.get('tooltipController'); const tooltip = tooltipController.tooltip; const { xTipBox: xTip, yTipBox: yTip } = tooltip; expect(yTip).not.to.be.undefined; expect(yTip.content).to.equal('2018-04-22'); expect(snapEqual(yTip.y, 227.91666666666669)).to.be.true; expect(xTip.content).to.equal(4999); }); it('show xTip in transposed coordinate, snap = true', () => { chart.destroy(); chart = new F2.Chart({ id: 'chart-tooltip', width: 400, height: 300, plugins: Tooltip, pixelRatio: 2 }); chart.source(data); chart.coord({ transposed: true }); chart.interval().position('date*steps'); chart.tooltip({ showXTip: true, snap: true }); chart.render(); const point = chart.getPosition({ date: '2018-04-22', steps: 2515 }); chart.showTooltip(point); const tooltipController = chart.get('tooltipController'); const tooltip = tooltipController.tooltip; const { xTipBox: xTip } = tooltip; expect(xTip.content).to.equal('2515'); chart.destroy(); document.body.removeChild(canvas); }); });