Skip to content

Commit

Permalink
develop violin plot (#2176)
Browse files Browse the repository at this point in the history
* feat: violin plot

* feat: 封装violin API

* fix: delete useEffect

* fix: delete .editor

* fix: ignore .vscode

* fix: delete .vscode & delete init

* feat: ignore .vscode

* fix: open api xField yField seriesField

* fix: lint

---------

Co-authored-by: zy371123 <zy371123@alibaba-inc.com>
Co-authored-by: Joel Alan <31396322+lxfu1@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 16, 2023
1 parent 1798094 commit 0834952
Show file tree
Hide file tree
Showing 16 changed files with 224 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ logs
#ide
.idea/
.eslintcache
.vscode/**

# temp
temp-gallery.md
3 changes: 3 additions & 0 deletions packages/plots/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Gauge from './gauge';
import Liquid from './liquid';
import WordCloud from './wordCloud';
import Treemap from './treemap';
import Violin from './violin';
import BidirectionalBar from './bidirectional-bar';

export type { AreaConfig } from './area';
Expand All @@ -43,6 +44,7 @@ export type { GaugeConfig } from './gauge';
export type { LiquidConfig } from './liquid';
export type { WordCloudConfig } from './wordCloud';
export type { TreemapConfig } from './treemap';
export type { ViolinConfig } from './violin';
export type { BidirectionalBarConfig } from './bidirectional-bar';

export {
Expand All @@ -68,5 +70,6 @@ export {
Liquid,
WordCloud,
Treemap,
Violin,
BidirectionalBar,
};
12 changes: 12 additions & 0 deletions packages/plots/src/components/violin/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { ViolinOptions } from '../../core';
import { CommonConfig } from '../../interface';
import { BaseChart } from '../base';

export type ViolinConfig = CommonConfig<ViolinOptions>;

const ViolinChart = (props: ViolinConfig) => {
return <BaseChart {...props} chartType="Violin" />;
}

export default ViolinChart;
2 changes: 0 additions & 2 deletions packages/plots/src/core/base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ export abstract class Plot<O extends Options> extends EE {
if (this.type === 'base' || this[SKIP_DEL_CUSTOM_SIGN]) {
return { ...this.options, ...this.getChartOptions() };
}

return deleteCustomKeys(omit(this.options, CHART_OPTIONS), true);
}

Expand Down Expand Up @@ -106,7 +105,6 @@ export abstract class Plot<O extends Options> extends EE {
this.chart.render().then(() => {
this.annotations();
});

// 绑定
this.bindSizeSensor();
}
Expand Down
3 changes: 3 additions & 0 deletions packages/plots/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type { GaugeOptions } from './plots/gauge';
export type { LiquidOptions } from './plots/liquid';
export type { WordCloudOptions } from './plots/wordCloud';
export type { TreemapOptions } from './plots/treemap';
export type { ViolinOptions } from './plots/violin';
export type { BidirectionalBarOptions } from './plots/bidirectional-bar';
export * from './types';

Expand Down Expand Up @@ -53,6 +54,7 @@ import { Gauge } from './plots/gauge';
import { Liquid } from './plots/liquid';
import { WordCloud } from './plots/wordCloud';
import { Treemap } from './plots/treemap';
import { Violin } from './plots/violin';
import { BidirectionalBar } from './plots/bidirectional-bar';

export const Plots = {
Expand Down Expand Up @@ -82,5 +84,6 @@ export const Plots = {
Liquid,
WordCloud,
Treemap,
Violin,
BidirectionalBar,
};
49 changes: 49 additions & 0 deletions packages/plots/src/core/plots/violin/adaptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { flow, transformOptions, set } from '../../utils';
import { mark } from '../../components';
import type { Adaptor } from '../../types';
import type { ViolinOptions } from './type';

type Params = Adaptor<ViolinOptions>;

/**
* @param chart
* @param options
*/
export function adaptor(params: Params) {
/**
* 图表差异化处理
*/
const customTransform = (params: Params) => {
const { options } = params;
const { xField, yField, seriesField, children } = options;

const newChildren = children?.map((item) => {
return {
...item,
xField,
yField,
seriesField,
colorField: seriesField,
data: item.type === 'density' ? {
transform: [
{
type: 'kde',
field: yField,
groupBy: [xField, seriesField],
},
],
} : item.data,
}
}).filter((item) => options.violinType !== 'density' || item.type === 'density');
set(options, 'children', newChildren);
// 默认‘normal’类型数据格式
if (options.violinType === 'polar') {
set(options, 'coordinate', { type: 'polar'})
}
// 底层不消费violinType字段。
set(options, 'violinType', undefined);
return params;
}

return flow(customTransform, transformOptions, mark)(params);
}
51 changes: 51 additions & 0 deletions packages/plots/src/core/plots/violin/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Plot } from '../../base';
import type { Adaptor } from '../../types';
import { adaptor } from './adaptor';
import { ViolinOptions } from './type';

