vccs 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,8 +15,8 @@ export declare const YAxis: import('vue').DefineComponent<import('vue').ExtractP
15
15
  default: boolean;
16
16
  };
17
17
  width: {
18
- type: NumberConstructor;
19
- default: number;
18
+ type: PropType<number | "auto">;
19
+ default: import('../../types/axis').YAxisWidth;
20
20
  };
21
21
  hide: {
22
22
  type: BooleanConstructor;
@@ -99,8 +99,8 @@ export declare const YAxis: import('vue').DefineComponent<import('vue').ExtractP
99
99
  default: boolean;
100
100
  };
101
101
  width: {
102
- type: NumberConstructor;
103
- default: number;
102
+ type: PropType<number | "auto">;
103
+ default: import('../../types/axis').YAxisWidth;
104
104
  };
105
105
  hide: {
106
106
  type: BooleanConstructor;
@@ -172,7 +172,7 @@ export declare const YAxis: import('vue').DefineComponent<import('vue').ExtractP
172
172
  }>> & Readonly<{}>, {
173
173
  tickFormatter: Function;
174
174
  unit: string;
175
- width: number;
175
+ width: number | "auto";
176
176
  scale: string | Function;
177
177
  padding: Record<string, any>;
178
178
  type: string;
@@ -110,6 +110,11 @@ export declare const CartesianAxis: import('vue').DefineComponent<import('vue').
110
110
  type: StringConstructor;
111
111
  default: string;
112
112
  };
113
+ /** Additional props to spread to each tick Text element. */
114
+ tickTextProps: {
115
+ type: ObjectConstructor;
116
+ default: any;
117
+ };
113
118
  }>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
114
119
  x: {
115
120
  type: NumberConstructor;
@@ -188,6 +193,11 @@ export declare const CartesianAxis: import('vue').DefineComponent<import('vue').
188
193
  type: StringConstructor;
189
194
  default: string;
190
195
  };
