diff --git a/__tests__/integration/snapshots/static/alphabetIntervalColumnWidthRatio.svg b/__tests__/integration/snapshots/static/alphabetIntervalColumnWidthRatio.svg new file mode 100644 index 0000000000..ef7b99993c --- /dev/null +++ b/__tests__/integration/snapshots/static/alphabetIntervalColumnWidthRatio.svg @@ -0,0 +1,1201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1951 年 + + + + + + + 1952 年 + + + + + + + 1956 年 + + + + + + + 1957 年 + + + + + + + 1958 年 + + + + + + + 1959 年 + + + + + + + 1960 年 + + + + + + + 1962 年 + + + + + + + + + year + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 20 + + + + + + + 40 + + + + + + + 60 + + + + + + + 80 + + + + + + + 100 + + + + + + + 120 + + + + + + + 140 + + + + + + + + + sales + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/__tests__/plots/static/alphabet-interval-column-width-ratio.ts b/__tests__/plots/static/alphabet-interval-column-width-ratio.ts new file mode 100644 index 0000000000..ba6dd92305 --- /dev/null +++ b/__tests__/plots/static/alphabet-interval-column-width-ratio.ts @@ -0,0 +1,26 @@ +import { G2Spec } from '../../../src'; + +export function alphabetIntervalColumnWidthRatio(): G2Spec { + return { + type: 'view', + autoFit: true, + children: [ + { + type: 'interval', + data: [ + { year: '1951 年', sales: 38 }, + { year: '1952 年', sales: 52 }, + { year: '1956 年', sales: 61 }, + { year: '1957 年', sales: 145 }, + { year: '1958 年', sales: 48 }, + { year: '1959 年', sales: 38 }, + { year: '1960 年', sales: 38 }, + { year: '1962 年', sales: 38 }, + ], + encode: { x: 'year', y: 'sales' }, + style: { columnWidthRatio: 0.2 }, + coordinate: { transform: [{ type: 'transpose' }] }, + }, + ], + }; +} diff --git a/__tests__/plots/static/index.ts b/__tests__/plots/static/index.ts index 71e6d5f3e7..4fd18d2d69 100644 --- a/__tests__/plots/static/index.ts +++ b/__tests__/plots/static/index.ts @@ -348,3 +348,4 @@ export { mockFacetPieLegend } from './mock-facet-pie-legend'; export { weatherLineMultiAxesSync } from './weather-line-multi-axes-sync'; export { mockIntervalLegendMarker } from './mock-interval-legend-marker'; export { energySankeyViewCustomTooltip } from './energy-sankey-view-custom-tooltip'; +export { alphabetIntervalColumnWidthRatio } from './alphabet-interval-column-width-ratio'; diff --git a/src/runtime/option-preprocess/index.ts b/src/runtime/option-preprocess/index.ts new file mode 100644 index 0000000000..b61033f4cf --- /dev/null +++ b/src/runtime/option-preprocess/index.ts @@ -0,0 +1,23 @@ +import { G2ViewTree } from '../types/options'; +import { flow } from '../../utils/flow'; +import { columnWidthRatio } from './style'; + +export function preprocessOption( + options: T, +): T { + const convertedOptions = adapter(options); + // If there are children, recursively convert each child node. + if (convertedOptions.children && Array.isArray(convertedOptions.children)) { + convertedOptions.children = convertedOptions.children.map((child) => + preprocessOption(child), + ); + } + + return convertedOptions; +} + +// Entry point for all syntactic sugar functions. +function adapter(options: T): T { + //@todo define a type for params of flow + return flow(columnWidthRatio)(options); +} diff --git a/src/runtime/option-preprocess/style.ts b/src/runtime/option-preprocess/style.ts new file mode 100644 index 0000000000..b5acababe6 --- /dev/null +++ b/src/runtime/option-preprocess/style.ts @@ -0,0 +1,21 @@ +import { get } from '@antv/util'; +import { G2View, G2ViewTree } from '../types/options'; + +// style: { columnWidthRatio: 0.2 } => scale: { x: { padding: 0.8 } } +export function columnWidthRatio( + options: T, +): T { + const { style, scale, type } = options; + const scaleOption: G2View = {}; + const columnWidthRatio = get(style, 'columnWidthRatio'); + if (columnWidthRatio && type === 'interval') { + scaleOption.x = { + ...scale?.x, + padding: 1 - columnWidthRatio, + }; + } + return { + ...options, + scale: { ...scale, ...scaleOption }, + }; +} diff --git a/src/runtime/render.ts b/src/runtime/render.ts index c0caea2b16..671f39a451 100644 --- a/src/runtime/render.ts +++ b/src/runtime/render.ts @@ -9,6 +9,7 @@ import { error } from '../utils/helper'; import { G2Context, G2ViewTree } from './types/options'; import { plot } from './plot'; import { VIEW_CLASS_NAME } from './constant'; +import { preprocessOption } from './option-preprocess'; /** * Infer key for each node of view tree. @@ -71,7 +72,9 @@ export function render( ): HTMLElement { // Initialize the context if it is not provided. const { width = 640, height = 480, depth = 0 } = options; - const keyed = inferKeys(options); + // Preprocessing here, such as syntactic sugar. + const preprocessedOption = preprocessOption(options); + const keyed = inferKeys(preprocessedOption); const { canvas = Canvas(width, height), emitter = new EventEmitter(), diff --git a/src/utils/flow.ts b/src/utils/flow.ts new file mode 100644 index 0000000000..924dc0042b --- /dev/null +++ b/src/utils/flow.ts @@ -0,0 +1,13 @@ +type FlowFunction

= (param: P) => P; + +/** + * 类似 lodash.flow 的方法 + * @param flows + */ +export function flow

(...flows: FlowFunction

[]): FlowFunction

{ + return (param: P) => { + return flows.reduce((result: P, f: FlowFunction

) => { + return f(result); + }, param); + }; +}