export type { ViolinOptions };

export class Violin extends Plot<ViolinOptions> {
/** 图表类型 */
public type = 'violin';

/**
* 获取 折线图 默认配置项
* 供外部使用
*/
static getDefaultOptions(): Partial<ViolinOptions> {
return {
type: 'view',
children: [
{
type: 'density',
sizeField: 'size',
tooltip: false,
},
{
type: 'boxplot',
shapeField: 'violin',
style: {
opacity: 0.5,
point: false,
},
},
],
animate: { enter: { type: 'fadeIn' } },
};
}

/**
* 获取 折线图 默认配置
*/
protected getDefaultOptions() {
return Violin.getDefaultOptions();
}

/**
* 折线图适配器
*/
protected getSchemaAdaptor(): (params: Adaptor<ViolinOptions>) => void {
return adaptor;
}
}
5 changes: 5 additions & 0 deletions packages/plots/src/core/plots/violin/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { BaseOptions, Options } from '../../types/common';

export type ViolinOptions = Options & BaseOptions & {
violinType?: 'normal' | 'density' | 'polar'
};
4 changes: 2 additions & 2 deletions packages/plots/src/core/utils/delete-custom-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export const deleteCustomKeys = <O extends Options>(options: O, isRender?: boole
[...deleteKeys, ...COORDIANTE_OPTIONS].forEach((key) => {
delete options[key];
});

options.children.forEach((child) => {
// 2023-11-09 对children为空情况做兼容。
options.children?.forEach((child) => {
Object.keys(child).forEach((key) => {
if (deleteKeys.includes(key)) {
delete child[key];
Expand Down
1 change: 1 addition & 0 deletions packages/plots/src/hooks/useChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export default function useChart<T extends Chart, U extends CommonConfig>(ChartC
};
}, []);


return {
chart,
container,
Expand Down
19 changes: 19 additions & 0 deletions site/examples/statistics/violin/demo/basic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Violin } from '@ant-design/plots';

const DemoViolin = () => {
const config = {
violinType: 'normal',
data: {
type: 'fetch',
value: 'https://assets.antv.antgroup.com/g2/species.json',
},
xField: 'x',
yField: 'y',
seriesField: 'species'
};
return <Violin {...config} />;
};

ReactDOM.render(<DemoViolin />, document.getElementById('container'));
19 changes: 19 additions & 0 deletions site/examples/statistics/violin/demo/density.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Violin } from '@ant-design/plots';

const DemoViolin = () => {
const config = {
violinType: 'density',
data: {
type: 'fetch',
value: 'https://assets.antv.antgroup.com/g2/species.json',
},
xField: 'x',
yField: 'y',
seriesField: 'species'
};
return <Violin {...config} />;
};

ReactDOM.render(<DemoViolin />, document.getElementById('container'));
32 changes: 32 additions & 0 deletions site/examples/statistics/violin/demo/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"title": {
"zh": "中文分类",
"en": "Category"
},
"demos": [
{
"filename": "density.js",
"title": {
"zh": "和密度图",
"en": "Density plot"
},
"screenshot": "https://mdn.alipayobjects.com/huamei_lwk8lu/afts/img/A*pctXQbGFiBIAAAAAAAAAAAAADma_AQ/original"
},
{
"filename": "basic.js",
"title": {
"zh": "基础小提琴图",
"en": "Basic violin plot"
},
"screenshot": "https://mdn.alipayobjects.com/huamei_lwk8lu/afts/img/A*vKc6SJjPY40AAAAAAAAAAAAADma_AQ/original"
},
{
"filename": "polar.js",
"title": {
"zh": "极坐标小提琴图",
"en": "Polar violin plot"
},
"screenshot": "https://mdn.alipayobjects.com/huamei_lwk8lu/afts/img/A*LLm1S5RBXGIAAAAAAAAAAAAADma_AQ/original"
}
]
}
19 changes: 19 additions & 0 deletions site/examples/statistics/violin/demo/polar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Violin } from '@ant-design/plots';

const DemoViolin = () => {
const config = {
violinType: 'polar',
data: {
type: 'fetch',
value: 'https://assets.antv.antgroup.com/g2/species.json',
},
xField: 'x',
yField: 'y',
seriesField: 'species'
};
return <Violin {...config} />;
};

ReactDOM.render(<DemoViolin />, document.getElementById('container'));
4 changes: 4 additions & 0 deletions site/examples/statistics/violin/index.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: Violin
order: 15
---
4 changes: 4 additions & 0 deletions site/examples/statistics/violin/index.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: 小提琴图
order: 15
---

0 comments on commit 0834952

Please sign in to comment.