-
Notifications
You must be signed in to change notification settings - Fork 605
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(circle-packing): 初始化 circle-packing 图表 * feat: 优化circle packing * test: 添加测试 * fix(circle-packing): 支持autoFit为true并修改默认配置项 * docs: 添加circle packing文档 * test(circle-packing): 增加animation和tooltip的单测 * fix(circle-packing): 修复packing下钻交互问题 Co-authored-by: visiky <736929286@qq.com> Co-authored-by: 酥云 <lisuwen.lsw@antgroup.com>
- Loading branch information
1 parent
94bfdf0
commit ab4ce2b
Showing
26 changed files
with
1,529 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
export const DATA = { | ||
name: 'root', | ||
children: [ | ||
{ | ||
name: 'Drama', | ||
value: 1046790, | ||
}, | ||
{ | ||
name: 'Comedy', | ||
value: 1039358, | ||
}, | ||
{ | ||
name: 'Documentary', | ||
value: 461880, | ||
}, | ||
{ | ||
name: 'News', | ||
value: 308136, | ||
}, | ||
{ | ||
name: 'Talk-Show', | ||
value: 270578, | ||
}, | ||
{ | ||
name: 'Action', | ||
value: 226334, | ||
}, | ||
{ | ||
name: 'Animation', | ||
value: 197342, | ||
}, | ||
{ | ||
name: 'Reality-TV', | ||
value: 189739, | ||
}, | ||
{ | ||
name: 'Crime', | ||
value: 175272, | ||
}, | ||
{ | ||
name: 'Family', | ||
value: 150621, | ||
}, | ||
{ | ||
name: 'Short', | ||
value: 138255, | ||
}, | ||
{ | ||
name: 'Adventure', | ||
value: 121216, | ||
}, | ||
{ | ||
name: 'Game-Show', | ||
value: 119912, | ||
}, | ||
{ | ||
name: 'Music', | ||
value: 102488, | ||
}, | ||
{ | ||
name: 'Adult', | ||
value: 90157, | ||
}, | ||
{ | ||
name: 'Biography', | ||
value: 59307, | ||
}, | ||
{ | ||
name: 'Sport', | ||
value: 58999, | ||
}, | ||
{ | ||
name: 'Romance', | ||
value: 52776, | ||
}, | ||
{ | ||
name: 'Horror', | ||
value: 50800, | ||
}, | ||
{ | ||
name: 'Fantasy', | ||
value: 22614, | ||
}, | ||
{ | ||
name: 'Sci-Fi', | ||
value: 22026, | ||
}, | ||
{ | ||
name: 'Thriller', | ||
value: 19706, | ||
}, | ||
{ | ||
name: 'Mystery', | ||
value: 18274, | ||
}, | ||
{ | ||
name: 'History', | ||
value: 16108, | ||
}, | ||
{ | ||
name: 'Western', | ||
value: 12535, | ||
}, | ||
{ | ||
name: 'Musical', | ||
value: 12240, | ||
}, | ||
{ | ||
name: 'War', | ||
value: 1992, | ||
}, | ||
{ | ||
name: 'Film-Noir', | ||
value: 12240 + 1992 + 1992, | ||
children: [ | ||
{ | ||
name: 'Musical', | ||
value: 12240, | ||
}, | ||
{ | ||
name: 'War', | ||
value: 1992, | ||
}, | ||
{ | ||
name: 'Film', | ||
value: 1992, | ||
}, | ||
], | ||
}, | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { CirclePacking } from '../../../../src'; | ||
import { createDiv } from '../../../utils/dom'; | ||
import { DATA } from '../../../data/circle-packing'; | ||
|
||
describe('Circle-Packing', () => { | ||
const div = createDiv(); | ||
const plot = new CirclePacking(div, { | ||
autoFit: true, | ||
padding: 0, | ||
data: DATA, | ||
animation: { | ||
appear: { | ||
animation: 'zoom-in', | ||
duration: 500, | ||
}, | ||
leave: { | ||
animation: 'zoom-out', | ||
duration: 500, | ||
}, | ||
}, | ||
}); | ||
plot.render(); | ||
|
||
it('default', () => { | ||
// | ||
expect(plot.chart.geometries[0].animateOption).toEqual({ | ||
appear: { | ||
animation: 'zoom-in', | ||
duration: 500, | ||
easing: 'easeQuadOut', | ||
}, | ||
update: { | ||
duration: 400, | ||
easing: 'easeQuadInOut', | ||
}, | ||
enter: { | ||
duration: 400, | ||
easing: 'easeQuadInOut', | ||
animation: 'zoom-in', | ||
}, | ||
leave: { | ||
duration: 500, | ||
easing: 'easeQuadIn', | ||
animation: 'zoom-out', | ||
}, | ||
}); | ||
}); | ||
|
||
it('update', () => { | ||
plot.update({ | ||
animation: { | ||
appear: { | ||
animation: 'fade-in', | ||
}, | ||
enter: { | ||
animation: 'fade-in', | ||
}, | ||
leave: { | ||
animation: 'wave-out', | ||
}, | ||
}, | ||
}); | ||
expect(plot.chart.geometries[0].animateOption).toEqual({ | ||
appear: { | ||
animation: 'fade-in', | ||
duration: 500, | ||
easing: 'easeQuadOut', | ||
}, | ||
update: { | ||
duration: 400, | ||
easing: 'easeQuadInOut', | ||
}, | ||
enter: { | ||
duration: 400, | ||
easing: 'easeQuadInOut', | ||
animation: 'fade-in', | ||
}, | ||
leave: { | ||
duration: 500, | ||
easing: 'easeQuadIn', | ||
animation: 'wave-out', | ||
}, | ||
}); | ||
}); | ||
|
||
afterAll(() => { | ||
plot.destroy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import { CirclePacking } from '../../../../src'; | ||
import { createDiv } from '../../../utils/dom'; | ||
import { DATA } from '../../../data/circle-packing'; | ||
import { DEFAULT_OPTIONS } from '../../../../src/plots/circle-packing/constant'; | ||
import { getContainerSize } from '../../../../src/utils'; | ||
|
||
describe('Circle-Packing', () => { | ||
const div = createDiv(); | ||
const plot = new CirclePacking(div, { | ||
padding: 0, | ||
data: DATA, | ||
legend: false, | ||
hierarchyConfig: { | ||
sort: (a, b) => b.depth - a.depth, | ||
}, | ||
}); | ||
plot.render(); | ||
|
||
it('default', () => { | ||
expect(plot.type).toBe('circle-packing'); | ||
// @ts-ignore | ||
expect(plot.getDefaultOptions()).toBe(CirclePacking.getDefaultOptions()); | ||
|
||
const geometry = plot.chart.geometries[0]; | ||
expect(geometry.type).toBe('point'); | ||
|
||
const positionFields = geometry.getAttribute('position').getFields(); | ||
expect(geometry.elements.length).toBe(geometry.data.length); | ||
expect(positionFields).toHaveLength(2); | ||
expect(positionFields).toEqual(['x', 'y']); | ||
|
||
// 圆形布局 宽高一致,即正常 | ||
const coordinateBox = plot.chart.coordinateBBox; | ||
const { width, height } = plot.chart.viewBBox; | ||
const minSize = Math.min(width, height); | ||
expect(coordinateBox.width).toBe(coordinateBox.height); | ||
expect(minSize).toBe(coordinateBox.width); | ||
expect(minSize).toBe(coordinateBox.height); | ||
}); | ||
|
||
it('color', () => { | ||
plot.update({ color: ['red', 'green', 'blue'] }); | ||
|
||
const geometry = plot.chart.geometries[0]; | ||
const elements = geometry.elements; | ||
expect(elements.length).toBe(plot.chart.getData().length); | ||
|
||
// 绘图数据 | ||
expect(elements[0].getModel().color).toBe('red'); | ||
expect(elements[1].getModel().color).toBe('green'); | ||
expect(elements[7].getModel().color).toBe('green'); | ||
expect(elements[14].getModel().color).toBe('blue' /** 15 % 3 === 0 */); | ||
}); | ||
|
||
it('style', () => { | ||
plot.update({ pointStyle: { fill: 'red', fillOpacity: 1 } }); | ||
|
||
const geometry = plot.chart.geometries[0]; | ||
let elements = geometry.elements; | ||
expect(elements.length).toBe(plot.chart.getData().length); | ||
|
||
// 绘图数据 | ||
expect(elements[0].shape.attr('fillOpacity')).toBe(1); | ||
expect(elements[1].shape.attr('fillOpacity')).toBe(1); | ||
expect(elements[1].shape.attr('fill')).toBe('red'); | ||
expect(elements[7].shape.attr('fillOpacity')).toBe(1); | ||
expect(elements[13].shape.attr('fillOpacity')).toBe(1); | ||
expect(elements[14].shape.attr('fillOpacity')).toBe(1); | ||
|
||
// callback | ||
plot.update({ | ||
rawFields: ['depth'], | ||
pointStyle: ({ depth }) => ({ | ||
fill: 'red', | ||
fillOpacity: depth > 1 ? 1 : 0.5, | ||
stroke: 'green', | ||
lineWidth: depth, | ||
}), | ||
}); | ||
elements = plot.chart.geometries[0].elements; | ||
// 绘图数据 | ||
expect(elements[0].shape.attr('fillOpacity')).toBe(0.5); | ||
expect(elements[0].shape.attr('stroke')).toBe('green'); | ||
|
||
expect(elements[0].shape.attr('fillOpacity')).toBe(0.5); | ||
expect(elements[elements.length - 1].shape.attr('fillOpacity')).toBe(1); | ||
|
||
expect(elements[0].shape.attr('lineWidth')).toBe(0); | ||
expect(elements[1].shape.attr('lineWidth')).toBe(1); | ||
expect(elements[elements.length - 1].shape.attr('lineWidth')).toBe(2); | ||
}); | ||
|
||
it('label', () => { | ||
let geometry = plot.chart.geometries[0]; | ||
let labelGroup = plot.chart.geometries[0].labelsContainer.getChildren()[0]; | ||
expect(typeof plot.chart.geometries[0].labelOption).toBe('object'); | ||
// @ts-ignore | ||
expect(labelGroup.getChildByIndex(0).attr('text')).toBe(DATA.name); | ||
// @ts-ignore | ||
expect(plot.chart.geometries[0].labelsContainer.getChildren()[1].getChildByIndex(0).attr('text')).toBe( | ||
DATA.children[0].name | ||
); | ||
|
||
plot.update({ label: { fields: ['value'] } }); | ||
labelGroup = plot.chart.geometries[0].labelsContainer.getChildren()[0]; | ||
const filterData = plot.chart.getData(); | ||
// @ts-ignore | ||
expect(labelGroup.getChildByIndex(0).attr('text')).toBe(`${filterData[0].value}`); | ||
|
||
// meta | ||
plot.update({ meta: { value: { formatter: (v) => v + '%' } } }); | ||
labelGroup = plot.chart.geometries[0].labelsContainer.getChildren()[0]; | ||
// @ts-ignore | ||
expect(labelGroup.getChildByIndex(0).attr('text')).toBe(`${filterData[0].value}%`); | ||
|
||
// formatter | ||
plot.update({ label: { formatter: () => 'xxx' } }); | ||
geometry = plot.chart.geometries[0]; | ||
// @ts-ignore | ||
expect(geometry.labelsContainer.getChildren()[0].getChildByIndex(0).attr('text')).toBe('xxx'); | ||
|
||
// 关闭 | ||
plot.update({ label: false }); | ||
expect(plot.chart.geometries[0].labelOption).toBe(false); | ||
}); | ||
|
||
it('defaultOptions 保持从 constants 中获取', () => { | ||
expect(CirclePacking.getDefaultOptions()).toEqual(DEFAULT_OPTIONS); | ||
}); | ||
|
||
afterAll(() => { | ||
plot.destroy(); | ||
}); | ||
}); |
Oops, something went wrong.