196
+ /** Additional props to spread to each tick Text element. */
197
+ tickTextProps: {
198
+ type: ObjectConstructor;
199
+ default: any;
200
+ };
191
201
  }>> & Readonly<{}>, {
192
202
  interval: string | number;
193
203
  tick: boolean;
@@ -207,4 +217,5 @@ export declare const CartesianAxis: import('vue').DefineComponent<import('vue').
207
217
  tickLine: boolean | Record<string, any>;
208
218
  tickSize: number;
209
219
  tickMargin: number;
220
+ tickTextProps: Record<string, any>;
210
221
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
@@ -1,6 +1,6 @@
1
1
  import { PropType, StyleValue } from 'vue';
2
2
  import { CategoricalChartFunc } from '../types';
3
- export declare const RechartsWrapper: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
3
+ export declare const ChartsWrapper: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
4
4
  class: {
5
5
  type: PropType<import('../types').VueClassValue>;
6
6
  default: any;
@@ -33,6 +33,9 @@ export declare const RechartsWrapper: import('vue').DefineComponent<import('vue'
33
33
  onMouseUp: {
34
34
  type: PropType<CategoricalChartFunc>;
35
35
  };
36
+ onResize: {
37
+ type: PropType<(width: number, height: number) => void>;
38
+ };
36
39
  onTouchEnd: {
37
40
  type: PropType<CategoricalChartFunc>;
38
41
  };
@@ -42,6 +45,10 @@ export declare const RechartsWrapper: import('vue').DefineComponent<import('vue'
42
45
  onTouchStart: {
43
46
  type: PropType<CategoricalChartFunc>;
44
47
  };
48
+ responsive: {
49
+ type: BooleanConstructor;
50
+ default: boolean;
51
+ };
45
52
  style: {
46
53
  type: PropType<StyleValue>;
47
54
  };
@@ -82,6 +89,9 @@ export declare const RechartsWrapper: import('vue').DefineComponent<import('vue'
82
89
  onMouseUp: {
83
90
  type: PropType<CategoricalChartFunc>;
84
91
  };
92
+ onResize: {
93
+ type: PropType<(width: number, height: number) => void>;
94
+ };
85
95
  onTouchEnd: {
86
96
  type: PropType<CategoricalChartFunc>;
87
97
  };
@@ -91,6 +101,10 @@ export declare const RechartsWrapper: import('vue').DefineComponent<import('vue'
91
101
  onTouchStart: {
92
102
  type: PropType<CategoricalChartFunc>;
93
103
  };
104
+ responsive: {
105
+ type: BooleanConstructor;
106
+ default: boolean;
107
+ };
94
108
  style: {
95
109
  type: PropType<StyleValue>;
96
110
  };
@@ -100,4 +114,5 @@ export declare const RechartsWrapper: import('vue').DefineComponent<import('vue'
100
114
  };
101
115
  }>> & Readonly<{}>, {
102
116
  class: import('../types').VueClassValue;
117
+ responsive: boolean;
103
118
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
@@ -1,4 +1,4 @@
1
- import { CSSProperties } from 'vue';
1
+ import { StyleValue } from 'vue';
2
2
  import { VueClassValue } from '../types';
3
3
  interface SurfaceProps {
4
4
  width: number;
@@ -10,7 +10,7 @@ interface SurfaceProps {
10
10
  height?: number;
11
11
  };
12
12
  class?: VueClassValue;
13
- style?: CSSProperties;
13
+ style?: StyleValue;
14
14
  title?: string;
15
15
  desc?: string;
16
16
  }
@@ -67,6 +67,10 @@ export declare const CategoricalProps: {
67
67
  outerRadius: {
68
68
  type: (NumberConstructor | StringConstructor)[];
69
69
  };
70
+ responsive: {
71
+ type: BooleanConstructor;
72
+ default: boolean;
73
+ };
70
74
  reverseStackOrder: {
71
75
  type: BooleanConstructor;
72
76
  default: boolean;
@@ -1,4 +1,4 @@
1
- import { CSSProperties, SVGAttributes } from 'vue';
1
+ import { SVGAttributes, StyleValue } from 'vue';
2
2
  import { VueClassValue } from '../types';
3
3
  interface ViewBox {
4
4
  x?: number;
@@ -11,7 +11,7 @@ declare const Surface: import('vue').DefineComponent<Omit<SVGAttributes, "viewBo
11
11
  height: number;
12
12
  viewBox?: ViewBox;
13
13
  class?: VueClassValue;
14
- style?: CSSProperties;
14
+ style?: StyleValue;
15
15
  title?: string;
16
16
  desc?: string;
17
17
  }, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Omit<SVGAttributes, "viewBox"> & {
@@ -19,7 +19,7 @@ declare const Surface: import('vue').DefineComponent<Omit<SVGAttributes, "viewBo
19
19
  height: number;
20
20
  viewBox?: ViewBox;
21
21
  class?: VueClassValue;
22
- style?: CSSProperties;
22
+ style?: StyleValue;
23
23
  title?: string;
24
24
  desc?: string;
25
25
  }> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
@@ -2,9 +2,10 @@ import { useIsPanorama } from "../../context/PanoramaContextProvider.mjs";
2
2
  import { selectAxisViewBox } from "../../state/selectors/selectChartOffset.mjs";
3
3
  import { implicitYAxis, selectAxisScale, selectTicksOfAxis, selectYAxisPosition, selectYAxisSize } from "../../state/selectors/axisSelectors.mjs";
4
4
  import { useAppDispatch, useAppSelector } from "../../state/hooks.mjs";
5
- import { addYAxis, removeYAxis } from "../../state/cartesianAxisSlice.mjs";
5
+ import { addYAxis, removeYAxis, updateYAxisWidth } from "../../state/cartesianAxisSlice.mjs";
6
6
  import { CartesianAxis } from "../cartesian-axis/CartesianAxis.mjs";
7
- import { createVNode, defineComponent, mergeProps, watchEffect } from "vue";
7
+ import { getCalculatedYAxisWidth } from "../../utils/YAxisUtils.mjs";
8
+ import { createVNode, defineComponent, isVNode, mergeProps, nextTick, ref, watch, watchEffect } from "vue";
8
9
  //#region src/cartesian/axis/YAxis.tsx
9
10
  var YAxisImpl = /* @__PURE__ */ defineComponent({
10
11
  props: { yAxisId: {
@@ -15,11 +16,55 @@ var YAxisImpl = /* @__PURE__ */ defineComponent({
15
16
  setup(props, { attrs }) {
16
17
  const isPanorama = useIsPanorama();
17
18
  const axisType = "yAxis";
19
+ const dispatch = useAppDispatch();
18
20
  const scale = useAppSelector((state) => selectAxisScale(state, axisType, props.yAxisId, isPanorama));
19
21
  const axisSize = useAppSelector((state) => selectYAxisSize(state, props.yAxisId));
20
22
  const position = useAppSelector((state) => selectYAxisPosition(state, props.yAxisId));
21
23
  const cartesianTickItems = useAppSelector((state) => selectTicksOfAxis(state, axisType, props.yAxisId, isPanorama));
22
24
  const viewBox = useAppSelector(selectAxisViewBox);
25
+ const chartDataLengthEmpty = useAppSelector((state) => !state.chartData.chartData?.length);
26
+ const cartesianAxisRef = ref(null);
27
+ const isAutoWidth = () => attrs.width === "auto";
28
+ const measureAxisWidth = () => {
29
+ const el = cartesianAxisRef.value?.$el;
30
+ if (!el) return;
31
+ const ticks = el.getElementsByClassName("v-charts-cartesian-axis-tick-value");
32
+ const label = el.getElementsByClassName("v-charts-label")[0];
33
+ return getCalculatedYAxisWidth({
34
+ ticks,
35
+ label,
36
+ labelGapWithTick: 5,
37
+ tickSize: typeof attrs.tickSize === "number" ? attrs.tickSize : 6,
38
+ tickMargin: typeof attrs.tickMargin === "number" ? attrs.tickMargin : 2
39
+ });
40
+ };
41
+ watch(chartDataLengthEmpty, (empty) => {
42
+ if (empty === false && isAutoWidth()) dispatch(updateYAxisWidth({
43
+ id: props.yAxisId,
44
+ width: 60
45
+ }));
46
+ });
47
+ const updateAutoWidth = () => {
48
+ if (!isAutoWidth() || axisSize.value == null) return;
49
+ const label = attrs.label;
50
+ if (typeof label === "function" || isVNode(label)) return;
51
+ const updatedYAxisWidth = measureAxisWidth();
52
+ if (updatedYAxisWidth == null) return;
53
+ if (Math.round(axisSize.value.width) !== Math.round(updatedYAxisWidth)) dispatch(updateYAxisWidth({
54
+ id: props.yAxisId,
55
+ width: updatedYAxisWidth
56
+ }));
57
+ };
58
+ watch([
59
+ axisSize,
60
+ cartesianTickItems,
61
+ () => attrs.label
62
+ ], () => {
63
+ nextTick(updateAutoWidth);
64
+ }, {
65
+ flush: "post",
66
+ immediate: true
67
+ });
23
68
  return () => {
24
69
  const { ...allOtherProps } = props;
25
70
  if (axisSize.value == null || position.value == null) return null;
@@ -31,7 +76,9 @@ var YAxisImpl = /* @__PURE__ */ defineComponent({
31
76
  "width": axisSize.value?.width,
32
77
  "height": axisSize.value?.height,
33
78
  "ticks": cartesianTickItems.value,
34
- "class": ["v-charts-yAxis yAxis"]
79
+ "tickTextProps": isAutoWidth() ? { width: void 0 } : { width: axisSize.value?.width },
80
+ "class": ["v-charts-yAxis yAxis"],
81
+ "ref": cartesianAxisRef
35
82
  }), null);
36
83
  };
37
84
  }
@@ -53,7 +100,7 @@ var YAxisSettingsDispatcher = /* @__PURE__ */ defineComponent({
53
100
  includeHidden: Boolean,
54
101
  reversed: Boolean,
55
102
  ticks: Array,
56
- width: Number,
103
+ width: [Number, String],
57
104
  orientation: String,
58
105
  mirror: Boolean,
59
106
  hide: Boolean,
@@ -113,7 +160,7 @@ var YAxis = /* @__PURE__ */ defineComponent({
113
160
  default: implicitYAxis.allowDuplicatedCategory
114
161
  },
115
162
  width: {
116
- type: Number,
163
+ type: [Number, String],
117
164
  default: implicitYAxis.width
118
165
  },
119
166
  hide: {
@@ -90,6 +90,10 @@ var CartesianAxis = /* @__PURE__ */ defineComponent({
90
90
  stroke: {
91
91
  type: String,
92
92
  default: "#666"
93
+ },
94
+ tickTextProps: {
95
+ type: Object,
96
+ default: void 0
93
97
  }
94
98
  },
95
99
  setup(props, { slots }) {
@@ -235,7 +239,8 @@ var CartesianAxis = /* @__PURE__ */ defineComponent({
235
239
  index: i,
236
240
  payload: entry,
237
241
  visibleTicksCount: finalTicks.length,
238
- tickFormatter
242
+ tickFormatter,
243
+ ...props.tickTextProps
239
244
  };
240
245
  return createVNode(Layer, {
241
246
  "class": "v-charts-cartesian-axis-tick",
@@ -10,10 +10,11 @@ import { useSynchronisedEventsFromOtherCharts } from "../events/useChartSynchron
10
10
  import { useReportScale } from "../state/utils/useReportScale.mjs";
11
11
  import { providePortalRaw } from "./TooltipPortalContext.mjs";
12
12
  import { provideLegendPortalRaw } from "./LegendPortalContext.mjs";
13
- import { createVNode, defineComponent, ref } from "vue";
14
- //#region src/chart/RechartsWrapper.tsx
15
- var RechartsWrapper = /* @__PURE__ */ defineComponent({
16
- name: "RechartsWrapper",
13
+ import { createVNode, defineComponent, onMounted, ref } from "vue";
14
+ import { useResizeObserver } from "@vueuse/core";
15
+ //#region src/chart/ChartsWrapper.tsx
16
+ var ChartsWrapper = /* @__PURE__ */ defineComponent({
17
+ name: "ChartsWrapper",
17
18
  props: {
18
19
  class: classProp,
19
20
  height: {
@@ -28,9 +29,14 @@ var RechartsWrapper = /* @__PURE__ */ defineComponent({
28
29
  onMouseLeave: { type: Function },
29
30
  onMouseMove: { type: Function },
30
31
  onMouseUp: { type: Function },
32
+ onResize: { type: Function },
31
33
  onTouchEnd: { type: Function },
32
34
  onTouchMove: { type: Function },
33
35
  onTouchStart: { type: Function },
36
+ responsive: {
37
+ type: Boolean,
38
+ default: false
39
+ },
34
40
  style: { type: [
35
41
  String,
36
42
  Object,
@@ -49,11 +55,24 @@ var RechartsWrapper = /* @__PURE__ */ defineComponent({
49
55
  const legendPortal = ref(null);
50
56
  providePortalRaw(tooltipPortal);
51
57
  provideLegendPortalRaw(legendPortal);
58
+ const wrapperEl = ref(null);
52
59
  const innerRef = (node) => {
53
60
  scaleRef.value = node;
54
61
  tooltipPortal.value = node;
55
62
  legendPortal.value = node;
63
+ wrapperEl.value = node;
56
64
  };
65
+ if (props.responsive) {
66
+ useResizeObserver(wrapperEl, (entries) => {
67
+ const { width, height } = entries[0].contentRect;
68
+ props.onResize?.(width, height);
69
+ });
70
+ onMounted(() => {
71
+ if (!wrapperEl.value) return;
72
+ const { width, height } = wrapperEl.value.getBoundingClientRect();
73
+ props.onResize?.(width, height);
74
+ });
75
+ }
57
76
  const myOnClick = (e) => {
58
77
  const chartPointer = getChartPointer(e);
59
78
  if (chartPointer) dispatch(mouseClickAction(chartPointer));
@@ -136,7 +155,12 @@ var RechartsWrapper = /* @__PURE__ */ defineComponent({
136
155
  };
137
156
  return () => createVNode("div", {
138
157
  "class": ["v-charts-wrapper", props.class],
139
- "style": [{
158
+ "style": [props.responsive ? {
159
+ position: "relative",
160
+ cursor: "default",
161
+ width: "100%",
162
+ height: "100%"
163
+ } : {
140
164
  position: "relative",
141
165
  cursor: "default",
142
166
  width: `${props.width}px`,
@@ -161,4 +185,4 @@ var RechartsWrapper = /* @__PURE__ */ defineComponent({
161
185
  }
162
186
  });
163
187
  //#endregion
164
- export { RechartsWrapper };
188
+ export { ChartsWrapper };
@@ -3,7 +3,7 @@ import { useAppDispatch } from "../state/hooks.mjs";
3
3
  import { Layer } from "../container/Layer.mjs";
4
4
  import { Animate } from "../animation/Animate.mjs";
5
5
  import { createRechartsStore } from "../state/store.mjs";
6
- import { RechartsWrapper } from "./RechartsWrapper.mjs";
6
+ import { ChartsWrapper } from "./ChartsWrapper.mjs";
7
7
  import Surface from "../container/Surface.mjs";
8
8
  import { computeSankeyLayout, linkPathGenerator } from "./sankeyUtils.mjs";
9
9
  import { Fragment, computed, createVNode, defineComponent, watchEffect } from "vue";
@@ -318,7 +318,7 @@ var Sankey = /* @__PURE__ */ defineComponent({
318
318
  provideStore({ store: createRechartsStore({ options: sankeyOptions }, "Sankey") });
319
319
  return () => {
320
320
  if (!props.data || !props.data.nodes || props.data.nodes.length === 0) return null;
321
- return createVNode(RechartsWrapper, {
321
+ return createVNode(ChartsWrapper, {
322
322
  "width": props.width,
323
323
  "height": props.height
324
324
  }, { default: () => [createVNode(SankeyInner, props, {
@@ -3,7 +3,7 @@ import { addTooltipEntrySettings, mouseLeaveItem, removeTooltipEntrySettings, se
3
3
  import { useAppDispatch } from "../state/hooks.mjs";
4
4
  import { Layer } from "../container/Layer.mjs";
5
5
  import { createRechartsStore } from "../state/store.mjs";
6
- import { RechartsWrapper } from "./RechartsWrapper.mjs";
6
+ import { ChartsWrapper } from "./ChartsWrapper.mjs";
7
7
  import Surface from "../container/Surface.mjs";
8
8
  import { Sector } from "../shape/Sector.mjs";
9
9
  import { computeSunburstLayout } from "./sunburstUtils.mjs";
@@ -218,7 +218,7 @@ var SunburstChart = /* @__PURE__ */ defineComponent({
218
218
  provideStore({ store: createRechartsStore({ options: sunburstOptions }, "SunburstChart") });
219
219
  return () => {
220
220
  if (!props.data?.children || props.data.children.length === 0) return null;
221
- return createVNode(RechartsWrapper, {
221
+ return createVNode(ChartsWrapper, {
222
222
  "width": props.width,
223
223
  "height": props.height
224
224
  }, { default: () => [createVNode(SunburstInner, props, { content: slots.content }), slots.default?.()] });
@@ -17,7 +17,13 @@ var Surface_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
17
17
  height: {},
18
18
  viewBox: {},
19
19
  class: {},
20
- style: {},
20
+ style: { type: [
21
+ Boolean,
22
+ null,
23
+ String,
24
+ Object,
25
+ Array
26
+ ] },
21
27
  title: {},
22
28
  desc: {}
23
29
  },
@@ -4,7 +4,7 @@ import { Layer } from "../container/Layer.mjs";
4
4
  import { getStringSize } from "../utils/attrs.mjs";
5
5
  import { Animate } from "../animation/Animate.mjs";
6
6
  import { createRechartsStore } from "../state/store.mjs";
7
- import { RechartsWrapper } from "./RechartsWrapper.mjs";
7
+ import { ChartsWrapper } from "./ChartsWrapper.mjs";
8
8
  import Surface from "../container/Surface.mjs";
9
9
  import { computeTreemapLayout } from "./treemapUtils.mjs";
10
10
  import { Fragment, computed, createTextVNode, createVNode, defineComponent, ref, watchEffect } from "vue";
@@ -368,7 +368,7 @@ var Treemap = /* @__PURE__ */ defineComponent({
368
368
  provideStore({ store: createRechartsStore({ options: treemapOptions }, "Treemap") });
369
369
  return () => {
370
370
  if (!props.data || props.data.length === 0) return null;
371
- return createVNode(RechartsWrapper, {
371
+ return createVNode(ChartsWrapper, {
372
372
  "width": props.width,
373
373
  "height": props.height
374
374
  }, { default: () => [createVNode(TreemapInner, props, { content: slots.content }), slots.default?.()] });
@@ -5,13 +5,13 @@ import { createRechartsStore } from "../state/store.mjs";
5
5
  import Surface_default from "./Surface.mjs";
6
6
  import { ChartDataContextProvider } from "../context/ChartDataContextProvider.mjs";
7
7
  import ClipPath_default from "../container/ClipPath.mjs";
8
- import { RechartsWrapper } from "./RechartsWrapper.mjs";
8
+ import { ChartsWrapper } from "./ChartsWrapper.mjs";
9
9
  import { FULL_WIDTH_AND_HEIGHT } from "./const.mjs";
10
10
  import { ReportMainChartProps } from "../state/ReportMainChartProps.mjs";
11
11
  import ReportChartProps_default from "../state/ReportChartProps.mjs";
12
12
  import { applyDefaultProps } from "../utils/props.mjs";
13
13
  import { ReportPolarOptions } from "../state/ReportPolarOptions.mjs";
14
- import { Fragment, createVNode, defineComponent, mergeProps } from "vue";
14
+ import { Fragment, createVNode, defineComponent, mergeProps, ref } from "vue";
15
15
  import { provideStore } from "@reduxjs/vue-redux";
16
16
  //#region src/chart/generateCategoricalChart.tsx
17
17
  var defaultLayout = "horizontal";
@@ -63,6 +63,10 @@ var CategoricalProps = {
63
63
  },
64
64
  maxBarSize: { type: Number },
65
65
  outerRadius: { type: [Number, String] },
66
+ responsive: {
67
+ type: Boolean,
68
+ default: false
69
+ },
66
70
  reverseStackOrder: {
67
71
  type: Boolean,
68
72
  default: false
@@ -102,38 +106,57 @@ function generateCategoricalChart({ chartName, defaultProps = {}, defaultTooltip
102
106
  eventEmitter: void 0
103
107
  } }, props.id ?? chartName) });
104
108
  const clipPathId = provideClipPathId(props);
109
+ const responsiveSize = ref({
110
+ width: 0,
111
+ height: 0
112
+ });
113
+ function handleResize(width, height) {
114
+ const roundedWidth = Math.round(width);
115
+ const roundedHeight = Math.round(height);
116
+ if (responsiveSize.value.width === roundedWidth && responsiveSize.value.height === roundedHeight) return;
117
+ responsiveSize.value = {
118
+ width: roundedWidth,
119
+ height: roundedHeight
120
+ };
121
+ }
105
122
  return () => {
106
- const { compact, width, height, title, desc, ...rest } = props;
123
+ const { compact, width, height, title, desc, responsive, ...rest } = props;
107
124
  const attributes = { ...attrs };
108
- if (!validateWidthHeight({
109
- width,
110
- height
111
- })) return null;
125
+ const effectiveWidth = responsive ? responsiveSize.value.width : width;
126
+ const effectiveHeight = responsive ? responsiveSize.value.height : height;
127
+ const hasValidSize = validateWidthHeight({
128
+ width: effectiveWidth,
129
+ height: effectiveHeight
130
+ });
112
131
  const layout = props.layout ?? defaultProps.layout ?? defaultLayout;
113
132
  const isPolarChart = layout === "centric" || layout === "radial";
114
- if (compact) return createVNode(Fragment, null, [
115
- createVNode(ChartDataContextProvider, { "chartData": props.data }, null),
116
- createVNode(ReportMainChartProps, {
117
- "width": width,
118
- "height": height,
119
- "layout": layout,
120
- "margin": props.margin ?? defaultMargin
121
- }, null),
122
- isPolarChart && createVNode(ReportPolarOptions, {
123
- "cx": props.cx ?? "50%",
124
- "cy": props.cy ?? "50%",
125
- "startAngle": props.startAngle ?? defaultProps.startAngle ?? 90,
126
- "endAngle": props.endAngle ?? defaultProps.endAngle ?? -270,
127
- "innerRadius": props.innerRadius ?? 0,
128
- "outerRadius": props.outerRadius ?? "80%"
129
- }, null),
130
- createVNode(Surface_default, mergeProps(attrs, rest, {
131
- "width": width,
132
- "height": height,
133
- "title": title,
134
- "desc": desc
135
- }), { default: () => [createVNode(ClipPath_default, { "clipPathId": clipPathId }, null), slots.default?.()] })
136
- ]);
133
+ if (compact) {
134
+ if (!hasValidSize) return null;
135
+ return createVNode(Fragment, null, [
136
+ createVNode(ChartDataContextProvider, { "chartData": props.data }, null),
137
+ createVNode(ReportMainChartProps, {
138
+ "width": effectiveWidth,
139
+ "height": effectiveHeight,
140
+ "layout": layout,
141
+ "margin": props.margin ?? defaultMargin
142
+ }, null),
143
+ isPolarChart && createVNode(ReportPolarOptions, {
144
+ "cx": props.cx ?? "50%",
145
+ "cy": props.cy ?? "50%",
146
+ "startAngle": props.startAngle ?? defaultProps.startAngle ?? 90,
147
+ "endAngle": props.endAngle ?? defaultProps.endAngle ?? -270,
148
+ "innerRadius": props.innerRadius ?? 0,
149
+ "outerRadius": props.outerRadius ?? "80%"
150
+ }, null),
151
+ createVNode(Surface_default, mergeProps(attrs, rest, {
152
+ "width": effectiveWidth,
153
+ "height": effectiveHeight,
154
+ "title": title,
155
+ "desc": desc
156
+ }), { default: () => [createVNode(ClipPath_default, { "clipPathId": clipPathId }, null), slots.default?.()] })
157
+ ]);
158
+ }
159
+ if (!responsive && !hasValidSize) return null;
137
160
  if (props.accessibilityLayer) {
138
161
  attributes.tabindex = props.tabIndex ?? 0;
139
162
  attributes.role = props.role ?? "application";
@@ -143,14 +166,14 @@ function generateCategoricalChart({ chartName, defaultProps = {}, defaultTooltip
143
166
  for (const [key, value] of Object.entries(attributes)) if (key.startsWith("on") && typeof value === "function") eventHandlerAttrs[key] = value;
144
167
  else svgAttributes[key] = value;
145
168
  return createVNode(Fragment, null, [
146
- createVNode(ChartDataContextProvider, { "chartData": props.data }, null),
147
- createVNode(ReportMainChartProps, {
148
- "width": width,
149
- "height": height,
169
+ hasValidSize && createVNode(ChartDataContextProvider, { "chartData": props.data }, null),
170
+ hasValidSize && createVNode(ReportMainChartProps, {
171
+ "width": effectiveWidth,
172
+ "height": effectiveHeight,
150
173
  "layout": layout,
151
174
  "margin": props.margin ?? defaultMargin
152
175
  }, null),
153
- isPolarChart && createVNode(ReportPolarOptions, {
176
+ hasValidSize && isPolarChart && createVNode(ReportPolarOptions, {
154
177
  "cx": props.cx ?? "50%",
155
178
  "cy": props.cy ?? "50%",
156
179
  "startAngle": props.startAngle ?? defaultProps.startAngle ?? 90,
@@ -158,19 +181,21 @@ function generateCategoricalChart({ chartName, defaultProps = {}, defaultTooltip
158
181
  "innerRadius": props.innerRadius ?? 0,
159
182
  "outerRadius": props.outerRadius ?? "80%"
160
183
  }, null),
161
- createVNode(RechartsWrapper, mergeProps({
184
+ createVNode(ChartsWrapper, mergeProps({
185
+ "responsive": responsive,
186
+ "onResize": handleResize,
162
187
  "style": props.style,
163
188
  "class": props.class,
164
- "width": width,
165
- "height": height
166
- }, eventHandlerAttrs), { default: () => [createVNode(Surface_default, mergeProps(svgAttributes, {
167
- "width": width,
168
- "height": height,
189
+ "width": effectiveWidth,
190
+ "height": effectiveHeight
191
+ }, eventHandlerAttrs), { default: () => [hasValidSize && createVNode(Surface_default, mergeProps(svgAttributes, {
192
+ "width": effectiveWidth,
193
+ "height": effectiveHeight,
169
194
  "title": title,
170
195
  "desc": desc,
171
196
  "style": FULL_WIDTH_AND_HEIGHT
172
197
  }), { default: () => [createVNode(ClipPath_default, { "clipPathId": clipPathId }, null), slots.default?.()] }), slots.tooltip?.()] }),
173
- createVNode(ReportChartProps_default, props, null)
198
+ hasValidSize && createVNode(ReportChartProps_default, props, null)
174
199
  ]);
175
200
  };
176
201
  }
@@ -21,7 +21,11 @@ var Surface = /* @__PURE__ */ defineComponent({
21
21
  },
22
22
  class: classProp,
23
23
  style: {
24
- type: Object,
24
+ type: [
25
+ String,
26
+ Object,
27
+ Array
28
+ ],
25
29
  default: void 0
26
30
  },
27
31
  title: {
@@ -25,6 +25,17 @@ var cartesianAxisSlice = createSlice({
25
25
  removeYAxis(state, action) {
26
26
  delete state.yAxis[action.payload.id];
27
27
  },
28
+ updateYAxisWidth(state, action) {
29
+ const { id, width } = action.payload;
30
+ const axis = state.yAxis[id];
31
+ if (axis) {
32
+ const history = axis.widthHistory || [];
33
+ if (history.length === 3 && history[0] === history[2] && width === history[1] && width !== axis.width && Math.abs(width - (history[0] ?? 0)) <= 1) return;
34
+ const newHistory = [...history, width].slice(-3);
35
+ axis.width = width;
36
+ axis.widthHistory = newHistory;
37
+ }
38
+ },
28
39
  addZAxis(state, action) {
29
40
  state.zAxis[action.payload.id] = castDraft(action.payload);
30
41
  },
@@ -33,7 +44,7 @@ var cartesianAxisSlice = createSlice({
33
44
  }
34
45
  }
35
46
  });
36
- var { addXAxis, removeXAxis, addYAxis, removeYAxis, addZAxis, removeZAxis } = cartesianAxisSlice.actions;
47
+ var { addXAxis, removeXAxis, addYAxis, removeYAxis, addZAxis, removeZAxis, updateYAxisWidth } = cartesianAxisSlice.actions;
37
48
  var cartesianAxisReducer = cartesianAxisSlice.reducer;
38
49
  //#endregion
39
- export { addXAxis, addYAxis, addZAxis, cartesianAxisReducer, removeXAxis, removeYAxis, removeZAxis };
50
+ export { addXAxis, addYAxis, addZAxis, cartesianAxisReducer, removeXAxis, removeYAxis, removeZAxis, updateYAxisWidth };
@@ -639,7 +639,7 @@ function getXAxisSize(offset, axisSettings) {
639
639
  }
640
640
  function getYAxisSize(offset, axisSettings) {
641
641
  return {
642
- width: axisSettings.width,
642
+ width: typeof axisSettings.width === "number" ? axisSettings.width : 60,
643
643
  height: offset.height
644
644
  };
645
645
  }
@@ -712,7 +712,7 @@ function selectYAxisPosition(state, axisId) {
712
712
  }
713
713
  var selectYAxisSize = createSelector(selectChartOffset, selectYAxisSettings, (offset, axisSettings) => {
714
714
  return {
715
- width: axisSettings.width,
715
+ width: typeof axisSettings.width === "number" ? axisSettings.width : 60,
716
716
  height: offset.height
717
717
  };
718
718
  });
@@ -18,10 +18,13 @@ var selectChartOffset = createSelector([
18
18
  ], (chartWidth, chartHeight, margin, brushHeight, xAxes, yAxes, legendSettings, legendSize) => {
19
19
  const offsetH = yAxes.reduce((result, entry) => {
20
20
  const { orientation } = entry;
21
- if (!entry.mirror && !entry.hide) return {
22
- ...result,
23
- [orientation]: result[orientation] + entry.width
24
- };
21
+ if (!entry.mirror && !entry.hide) {
22
+ const width = typeof entry.width === "number" ? entry.width : 60;
23
+ return {
24
+ ...result,
25
+ [orientation]: result[orientation] + width
26
+ };
27
+ }
25
28
  return result;
26
29
  }, {
27
30
  left: margin.left || 0,
@@ -1,7 +1,7 @@
1
+ import { DATA_ITEM_DATAKEY_ATTRIBUTE_NAME, DATA_ITEM_INDEX_ATTRIBUTE_NAME } from "../utils/const.mjs";
1
2
  import { getChartPointer } from "../utils/chart.mjs";
2
3
  import { selectTooltipEventType } from "./selectors/selectTooltipEventType.mjs";
3
4
  import { setActiveMouseOverItemIndex, setMouseOverAxisIndex } from "./tooltipSlice.mjs";
4
- import { DATA_ITEM_DATAKEY_ATTRIBUTE_NAME, DATA_ITEM_INDEX_ATTRIBUTE_NAME } from "../utils/const.mjs";
5
5
  import { selectActivePropsFromChartPointer } from "./selectors/selectActivePropsFromChartPointer.mjs";
6
6
  import { selectTooltipCoordinate } from "./selectors/touchSelectors.mjs";
7
7
  import { createAction, createListenerMiddleware } from "@reduxjs/toolkit";
@@ -0,0 +1,29 @@
1
+ //#region src/utils/YAxisUtils.ts
2
+ /**
3
+ * Calculates the width of the Y-axis based on the tick labels and the axis label.
4
+ * @param params - The parameters object.
5
+ * @param [params.ticks] - An array-like object of tick elements, each with a `getBoundingClientRect` method.
6
+ * @param [params.label] - The axis label element, with a `getBoundingClientRect` method.
7
+ * @param [params.labelGapWithTick] - The gap between the label and the tick.
8
+ * @param [params.tickSize] - The length of the tick line.
9
+ * @param [params.tickMargin] - The margin between the tick line and the tick text.
10
+ * @returns The calculated width of the Y-axis.
11
+ */
12
+ function getCalculatedYAxisWidth({ ticks, label, labelGapWithTick = 5, tickSize = 0, tickMargin = 0 }) {
13
+ let maxTickWidth = 0;
14
+ if (ticks) {
15
+ Array.from(ticks).forEach((tickNode) => {
16
+ if (tickNode) {
17
+ const bbox = tickNode.getBoundingClientRect();
18
+ if (bbox.width > maxTickWidth) maxTickWidth = bbox.width;
19
+ }
20
+ });
21
+ const labelWidth = label ? label.getBoundingClientRect().width : 0;
22
+ const tickWidth = (tickSize ?? 0) + (tickMargin ?? 0);
23
+ const updatedYAxisWidth = maxTickWidth + tickWidth + labelWidth + (label ? labelGapWithTick : 0);
24
+ return Math.round(updatedYAxisWidth);
25
+ }
26
+ return 0;
27
+ }
28
+ //#endregion
29
+ export { getCalculatedYAxisWidth };
@@ -1,7 +1,7 @@
1
1
  import { AxisRange } from './selectors/axisSelectors';
2
2
  import { SVGAttributes } from 'vue';
3
3
  import { RechartsScale, ScaleType } from '../types/scale';
4
- import { AxisDomain, AxisDomainType, AxisInterval } from '../types/axis';
4
+ import { AxisDomain, AxisDomainType, AxisInterval, YAxisWidth } from '../types/axis';
5
5
  import { DataKey } from '../types';
6
6
  import { AxisTick, TickFormatter } from '../types/tick';
7
7
  export type AxisId = string | number;
@@ -68,8 +68,13 @@ export type XAxisSettings = CartesianAxisSettings & {
68
68
  };
69
69
  export type YAxisSettings = CartesianAxisSettings & {
70
70
  padding: YAxisPadding;
71
- width: number;
71
+ width: YAxisWidth;
72
72
  orientation: YAxisOrientation;
73
+ /**
74
+ * Internal: recent measured widths, used to detect A→B→A oscillation
75
+ * when width is measured dynamically (width === 'auto').
76
+ */
77
+ widthHistory?: number[];
73
78
  };
74
79
  /**
75
80
  * Z axis is special because it's never displayed. It controls the size of Scatter dots,
@@ -83,6 +88,9 @@ type AxisMapState = {
83
88
  yAxis: Record<AxisId, YAxisSettings>;
84
89
  zAxis: Record<AxisId, ZAxisSettings>;
85
90
  };
86
- export declare const addXAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<XAxisSettings, "cartesianAxis/addXAxis">, removeXAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<XAxisSettings, "cartesianAxis/removeXAxis">, addYAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<YAxisSettings, "cartesianAxis/addYAxis">, removeYAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<YAxisSettings, "cartesianAxis/removeYAxis">, addZAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<ZAxisSettings, "cartesianAxis/addZAxis">, removeZAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<ZAxisSettings, "cartesianAxis/removeZAxis">;
91
+ export declare const addXAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<XAxisSettings, "cartesianAxis/addXAxis">, removeXAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<XAxisSettings, "cartesianAxis/removeXAxis">, addYAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<YAxisSettings, "cartesianAxis/addYAxis">, removeYAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<YAxisSettings, "cartesianAxis/removeYAxis">, addZAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<ZAxisSettings, "cartesianAxis/addZAxis">, removeZAxis: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<ZAxisSettings, "cartesianAxis/removeZAxis">, updateYAxisWidth: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
92
+ id: AxisId;
93
+ width: number;
94
+ }, "cartesianAxis/updateYAxisWidth">;
87
95
  export declare const cartesianAxisReducer: import('@reduxjs/toolkit').Reducer<AxisMapState>;
88
96
  export {};
@@ -63,10 +63,20 @@ export type YAxisPadding = {
63
63
  bottom?: number;
64
64
  } | 'gap' | 'no-gap';
65
65
  export type YAxisOrientation = 'left' | 'right';
66
+ /**
67
+ * Width of the Y axis in pixels.
68
+ * `auto` will attempt to resize the axis based on its content.
69
+ */
70
+ export type YAxisWidth = number | 'auto';
66
71
  export type YAxisSettings = CartesianAxisSettings & {
67
72
  padding: YAxisPadding;
68
- width: number;
73
+ width: YAxisWidth;
69
74
  orientation: YAxisOrientation;
75
+ /**
76
+ * Internal: recent measured widths, used to detect A→B→A oscillation
77
+ * when width is measured dynamically (width === 'auto').
78
+ */
79
+ widthHistory?: number[];
70
80
  };
71
81
  export type AxisRange = readonly [number, number];
72
82
  /**
@@ -0,0 +1,20 @@
1
+ type IGetBoundingClient = Pick<Element, 'getBoundingClientRect'>;
2
+ /**
3
+ * Calculates the width of the Y-axis based on the tick labels and the axis label.
4
+ * @param params - The parameters object.
5
+ * @param [params.ticks] - An array-like object of tick elements, each with a `getBoundingClientRect` method.
6
+ * @param [params.label] - The axis label element, with a `getBoundingClientRect` method.
7
+ * @param [params.labelGapWithTick] - The gap between the label and the tick.
8
+ * @param [params.tickSize] - The length of the tick line.
9
+ * @param [params.tickMargin] - The margin between the tick line and the tick text.
10
+ * @returns The calculated width of the Y-axis.
11
+ */
12
+ export declare function getCalculatedYAxisWidth({ ticks, label, labelGapWithTick, // Default gap between label and tick
13
+ tickSize, tickMargin, }: {
14
+ ticks: ArrayLike<IGetBoundingClient> | null;
15
+ label: IGetBoundingClient | null | undefined;
16
+ labelGapWithTick: number | undefined;
17
+ tickSize: number | undefined;
18
+ tickMargin: number | undefined;
19
+ }): number;
20
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vccs",
3
3
  "type": "module",
4
- "version": "0.4.1",
4
+ "version": "0.5.0",
5
5
  "description": "Composable charting components for Vue 3 — an unofficial port of Recharts",
6
6
  "author": "rick-hup",
7
7
  "license": "MIT",