Skip to content

Commit b5df7c9

Browse files
hustccarcsin1zhangzhonghelxfu1
authored
refactor: remove data-set dependence (#1728)
* refactor: remove data-set in stock * refactor(percent): column 去除 data-set 依赖 * refactor: 去掉histogram的data-set (#1731) * refactor(word-cloud): remove data set for word cloud (#1732) * refactor(word-cloud): remove data-set * chore: add test for word-cloud * fix: 修复一些问题 * feat: 旭日图移除 DataSet (#1739) * chore: move data-set into devDependence Co-authored-by: arcsin1 <[email protected]> Co-authored-by: 被雨水过滤的空气 <[email protected]> Co-authored-by: 柯南 <[email protected]>
1 parent 2c86ddd commit b5df7c9

File tree

18 files changed

+1144
-61
lines changed

18 files changed

+1144
-61
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import DataSet from '@antv/data-set';
2+
import { binHistogram } from '../../../../src/utils/transform/histogram';
3+
import { histogramData, histogramStackData } from '../../../data/histogram-data';
4+
5+
const { DataView } = DataSet;
6+
7+
const ds = new DataSet();
8+
const dv = ds.createView().source(histogramData);
9+
10+
// 基本
11+
dv.transform({
12+
type: 'bin.histogram',
13+
field: 'value',
14+
binWidth: 2,
15+
as: ['range', 'count'],
16+
});
17+
18+
describe('binHistogram', () => {
19+
it('binHistogram binWidth', () => {
20+
expect(binHistogram(histogramData, 'value', 2)).toEqual(dv.rows);
21+
});
22+
});
23+
24+
const dv2 = ds.createView().source(histogramData);
25+
dv2.transform({
26+
type: 'bin.histogram',
27+
field: 'value',
28+
bins: 4, // binNumber
29+
as: ['range', 'count'],
30+
});
31+
32+
describe('binHistogram', () => {
33+
it('binHistogram binNumber', () => {
34+
expect(binHistogram(histogramData, 'value', undefined, 4)).toEqual(dv2.rows);
35+
});
36+
});
37+
38+
// stack 处理数据
39+
const dv3 = ds.createView().source(histogramStackData);
40+
41+
dv3.transform({
42+
type: 'bin.histogram',
43+
field: 'value',
44+
binWidth: 2,
45+
groupBy: ['type'],
46+
as: ['range', 'count'],
47+
});
48+
49+
describe('binHistogram', () => {
50+
it('binHistogram stack', () => {
51+
expect(binHistogram(histogramStackData, 'value', 2, undefined, 'type')).toEqual(dv3.rows);
52+
});
53+
});
54+
55+
// stack binNumber 处理数据
56+
const dv4 = ds.createView().source(histogramStackData);
57+
58+
dv4.transform({
59+
type: 'bin.histogram',
60+
field: 'value',
61+
bins: 4, // binNumber
62+
groupBy: ['type'],
63+
as: ['range', 'count'],
64+
});
65+
66+
describe('binHistogram', () => {
67+
it('binHistogram stack binNumber', () => {
68+
expect(binHistogram(histogramStackData, 'value', undefined, 4, 'type')).toEqual(dv4.rows);
69+
});
70+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import DataSet from '@antv/data-set';
2+
import { percent } from '../../../../src/utils/transform/percent';
3+
4+
const { DataView } = DataSet;
5+
6+
const data = [
7+
{ country: 'Europe', year: '1750', value: 163 },
8+
{ country: 'Europe', year: '1800', value: 203 },
9+
{ country: 'Europe', year: '1850', value: 276 },
10+
{ country: 'Europe', year: '1900', value: 408 },
11+
{ country: 'Europe', year: '1950', value: 547 },
12+
{ country: 'Europe', year: '1999', value: 729 },
13+
{ country: 'Europe', year: '2050', value: 628 },
14+
{ country: 'Europe', year: '2100', value: 828 },
15+
{ country: 'Asia', year: '1750', value: 502 },
16+
{ country: 'Asia', year: '1800', value: 635 },
17+
{ country: 'Asia', year: '1850', value: 809 },
18+
{ country: 'Asia', year: '1900', value: 947 },
19+
{ country: 'Asia', year: '1950', value: 1402 },
20+
{ country: 'Asia', year: '1999', value: 3634 },
21+
{ country: 'Asia', year: '2050', value: 5268 },
22+
{ country: 'Asia', year: '2100', value: 7268 },
23+
];
24+
25+
const dv = new DataView();
26+
dv.source(data).transform({
27+
type: 'percent',
28+
field: 'value',
29+
dimension: 'country',
30+
groupBy: ['year'],
31+
as: 'as',
32+
});
33+
34+
describe('percent', () => {
35+
it('percent', () => {
36+
expect(percent(data, 'value', 'year', 'as')).toEqual(dv.rows);
37+
});
38+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import DataSet from '@antv/data-set';
2+
import { DataItem, wordCloud } from '../../../../src/utils/transform/word-cloud';
3+
4+
const { View } = DataSet;
5+
const options = {
6+
type: 'tag-cloud',
7+
fields: ['text', 'value'],
8+
fontSize: 10,
9+
fontWeight: 'bold',
10+
size: [800, 800],
11+
padding: 0,
12+
timeInterval: 5000,
13+
rotate: 90,
14+
};
15+
const data = ['Hello', 'world', 'normally', 'you', 'want', 'more', 'words', 'than', 'this'].map((d) => {
16+
return {
17+
text: d,
18+
value: 5 + Math.random() * 10,
19+
test: 'haha',
20+
};
21+
});
22+
23+
describe('word-cloud', () => {
24+
it('with data-set', () => {
25+
const dv = new View();
26+
dv.source(data).transform(options as any);
27+
// 由于生成的每个单词的 x,y 坐标是比较随机的,每次都不一样,
28+
// 所以为了测试通过,把 x,y 属性删除。
29+
function removeXY(v) {
30+
delete v.x;
31+
delete v.y;
32+
}
33+
const result1 = wordCloud(data, options as any);
34+
const result2 = dv.rows;
35+
36+
result1.forEach(removeXY);
37+
result2.forEach(removeXY);
38+
39+
expect(result1).toEqual(result2);
40+
});
41+
42+
it('default', () => {
43+
const result = wordCloud(data);
44+
const firstRow = result[0];
45+
46+
expect(firstRow.hasText).toBe(true);
47+
expect(typeof firstRow.x).toBe('number');
48+
expect(typeof firstRow.y).toBe('number');
49+
expect(typeof firstRow.text).toBe('string');
50+
expect(typeof firstRow.size).toBe('number');
51+
expect(typeof firstRow.font).toBe('string');
52+
});
53+
54+
it('callback', () => {
55+
const common = (row: DataItem) => {
56+
expect(typeof row.text).toBe('string');
57+
expect(typeof row.value).toBe('number');
58+
};
59+
const font = (row: DataItem) => {
60+
common(row);
61+
return 'font-test';
62+
};
63+
const fontWeight = (row: DataItem): any => {
64+
common(row);
65+
return 'fontWeight-test';
66+
};
67+
const fontSize = (row: DataItem) => {
68+
common(row);
69+
return 11;
70+
};
71+
const rotate = (row: DataItem) => {
72+
common(row);
73+
return 22;
74+
};
75+
const padding = (row: DataItem) => {
76+
common(row);
77+
return 33;
78+
};
79+
const spiral = (size: [number, number]) => {
80+
expect(size.length).toBe(2);
81+
const e = size[0] / size[1];
82+
return (t: number) => {
83+
expect(typeof t).toBe('number');
84+
return [e * (t *= 0.1) * Math.cos(t), t * Math.sin(t)];
85+
};
86+
};
87+
88+
const result = wordCloud(data, {
89+
font,
90+
fontWeight,
91+
fontSize,
92+
rotate,
93+
padding,
94+
spiral,
95+
});
96+
const firstRow = result[0];
97+
expect(firstRow.hasText).toBe(true);
98+
expect(typeof firstRow.x).toBe('number');
99+
expect(typeof firstRow.y).toBe('number');
100+
expect(typeof firstRow.text).toBe('string');
101+
expect(firstRow.font).toBe('font-test');
102+
expect(firstRow.weight).toBe('fontWeight-test');
103+
expect(firstRow.size).toBe(11);
104+
expect(firstRow.rotate).toBe(22);
105+
expect(firstRow.padding).toBe(33);
106+
});
107+
});

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,15 @@
5454
}
5555
},
5656
"dependencies": {
57-
"@antv/data-set": "^0.11.5",
5857
"@antv/event-emitter": "^0.1.2",
5958
"@antv/g2": "^4.1.0-beta.11",
59+
"d3-hierarchy": "^2.0.0",
6060
"dayjs": "^1.8.36",
6161
"size-sensor": "^1.0.1",
6262
"tslib": "^1.13.0"
6363
},
6464
"devDependencies": {
65+
"@antv/data-set": "^0.11.5",
6566
"@antv/gatsby-theme-antv": "^1.0.0-beta.8",
6667
"@babel/core": "^7.10.4",
6768
"@babel/plugin-transform-runtime": "^7.11.5",

src/plots/column/adaptor.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ import { findGeometry } from '../../utils';
44
import { tooltip, slider, interaction, animation, theme, scale, annotation, scrollbar } from '../../adaptor/common';
55
import { interval } from '../../adaptor/geometries';
66
import { flow, transformLabel } from '../../utils';
7+
import { percent } from '../../utils/transform/percent';
78
import { ColumnOptions } from './types';
8-
import { transformData } from './utils';
99

1010
/**
1111
* 字段
1212
* @param params
1313
*/
1414
function geometry(params: Params<ColumnOptions>): Params<ColumnOptions> {
1515
const { chart, options } = params;
16-
const { data, columnStyle, color, columnWidthRatio, isPercent } = options;
16+
const { data, columnStyle, color, columnWidthRatio, isPercent, xField, yField } = options;
1717
let chartData = data;
1818
if (isPercent) {
19-
chartData = transformData(options);
19+
chartData = percent(data, yField, xField, yField);
2020
}
2121
chart.data(chartData);
2222

src/plots/column/utils.ts

-20
This file was deleted.

src/plots/histogram/adaptor.ts

+4-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import DataSet from '@antv/data-set';
21
import { deepMix } from '@antv/util';
32
import { Params } from '../../core/adaptor';
43
import { tooltip, interaction, animation, theme, scale } from '../../adaptor/common';
54
import { findGeometry } from '../../utils';
65
import { flow, transformLabel } from '../../utils';
76
import { interval } from '../../adaptor/geometries';
7+
import { binHistogram } from '../../utils/transform/histogram';
88
import { HistogramOptions } from './types';
99

1010
/**
@@ -15,20 +15,10 @@ function geometry(params: Params<HistogramOptions>): Params<HistogramOptions> {
1515
const { chart, options } = params;
1616
const { data, binField, binNumber, binWidth, color, stackField, legend, columnStyle } = options;
1717

18-
const ds = new DataSet();
19-
const dv = ds.createView().source(data);
20-
21-
// dataset 处理数据
22-
dv.transform({
23-
type: 'bin.histogram',
24-
field: binField,
25-
bins: binNumber,
26-
binWidth: binWidth,
27-
groupBy: stackField ? [stackField] : undefined,
28-
as: ['range', 'count'],
29-
});
18+
// 处理数据
19+
const plotData = binHistogram(data, binField, binWidth, binNumber, stackField);
3020

31-
chart.data(dv.rows);
21+
chart.data(plotData);
3222

3323
const p = deepMix({}, params, {
3424
options: {

src/plots/stock/adaptor.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { deepMix, isArray, isObject, map } from '@antv/util';
2-
import DataSet from '@antv/data-set';
32
import { Params } from '../../core/adaptor';
43
import { interaction, animation, theme } from '../../adaptor/common';
54
import { findGeometry, flow, pick, transformTooltip } from '../../utils';
@@ -28,10 +27,7 @@ function field(params: Params<StockOptions>): Params<StockOptions> {
2827
return obj;
2928
});
3029

31-
const ds = new DataSet();
32-
const dv = ds.createView().source(data);
33-
34-
chart.data(dv.rows);
30+
chart.data(data);
3531

3632
const geometry = chart.schema().position(`${xField}*${Y_FIELD}`).shape('candle');
3733

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import * as d3Hierarchy from 'd3-hierarchy';
2+
import { assign, isArray } from '@antv/util';
3+
import { getField, getAllNodes } from './util';
4+
5+
const DEFAULT_OPTIONS: Options = {
6+
field: 'value',
7+
size: [1, 1], // width, height
8+
round: false,
9+
padding: 0,
10+
sort: true,
11+
as: ['x', 'y'],
12+
};
13+
14+
export interface Options {
15+
field: string;
16+
size?: [number, number];
17+
round?: boolean;
18+
ratio?: number;
19+
padding?: number;
20+
sort?: boolean;
21+
as?: [string, string];
22+
}
23+
24+
export function partition(data: any, options: Options): any[] {
25+
options = assign({} as Options, DEFAULT_OPTIONS, options);
26+
const as = options.as;
27+
if (!isArray(as) || as.length !== 2) {
28+
throw new TypeError('Invalid as: it must be an array with 2 strings (e.g. [ "x", "y" ])!');
29+
}
30+
31+
let field;
32+
try {
33+
field = getField(options);
34+
} catch (e) {
35+
console.warn(e);
36+
}
37+
38+
const partition = (data) =>
39+
d3Hierarchy.partition().size(options.size).round(options.round).padding(options.padding)(
40+
d3Hierarchy.hierarchy(data).sum((d) => d[field])
41+
);
42+
const root = partition(data);
43+
44+
/*
45+
* points:
46+
* 3 2
47+
* 0 1
48+
*/
49+
const x = as[0];
50+
const y = as[1];
51+
root.each((node) => {
52+
node[x] = [node.x0, node.x1, node.x1, node.x0];
53+
node[y] = [node.y1, node.y1, node.y0, node.y0];
54+
['x0', 'x1', 'y0', 'y1'].forEach((prop) => {
55+
if (as.indexOf(prop) === -1) {
56+
delete node[prop];
57+
}
58+
});
59+
});
60+
61+
return getAllNodes(root);
62+
}

0 commit comments

Comments
 (0)