From eac7e8b1227a55d344bdc4114993e14a3ef1355d Mon Sep 17 00:00:00 2001 From: pearmini Date: Wed, 29 May 2024 16:48:18 +0800 Subject: [PATCH 1/2] feat: add channels to style and label callback --- .../static/diamondIntervalGroupX.svg | 1270 +++++++++++++++++ .../plots/static/diamond-interval-group-x.ts | 25 + __tests__/plots/static/index.ts | 1 + src/runtime/plot.ts | 15 +- 4 files changed, 1305 insertions(+), 6 deletions(-) create mode 100644 __tests__/integration/snapshots/static/diamondIntervalGroupX.svg create mode 100644 __tests__/plots/static/diamond-interval-group-x.ts diff --git a/__tests__/integration/snapshots/static/diamondIntervalGroupX.svg b/__tests__/integration/snapshots/static/diamondIntervalGroupX.svg new file mode 100644 index 0000000000..3725fb54c5 --- /dev/null +++ b/__tests__/integration/snapshots/static/diamondIntervalGroupX.svg @@ -0,0 +1,1270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VS2 + + + + + + + VVS1 + + + + + + + SI2 + + + + + + + VS1 + + + + + + + IF + + + + + + + VVS2 + + + + + + + I1 + + + + + + + SI1 + + + + + + + + + clarity + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 5000 + + + + + + + 10000 + + + + + + + 15000 + + + + + + + + + max of price + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 18791 + + + + + + + + + + + + + 16808 + + + + + + + + + + + + + 18472 + + + + + + + + + + + + + 18462 + + + + + + + + + + + + + 15231 + + + + + + + + + + + + + 17267 + + + + + + + + + + + + + 11668 + + + + + + + + + + + + + 18295 + + + + + + + + + + + + \ No newline at end of file diff --git a/__tests__/plots/static/diamond-interval-group-x.ts b/__tests__/plots/static/diamond-interval-group-x.ts new file mode 100644 index 0000000000..b948af3681 --- /dev/null +++ b/__tests__/plots/static/diamond-interval-group-x.ts @@ -0,0 +1,25 @@ +import { G2Spec } from '../../../src'; + +export function diamondIntervalGroupX(): G2Spec { + return { + type: 'interval', + data: { + type: 'fetch', + value: 'data/diamond.csv', + }, + encode: { + x: 'clarity', + y: 'price', + }, + labels: [ + { + text: (_, index, __, channels) => channels.y[index], + }, + ], + transform: [{ type: 'groupX', y: 'max' }], + style: { + fill: (_, index, __, channels) => + channels.y[index] < 11700 ? 'red' : 'blue', + }, + }; +} diff --git a/__tests__/plots/static/index.ts b/__tests__/plots/static/index.ts index acc47cc560..d9496b1b39 100644 --- a/__tests__/plots/static/index.ts +++ b/__tests__/plots/static/index.ts @@ -335,3 +335,4 @@ export { flareElementPointMoveArea } from './flare-element-point-move-area'; export { flareElementPointMoveAreaNormalizeY } from './flare-element-point-move-area-normalizeY'; export { stackBarAnnotationStyleText } from './stack-bar-annotation-style-text'; export { githubStarIntervalDarkThemeTransparent } from './github-star-interval-dark-theme-transparent'; +export { diamondIntervalGroupX } from './diamond-interval-group-x'; diff --git a/src/runtime/plot.ts b/src/runtime/plot.ts index 93a039d972..4b822f27d2 100644 --- a/src/runtime/plot.ts +++ b/src/runtime/plot.ts @@ -1331,9 +1331,10 @@ function createLabelShapeFunction( 'shape', library, ); - const { data: abstractData } = mark; + const { data: abstractData, encode } = mark; const { data: visualData, defaultLabelShape } = state; const point2d = visualData.map((d) => d.points); + const channels = mapObject(encode, (d) => d.value); // Assemble Context. const { theme, coordinate } = view; @@ -1357,7 +1358,7 @@ function createLabelShapeFunction( } = options; const visualOptions = mapObject( { ...abstractOptions, ...abstractStyle } as Record, - (d) => valueOf(d, datum, index, abstractData), + (d) => valueOf(d, datum, index, abstractData, channels), ); const { shape = defaultLabelShape, text, ...style } = visualOptions; const f = typeof formatter === 'string' ? format(formatter) : formatter; @@ -1377,12 +1378,13 @@ function createLabelShapeFunction( } function valueOf( - value: Primitive | ((d: any, i: number, array: any) => any), + value: Primitive | ((d: any, i: number, array: any, channel: any) => any), datum: Record, i: number, data: Record, + channels: Record, ) { - if (typeof value === 'function') return value(datum, i, data); + if (typeof value === 'function') return value(datum, i, data, channels); if (typeof value !== 'string') return value; if (isStrictObject(datum) && datum[value] !== undefined) return datum[value]; return value; @@ -1497,8 +1499,9 @@ function createMarkShapeFunction( 'shape', library, ); - const { data: abstractData } = mark; + const { data: abstractData, encode } = mark; const { defaultShape, data, shape: shapeLibrary } = state; + const channels = mapObject(encode, (d) => d.value); const point2d = data.map((d) => d.points); const { theme, coordinate } = view; const { type: markType, style = {} } = mark; @@ -1524,7 +1527,7 @@ function createMarkShapeFunction( const I = seriesIndex ? seriesIndex : i; const visualStyle = mapObject(style, (d) => - valueOf(d, abstractDatum, I, abstractData), + valueOf(d, abstractDatum, I, abstractData, channels), ); // Try get shape from mark first, then from library. From a5a725f20fd2b14ab98e29161a7f1240fbe3c5c9 Mon Sep 17 00:00:00 2001 From: pearmini Date: Wed, 29 May 2024 17:10:11 +0800 Subject: [PATCH 2/2] fix: cr --- __tests__/plots/static/diamond-interval-group-x.ts | 6 +++--- src/runtime/plot.ts | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/__tests__/plots/static/diamond-interval-group-x.ts b/__tests__/plots/static/diamond-interval-group-x.ts index b948af3681..fcc7049f39 100644 --- a/__tests__/plots/static/diamond-interval-group-x.ts +++ b/__tests__/plots/static/diamond-interval-group-x.ts @@ -13,13 +13,13 @@ export function diamondIntervalGroupX(): G2Spec { }, labels: [ { - text: (_, index, __, channels) => channels.y[index], + text: (_, index, __, { channel }) => channel.y[index], }, ], transform: [{ type: 'groupX', y: 'max' }], style: { - fill: (_, index, __, channels) => - channels.y[index] < 11700 ? 'red' : 'blue', + fill: (_, index, __, { channel }) => + channel.y[index] < 11700 ? 'red' : 'blue', }, }; } diff --git a/src/runtime/plot.ts b/src/runtime/plot.ts index 4b822f27d2..230ee63832 100644 --- a/src/runtime/plot.ts +++ b/src/runtime/plot.ts @@ -1334,7 +1334,7 @@ function createLabelShapeFunction( const { data: abstractData, encode } = mark; const { data: visualData, defaultLabelShape } = state; const point2d = visualData.map((d) => d.points); - const channels = mapObject(encode, (d) => d.value); + const channel = mapObject(encode, (d) => d.value); // Assemble Context. const { theme, coordinate } = view; @@ -1358,7 +1358,7 @@ function createLabelShapeFunction( } = options; const visualOptions = mapObject( { ...abstractOptions, ...abstractStyle } as Record, - (d) => valueOf(d, datum, index, abstractData, channels), + (d) => valueOf(d, datum, index, abstractData, { channel }), ); const { shape = defaultLabelShape, text, ...style } = visualOptions; const f = typeof formatter === 'string' ? format(formatter) : formatter; @@ -1382,9 +1382,9 @@ function valueOf( datum: Record, i: number, data: Record, - channels: Record, + options: { channel: Record }, ) { - if (typeof value === 'function') return value(datum, i, data, channels); + if (typeof value === 'function') return value(datum, i, data, options); if (typeof value !== 'string') return value; if (isStrictObject(datum) && datum[value] !== undefined) return datum[value]; return value; @@ -1501,7 +1501,7 @@ function createMarkShapeFunction( ); const { data: abstractData, encode } = mark; const { defaultShape, data, shape: shapeLibrary } = state; - const channels = mapObject(encode, (d) => d.value); + const channel = mapObject(encode, (d) => d.value); const point2d = data.map((d) => d.points); const { theme, coordinate } = view; const { type: markType, style = {} } = mark; @@ -1527,7 +1527,7 @@ function createMarkShapeFunction( const I = seriesIndex ? seriesIndex : i; const visualStyle = mapObject(style, (d) => - valueOf(d, abstractDatum, I, abstractData, channels), + valueOf(d, abstractDatum, I, abstractData, { channel }), ); // Try get shape from mark first, then from library.