From 3834599c7b7cc2f7f0c250948fa1ac19bee37690 Mon Sep 17 00:00:00 2001 From: shield2018 <> Date: Fri, 7 Apr 2023 11:27:49 +0800 Subject: [PATCH] fix(interval): fix interval render funnel (#4868) --- .../static/alphabetIntervalFunnel.png | Bin 0 -> 10543 bytes .../plots/static/alphabet-interval-funnel.ts | 38 ++++++++++++++++++ __tests__/plots/static/index.ts | 1 + src/shape/interval/color.ts | 12 +++++- 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 __tests__/integration/snapshots/static/alphabetIntervalFunnel.png create mode 100644 __tests__/plots/static/alphabet-interval-funnel.ts diff --git a/__tests__/integration/snapshots/static/alphabetIntervalFunnel.png b/__tests__/integration/snapshots/static/alphabetIntervalFunnel.png new file mode 100644 index 0000000000000000000000000000000000000000..be9d422f36749cb69b3f2d96e6d51b54fdc894cf GIT binary patch literal 10543 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 literal 0 HcmV?d00001 diff --git a/__tests__/plots/static/alphabet-interval-funnel.ts b/__tests__/plots/static/alphabet-interval-funnel.ts new file mode 100644 index 0000000000..09b223a624 --- /dev/null +++ b/__tests__/plots/static/alphabet-interval-funnel.ts @@ -0,0 +1,38 @@ +import { G2Spec } from '../../../src'; + +export function alphabetIntervalFunnel(): G2Spec { + return { + type: 'interval', + coordinate: { + transform: [{ type: 'transpose' }], + }, + data: [ + { text: '页面', value: 1000 }, + { text: '页面1', value: 900 }, + { text: '页面2', value: 800 }, + { text: '页面3', value: 700 }, + ], + transform: [ + { + type: 'symmetryY', + }, + ], + axis: { + x: false, + y: false, + }, + style: { + radius: 6, + stroke: '#ff0000', + }, + encode: { + x: 'text', + y: 'value', + color: 'steelblue', + shape: 'funnel', + }, + scale: { + x: { paddingOuter: 0, paddingInner: 0 }, + }, + }; +} diff --git a/__tests__/plots/static/index.ts b/__tests__/plots/static/index.ts index 43a9343a26..e1f2310a8c 100644 --- a/__tests__/plots/static/index.ts +++ b/__tests__/plots/static/index.ts @@ -1,4 +1,5 @@ export { alphabetInterval } from './alphabet-interval'; +export { alphabetIntervalFunnel } from './alphabet-interval-funnel'; export { alphabetIntervalTitle } from './alphabet-interval-title'; export { alphabetIntervalLabelOverflowHide } from './alphabet-interval-label-overflow-hide'; export { alphabetIntervalLabelContrastReverse } from './alphabet-interval-label-contrast-reverse'; diff --git a/src/shape/interval/color.ts b/src/shape/interval/color.ts index bb948fc9b5..b1d3fb7c3e 100644 --- a/src/shape/interval/color.ts +++ b/src/shape/interval/color.ts @@ -1,5 +1,5 @@ import { Path, Rect } from '@antv/g'; -import { arc } from 'd3-shape'; +import { arc, line, curveLinearClosed } from 'd3-shape'; import { Vector2, ShapeComponent as SC } from '../../runtime'; import { isPolar, isHelix, isTranspose } from '../../utils/coordinate'; import { select } from '../../utils/selection'; @@ -40,7 +40,7 @@ export function rect( if (!isPolar(coordinate) && !isHelix(coordinate)) { const tpShape = !!isTranspose(coordinate); - const [p0, , p2] = tpShape ? reorder(points) : points; + const [p0, p1, p2, p3] = tpShape ? reorder(points) : points; const [x, y] = p0; const [width, height] = sub(p2, p0); // Deal with width or height is negative. @@ -52,7 +52,15 @@ export function rect( const finalY = absY + insetTop; const finalWidth = absWidth - (insetLeft + insetRight); const finalHeight = absHeight - (insetTop + insetBottom); + const { shape } = value; + if (shape === 'funnel' || shape === 'pyramid') { + const b = line().curve(curveLinearClosed)([p0, p1, p2, p3]); + return select(new Path({})) + .style('path', b) + .call(applyStyle, rest) + .node(); + } return select(new Rect({})) .style('x', finalX) .style('y', finalY)