From ec7165126afb327613cc7e69e55915fff91f6085 Mon Sep 17 00:00:00 2001 From: connono <36756846+connono@users.noreply.github.com> Date: Mon, 20 Jul 2020 21:42:24 +0800 Subject: [PATCH] feat: add tiny-line (#1304) * feat: add tinyLine * feat: add tiny-line * feat: add tinyLine * feat: add tiny-line * feat: add tiny-line * feat: add tiny-line * feat: add tiny-line Co-authored-by: yinshi.wyl --- __tests__/unit/plots/tiny-line/index-spec.ts | 82 +++++++++++++ src/core/adaptor.ts | 5 +- src/index.ts | 2 + src/plots/tiny-line/adaptor.ts | 116 +++++++++++++++++++ src/plots/tiny-line/index.ts | 18 +++ src/plots/tiny-line/types.ts | 13 +++ 6 files changed, 233 insertions(+), 3 deletions(-) create mode 100644 __tests__/unit/plots/tiny-line/index-spec.ts create mode 100644 src/plots/tiny-line/adaptor.ts create mode 100644 src/plots/tiny-line/index.ts create mode 100644 src/plots/tiny-line/types.ts diff --git a/__tests__/unit/plots/tiny-line/index-spec.ts b/__tests__/unit/plots/tiny-line/index-spec.ts new file mode 100644 index 0000000000..f09ebc4240 --- /dev/null +++ b/__tests__/unit/plots/tiny-line/index-spec.ts @@ -0,0 +1,82 @@ +import { TinyLine } from '../../../../src'; +import { partySupport } from '../../../data/party-support'; +import { createDiv } from '../../../utils/dom'; + +describe('tiny-line', () => { + it('data', () => { + const tinyLine = new TinyLine(createDiv(), { + width: 80, + height: 40, + meta: { + value: { + min: 0, + max: 5000, + }, + }, + data: partySupport + .filter((o) => o.type === 'FF') + .map((item) => { + return item.value; + }), + autoFit: false, + }); + + tinyLine.render(); + expect(tinyLine.chart.geometries[0].elements.length).toBe(1); + }); + + it('data with smooth', () => { + const tinyLine = new TinyLine(createDiv(), { + width: 80, + height: 40, + meta: { + value: { + min: 0, + max: 5000, + }, + }, + data: partySupport + .filter((o) => o.type === 'FF') + .map((item) => { + return item.value; + }), + autoFit: false, + smooth: true, + }); + + tinyLine.render(); + expect(tinyLine.chart.geometries[0].attributes.shape.values).toEqual(['smooth']); + expect(tinyLine.chart.geometries[0].elements.length).toBe(1); + }); + + it('data with style', () => { + const tinyLine = new TinyLine(createDiv(), { + width: 80, + height: 40, + data: partySupport + .filter((o) => o.type === 'FF') + .map((item) => { + return item.value; + }), + lineStyle: { + lineDash: [2, 2], + }, + autoFit: false, + appendPadding: 10, + }); + + tinyLine.render(); + + const geometry = tinyLine.chart.geometries[0]; + const elements = geometry.elements; + expect(elements[0].shape.attr('lineDash')).toEqual([2, 2]); + + tinyLine.update({ + ...tinyLine.options, + lineStyle: () => { + return { lineDash: [4, 4] }; + }, + }); + expect(tinyLine.chart.geometries[0].elements[0].shape.attr('lineDash')).toEqual([4, 4]); + }); +}); diff --git a/src/core/adaptor.ts b/src/core/adaptor.ts index 9fa59f955f..1c7888176b 100644 --- a/src/core/adaptor.ts +++ b/src/core/adaptor.ts @@ -1,10 +1,9 @@ import { Chart } from '@antv/g2'; -import { Options } from '../types'; /** * adaptor flow 的参数 */ -export type Params = { +export type Params = { readonly chart: Chart; readonly options: O; }; @@ -13,4 +12,4 @@ export type Params = { * schema 转 G2 的适配器基类 * 使用 纯函数的方式,这里只是类型定义 */ -export type Adaptor = (params: Params) => void; +export type Adaptor = (params: Params) => void; diff --git a/src/index.ts b/src/index.ts index e991eb444f..351a6747a6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,3 +10,5 @@ export { Pie, PieOptions } from './plots/pie'; //散点图及类型定义 export { Scatter, ScatterOptions } from './plots/scatter'; + +export { TinyLine, TinyLineOptions } from './plots/tiny-line'; diff --git a/src/plots/tiny-line/adaptor.ts b/src/plots/tiny-line/adaptor.ts new file mode 100644 index 0000000000..5ede28447f --- /dev/null +++ b/src/plots/tiny-line/adaptor.ts @@ -0,0 +1,116 @@ +import { Geometry } from '@antv/g2'; +import { Params } from '../../core/adaptor'; +import { flow } from '../../utils'; +import { TinyLineOptions } from './types'; +import { isFunction } from '@antv/util'; + +/** + * 字段 + * @param params + */ +function field(params: Params): Params { + const { chart, options } = params; + const { data, connectNulls } = options; + + const seriesData = data.map((y: number, x: number) => { + return { x, y }; + }); + + chart.data(seriesData); + + chart.line({ connectNulls }).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 } = options; + + const geometry = chart.geometries[0]; + if (lineStyle && geometry) { + if (isFunction(lineStyle)) { + geometry.style('x*y', lineStyle); + } else { + geometry.style(lineStyle); + } + } + return params; +} + +/** + * shape 的配置处理 + * @param params + */ +function shape(params: Params): Params { + const { chart, options } = params; + const { smooth } = options; + + const lineGeometry = chart.geometries.find((g: Geometry) => g.type === 'line'); + + lineGeometry.shape(smooth ? 'smooth' : 'line'); + return params; +} + +/** + * 迷你折线图适配器 + * @param chart + * @param options + */ +export function adaptor(params: Params) { + // flow 的方式处理所有的配置到 G2 API + flow(field, meta, axis, legend, tooltip, style, shape)(params); +} diff --git a/src/plots/tiny-line/index.ts b/src/plots/tiny-line/index.ts new file mode 100644 index 0000000000..c5cc1de9e5 --- /dev/null +++ b/src/plots/tiny-line/index.ts @@ -0,0 +1,18 @@ +import { Plot } from '../../core/plot'; +import { TinyLineOptions } from './types'; +import { adaptor } from './adaptor'; +import { Adaptor } from '../../core/adaptor'; + +export { TinyLineOptions }; + +export class TinyLine extends Plot { + /** 图表类型 */ + public type: string = 'tiny-line'; + + /** + * 获取 迷你折线图 的适配器 + */ + protected getSchemaAdaptor(): Adaptor { + return adaptor; + } +} diff --git a/src/plots/tiny-line/types.ts b/src/plots/tiny-line/types.ts new file mode 100644 index 0000000000..16ce00baa1 --- /dev/null +++ b/src/plots/tiny-line/types.ts @@ -0,0 +1,13 @@ +import { Options } from '../../types'; +import { ShapeStyle } from '../../types/style'; + +export interface TinyLineOptions extends Options { + /** 具体的数据 */ + data: any[]; + /** 是否平滑 */ + smooth?: boolean; + /** 是否连接空数据 */ + connectNulls?: boolean; + /** 折线extra图形样式 */ + lineStyle?: ShapeStyle | ((x?: number, y?: number) => ShapeStyle); +}