diff --git a/__tests__/integration/snapshots/static/gaugeRoundShape.svg b/__tests__/integration/snapshots/static/gaugeRoundShape.svg
new file mode 100644
index 0000000000..b2f1697c8c
--- /dev/null
+++ b/__tests__/integration/snapshots/static/gaugeRoundShape.svg
@@ -0,0 +1,506 @@
+
\ No newline at end of file
diff --git a/__tests__/plots/static/gauge-round-shape.ts b/__tests__/plots/static/gauge-round-shape.ts
new file mode 100644
index 0000000000..025b70bd94
--- /dev/null
+++ b/__tests__/plots/static/gauge-round-shape.ts
@@ -0,0 +1,29 @@
+import { G2Spec } from '../../../src';
+
+export function gaugeRoundShape(): G2Spec {
+ return {
+ type: 'gauge',
+ data: {
+ value: {
+ target: 159,
+ total: 400,
+ name: 'score',
+ thresholds: [100, 200, 400],
+ },
+ },
+ scale: {
+ color: {
+ range: ['#F4664A', '#FAAD14', 'green'],
+ },
+ },
+ legend: false,
+ style: {
+ arcShape: 'round',
+ arcLineWidth: 2,
+ arcStroke: '#fff',
+ textContent: (target, total) => {
+ return `得分:${target}\n占比:${(target / total) * 100}%`;
+ },
+ },
+ };
+}
diff --git a/__tests__/plots/static/index.ts b/__tests__/plots/static/index.ts
index 8d3ecfe4fb..cb15d80681 100644
--- a/__tests__/plots/static/index.ts
+++ b/__tests__/plots/static/index.ts
@@ -216,6 +216,7 @@ export { soldIntervalCustomShape } from './sold-interval-custom-shape';
export { gaugeDefault } from './gauge-default';
export { gaugeCustomColor } from './gauge-custom-color';
export { gaugeCustomShape } from './gauge-custom-shape';
+export { gaugeRoundShape } from './gauge-round-shape';
export { scoreByItemAreaRadarSize } from './score-by-item-area-radar-size';
export { mockPointLogTicks } from './mock-point-log-ticks';
export { alphabetIntervalLabelRotate } from './alphabet-interval-label-rotate';
diff --git a/site/examples/general/gauge/demo/gauge-round.ts b/site/examples/general/gauge/demo/gauge-round.ts
new file mode 100644
index 0000000000..a9801ba002
--- /dev/null
+++ b/site/examples/general/gauge/demo/gauge-round.ts
@@ -0,0 +1,32 @@
+import { Chart } from '@antv/g2';
+
+const chart = new Chart({
+ container: 'container',
+ autoFit: true,
+});
+
+chart
+ .gauge()
+ .data({
+ value: {
+ target: 159,
+ total: 400,
+ name: 'score',
+ thresholds: [100, 200, 400],
+ },
+ })
+ .scale('color', {
+ range: ['#F4664A', '#FAAD14', 'green'],
+ })
+ .style({
+ arcShape: 'round',
+ arcLineWidth: 2,
+ arcStroke: '#fff',
+ })
+ .style(
+ 'textContent',
+ (target, total) => `得分:${target}\n占比:${(target / total) * 100}%`,
+ )
+ .legend(false);
+
+chart.render();
diff --git a/site/examples/general/gauge/demo/meta.json b/site/examples/general/gauge/demo/meta.json
index e364babcb5..4ed9dd9ebc 100644
--- a/site/examples/general/gauge/demo/meta.json
+++ b/site/examples/general/gauge/demo/meta.json
@@ -19,6 +19,14 @@
"en": "Custom Color Gauge Chart"
},
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*vE7cR6ZHHk0AAAAAAAAAAAAADmJ7AQ/original"
+ },
+ {
+ "filename": "gauge-round.ts",
+ "title": {
+ "zh": "仪表盘内置 round 形状",
+ "en": "Round Shape Gauge Chart"
+ },
+ "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*_tUeQ64QNVEAAAAAAAAAAAAADmJ7AQ/original"
}
]
}
diff --git a/src/mark/gauge.ts b/src/mark/gauge.ts
index f05b09c961..7abd57804d 100644
--- a/src/mark/gauge.ts
+++ b/src/mark/gauge.ts
@@ -9,6 +9,7 @@ import { getTransformOptions } from '../utils/coordinate';
import { Radial } from '../coordinate';
import { applyStyle, getOrigin } from '../shape/utils';
import { select } from '../utils/selection';
+import { GaugeRound } from '../shape';
const indicatorShape: SC = (options, context) => {
const { shape, radius, ...style } = options;
@@ -215,13 +216,16 @@ export const Gauge: CC = (options) => {
// pointer + pin
const indicatorStyle = filterPrefixObject(style, ['pointer', 'pin']);
+ const arcStyle = subObject(style, 'arc');
+ const shape = arcStyle.shape;
+
return [
deepMix({}, DEFAULT_OPTIONS, {
type: 'interval',
transform: [{ type: 'stackY' }],
data: totalData,
scale: newScale,
- style: subObject(style, 'arc'),
+ style: shape === 'round' ? { ...arcStyle, shape: GaugeRound } : arcStyle,
animate:
typeof animate === 'object' ? subObject(animate, 'arc') : animate,
...resOptions,
diff --git a/src/shape/gauge/round.ts b/src/shape/gauge/round.ts
new file mode 100644
index 0000000000..f444e16c4a
--- /dev/null
+++ b/src/shape/gauge/round.ts
@@ -0,0 +1,57 @@
+import { omit } from '@antv/util';
+import type { Vector2, ShapeComponent as SC } from '../../runtime';
+
+export type RoundOptions = Record;
+
+// Get point1 point2 radius.
+const getR = (point1, point2) => {
+ return (
+ Math.sqrt(
+ Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2),
+ ) / 2
+ );
+};
+
+// Gauge round.
+export const Round: SC = (options, context) => {
+ if (!context) return;
+ const { coordinate } = context;
+ if (!coordinate?.getCenter) return;
+ // Get coordinate center point.
+ const center = coordinate.getCenter() as Vector2;
+
+ return (points, cfg, defaultCfg) => {
+ const { document } = context.canvas;
+ const { color, index } = cfg;
+
+ const g = document.createElement('g', {});
+
+ const minR = getR(points[0], points[1]);
+ const maxR = getR(points[0], center) * 2;
+
+ /**
+ * MinR small circle radius, maxR big circle radius.
+ * Draw four arcs.
+ * Style lineWidth and stroke for the time being inset.
+ */
+ const roundPath = document.createElement('path', {
+ style: {
+ path: [
+ ['M', ...points[0]],
+ ['A', minR, minR, 0, 1, 0, ...points[1]],
+ ['A', maxR + minR * 2, maxR + minR * 2, 0, 0, 0, ...points[2]],
+ ['A', minR, minR, 0, 1, index === 0 ? 0 : 1, ...points[3]],
+ ['A', maxR, maxR, 0, 0, 1, ...points[0]],
+ ['Z'],
+ ],
+ ...defaultCfg,
+ ...omit(options, ['shape', 'last', 'first']),
+ fill: color || defaultCfg.color,
+ },
+ });
+
+ g.appendChild(roundPath);
+
+ return g;
+ };
+};
diff --git a/src/shape/index.ts b/src/shape/index.ts
index 6c466ab5f2..ba161d9457 100644
--- a/src/shape/index.ts
+++ b/src/shape/index.ts
@@ -58,6 +58,7 @@ export { Rect as RectShape } from './interval/rect';
export { Hollow as RectHollow } from './interval/hollow';
export { Shape as ShapeShape } from './shape/shape';
export { Liquid as LiquidShape } from './liquid/liquid';
+export { Round as GaugeRound } from './gauge/round';
export type { RectOptions as IntervalShapeOptions } from './interval/rect';
export type { HollowOptions as IntervalHollowOptions } from './interval/hollow';