diff --git a/__tests__/unit/plots/tiny-area/index-spec.ts b/__tests__/unit/plots/tiny-area/index-spec.ts new file mode 100644 index 0000000000..9c23e53891 --- /dev/null +++ b/__tests__/unit/plots/tiny-area/index-spec.ts @@ -0,0 +1,103 @@ +import { TinyArea } from '../../../../src'; +import { partySupport } from '../../../data/party-support'; +import { createDiv } from '../../../utils/dom'; + +describe('tiny-area', () => { + it('data', () => { + const tinyArea = new TinyArea(createDiv(), { + width: 200, + height: 100, + data: partySupport + .filter((o) => o.type === 'FF') + .map((item) => { + return item.value; + }), + autoFit: false, + }); + + tinyArea.render(); + expect(tinyArea.chart.geometries.length).toBe(2); + expect(tinyArea.chart.geometries[0].shapeType).toEqual('area'); + expect(tinyArea.chart.geometries[1].shapeType).toEqual('line'); + }); + + it('data with area style', () => { + const tinyArea = new TinyArea(createDiv(), { + width: 200, + height: 100, + areaStyle: { + fill: '#123456', + }, + data: partySupport + .filter((o) => o.type === 'FF') + .map((item) => { + return item.value; + }), + autoFit: false, + }); + + tinyArea.render(); + expect(tinyArea.chart.geometries[0].elements[0].shape.attr('fill')).toEqual('#123456'); + }); + + it('data with smooth', () => { + const tinyArea = new TinyArea(createDiv(), { + width: 200, + height: 100, + data: partySupport + .filter((o) => o.type === 'FF') + .map((item) => { + return item.value; + }), + autoFit: false, + smooth: true, + }); + + tinyArea.render(); + expect(tinyArea.chart.geometries[0].attributes.shape.values).toEqual(['smooth']); + expect(tinyArea.chart.geometries[0].elements.length).toBe(1); + }); + + it('data with line style', () => { + const tinyArea = new TinyArea(createDiv(), { + width: 200, + height: 100, + smooth: true, + data: partySupport + .filter((o) => o.type === 'FF') + .map((item) => { + return item.value; + }), + lineStyle: { + stroke: '#123456', + lineDash: [2, 2], + lineWidth: 2, + }, + autoFit: false, + appendPadding: 10, + }); + + tinyArea.render(); + + const geometry = tinyArea.chart.geometries[1]; + const elements = geometry.elements; + expect(elements[0].shape.attr('lineDash')).toEqual([2, 2]); + expect(elements[0].shape.attr('stroke')).toEqual('#123456'); + expect(elements[0].shape.attr('lineWidth')).toEqual(2); + + tinyArea.update({ + ...tinyArea.options, + lineStyle: () => { + return { + stroke: '#123456', + lineDash: [4, 4], + lineWidth: 2, + }; + }, + }); + + expect(tinyArea.chart.geometries[1].elements[0].shape.attr('lineDash')).toEqual([4, 4]); + expect(tinyArea.chart.geometries[1].elements[0].shape.attr('stroke')).toEqual('#123456'); + expect(tinyArea.chart.geometries[1].elements[0].shape.attr('lineWidth')).toEqual(2); + }); +}); diff --git a/src/index.ts b/src/index.ts index b2f8c7a393..5ce9654c78 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,14 +5,18 @@ export * from './types'; // 折线图及类型定义 export { Line, LineOptions } from './plots/line'; + // 饼图及类型定义 export { Pie, PieOptions } from './plots/pie'; -//散点图及类型定义 +// 散点图及类型定义 export { Scatter, ScatterOptions } from './plots/scatter'; -//迷你折线图及类型定义 +// 迷你折线图及类型定义 export { TinyLine, TinyLineOptions } from './plots/tiny-line'; -//迷你柱形图及类型定义 +// 迷你柱形图及类型定义 export { TinyColumn, TinyColumnOptions } from './plots/tiny-column'; + +// 迷你面积图及类型定义 +export { TinyArea, TinyAreaOptions } from './plots/tiny-area'; diff --git a/src/plots/tiny-area/adaptor.ts b/src/plots/tiny-area/adaptor.ts new file mode 100644 index 0000000000..ecfa54805e --- /dev/null +++ b/src/plots/tiny-area/adaptor.ts @@ -0,0 +1,127 @@ +import { isFunction } from '@antv/util'; +import { Params } from '../../core/adaptor'; +import { flow } from '../../utils'; +import { TinyAreaOptions } from './types'; + +/** + * 字段 + * @param params + */ +function field(params: Params): Params { + const { chart, options } = params; + const { data } = options; + + const seriesData = data.map((y: number, x: number) => { + return { x, y }; + }); + + chart.data(seriesData); + + chart.area().position('x*y'); + chart.line().position('x*y'); + + return params; +} + +/** + * meta 配置 + * @param params + */ +function meta(params: Params): Params { + const { chart, options } = params; + const { meta } = options; + + chart.scale(meta); + + return params; +} + +/** + * axis 配置 + * @param params + */ +function axis(params: Params): Params { + const { chart } = params; + + chart.axis(false); + + return params; +} + +/** + * legend 配置 + * @param params + */ +function legend(params: Params): Params { + const { chart } = params; + + chart.legend(false); + + return params; +} + +/** + * tooltip 配置 + * @param params + */ +function tooltip(params: Params): Params { + const { chart } = params; + + chart.tooltip(false); + + return params; +} + +/** + * 样式 + * @param params + */ +function style(params: Params): Params { + const { chart, options } = params; + const { lineStyle, areaStyle } = options; + + const areaGeometry = chart.geometries[0]; + if (areaStyle && areaGeometry) { + if (isFunction(areaStyle)) { + areaGeometry.style('x*y', areaStyle); + } else { + areaGeometry.style(areaStyle); + } + } + + const lineGeometry = chart.geometries[1]; + if (lineStyle && lineGeometry) { + if (isFunction(lineStyle)) { + lineGeometry.style('x*y', lineStyle); + } else { + lineGeometry.style(lineStyle); + } + } + return params; +} + +/** + * shape 的配置处理 + * @param params + */ +function shape(params: Params): Params { + const { chart, options } = params; + const { smooth } = options; + + const areaGeometry = chart.geometries[0]; + areaGeometry.shape(smooth ? 'smooth' : 'area'); + + const lineGeometry = chart.geometries[1]; + lineGeometry.shape(smooth ? 'smooth' : 'line'); + + return params; +} + +/** + * 迷你面积图适配器 + * @param chart + * @param options + */ +export function adaptor(params: Params) { + flow(field, meta, axis, legend, tooltip, style, shape)(params); +} diff --git a/src/plots/tiny-area/index.ts b/src/plots/tiny-area/index.ts new file mode 100644 index 0000000000..5205a2dad2 --- /dev/null +++ b/src/plots/tiny-area/index.ts @@ -0,0 +1,18 @@ +import { Plot } from '../../core/plot'; +import { TinyAreaOptions } from './types'; +import { adaptor } from './adaptor'; +import { Adaptor } from '../../core/adaptor'; + +export { TinyAreaOptions }; + +export class TinyArea extends Plot { + /** 图表类型 */ + public type: string = 'tiny-area'; + + /** + * 获取 迷你面积图 的适配器 + */ + protected getSchemaAdaptor(): Adaptor { + return adaptor; + } +} diff --git a/src/plots/tiny-area/types.ts b/src/plots/tiny-area/types.ts new file mode 100644 index 0000000000..ef25f005df --- /dev/null +++ b/src/plots/tiny-area/types.ts @@ -0,0 +1,17 @@ +import { ChartOptions } from '../../types'; +import { ShapeStyle } from '../../types/style'; + +/** mini 图的配置继承自 ChartOptions,因为很多的 G2 图形配置都不需要 */ +export interface TinyAreaOptions extends ChartOptions { + // 通用数据配置 + /** 具体的数据 */ + readonly data: number[]; + /** 数据字段元信息 */ + readonly meta?: Record; + /** 是否平滑 */ + readonly smooth?: boolean; + /** 面积折线图形样式 */ + readonly lineStyle?: ShapeStyle | ((x?: number, y?: number) => ShapeStyle); + /** 面积填充图形样式 */ + readonly areaStyle?: ShapeStyle | ((x?: number, y?: number) => ShapeStyle); +}