@bikdotai/bik-component-library 0.0.859 → 0.0.860-beta.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.
- package/README.md +9 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/AnalyticsTrend.js +1 -1
- package/dist/cjs/components/analytics-chips-and-dropdowns/AnalyticsTrend.js.map +1 -1
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/ChartLayout.js +2 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/ChartLayout.js.map +1 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.js +2 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.js.map +1 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.styled.js +50 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.styled.js.map +1 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.js +2 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.js.map +1 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.styled.js +43 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.styled.js.map +1 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/FunnelChart/funnelGeometry.js +2 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/FunnelChart/funnelGeometry.js.map +1 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/HorizontalBarGraph/HorizontalGraph.js +1 -1
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/HorizontalBarGraph/HorizontalGraph.js.map +1 -1
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/StackedBarChart/StackedBarChart.js +1 -1
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/StackedBarChart/StackedBarChart.js.map +1 -1
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/StackedBarChart/StackedBarChart.model.js.map +1 -1
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/chartPalette.js +2 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/chartPalette.js.map +1 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/formatChartValue.js +2 -0
- package/dist/cjs/components/analytics-chips-and-dropdowns/chart/formatChartValue.js.map +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/analytics-chips-and-dropdowns/AnalyticsTrend.d.ts +3 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/AnalyticsTrend.js +182 -172
- package/dist/esm/components/analytics-chips-and-dropdowns/AnalyticsTrend.js.map +1 -1
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/ChartLayout.d.ts +16 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/ChartLayout.js +69 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/ChartLayout.js.map +1 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.d.ts +3 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.js +110 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.js.map +1 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.model.d.ts +21 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.styled.d.ts +16 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.styled.js +61 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.styled.js.map +1 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.d.ts +3 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.js +109 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.js.map +1 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.model.d.ts +19 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.styled.d.ts +16 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.styled.js +54 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.styled.js.map +1 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/funnelGeometry.d.ts +23 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/funnelGeometry.js +48 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/funnelGeometry.js.map +1 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/HorizontalBarGraph/HorizontalGraph.js +16 -15
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/HorizontalBarGraph/HorizontalGraph.js.map +1 -1
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/StackedBarChart/StackedBarChart.js +1 -1
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/StackedBarChart/StackedBarChart.js.map +1 -1
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/StackedBarChart/StackedBarChart.model.d.ts +1 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/StackedBarChart/StackedBarChart.model.js.map +1 -1
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/chartPalette.d.ts +3 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/chartPalette.js +18 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/chartPalette.js.map +1 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/formatChartValue.d.ts +4 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/formatChartValue.js +13 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/chart/formatChartValue.js.map +1 -0
- package/dist/esm/components/analytics-chips-and-dropdowns/index.d.ts +4 -0
- package/dist/esm/icons/index.d.ts +25 -25
- package/dist/esm/index.js +383 -379
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsxs as a, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import { TitleRegular as s, TitleMedium as c, BodyCaption as p } from "../../TypographyStyle.js";
|
|
3
|
+
import { COLORS as r } from "../../../constants/Theme.js";
|
|
4
|
+
const x = ({
|
|
5
|
+
title: e,
|
|
6
|
+
padding: o,
|
|
7
|
+
gap: d,
|
|
8
|
+
dataTest: t,
|
|
9
|
+
wrapperStyle: l,
|
|
10
|
+
children: n
|
|
11
|
+
}) => /* @__PURE__ */ a(
|
|
12
|
+
"div",
|
|
13
|
+
{
|
|
14
|
+
"data-test": t,
|
|
15
|
+
style: {
|
|
16
|
+
display: "flex",
|
|
17
|
+
flexDirection: "column",
|
|
18
|
+
gap: d,
|
|
19
|
+
width: "100%",
|
|
20
|
+
padding: o,
|
|
21
|
+
borderRadius: 8,
|
|
22
|
+
border: `1px solid ${r.stroke.primary}`,
|
|
23
|
+
backgroundColor: r.surface.standard,
|
|
24
|
+
...l
|
|
25
|
+
},
|
|
26
|
+
children: [
|
|
27
|
+
e && /* @__PURE__ */ i(s, { color: r.content.primary, children: e }),
|
|
28
|
+
n
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
), f = ({
|
|
32
|
+
value: e,
|
|
33
|
+
chip: o
|
|
34
|
+
}) => /* @__PURE__ */ a(
|
|
35
|
+
"div",
|
|
36
|
+
{
|
|
37
|
+
style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" },
|
|
38
|
+
children: [
|
|
39
|
+
/* @__PURE__ */ i(
|
|
40
|
+
c,
|
|
41
|
+
{
|
|
42
|
+
color: r.content.primary,
|
|
43
|
+
style: { whiteSpace: "nowrap" },
|
|
44
|
+
children: e
|
|
45
|
+
}
|
|
46
|
+
),
|
|
47
|
+
o && /* @__PURE__ */ i(
|
|
48
|
+
"div",
|
|
49
|
+
{
|
|
50
|
+
style: {
|
|
51
|
+
display: "inline-flex",
|
|
52
|
+
alignItems: "center",
|
|
53
|
+
padding: "4px 8px",
|
|
54
|
+
borderRadius: 4,
|
|
55
|
+
border: `1px solid ${r.stroke.primary}`,
|
|
56
|
+
backgroundColor: r.surface.subdued,
|
|
57
|
+
whiteSpace: "nowrap"
|
|
58
|
+
},
|
|
59
|
+
children: /* @__PURE__ */ i(p, { color: r.content.secondary, children: o })
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
export {
|
|
66
|
+
x as ChartCard,
|
|
67
|
+
f as ChartValueRow
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=ChartLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChartLayout.js","sources":["../../../../../src/components/analytics-chips-and-dropdowns/chart/ChartLayout.tsx"],"sourcesContent":["import React, { CSSProperties, ReactNode } from 'react';\nimport {\n\tBodyCaption,\n\tTitleMedium,\n\tTitleRegular,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\n\ninterface ChartCardProps {\n\ttitle?: string;\n\tpadding: CSSProperties['padding'];\n\tgap: number;\n\tdataTest: string;\n\twrapperStyle?: CSSProperties;\n\tchildren: ReactNode;\n}\n\nexport const ChartCard: React.FC<ChartCardProps> = ({\n\ttitle,\n\tpadding,\n\tgap,\n\tdataTest,\n\twrapperStyle,\n\tchildren,\n}) => (\n\t<div\n\t\tdata-test={dataTest}\n\t\tstyle={{\n\t\t\tdisplay: 'flex',\n\t\t\tflexDirection: 'column',\n\t\t\tgap,\n\t\t\twidth: '100%',\n\t\t\tpadding,\n\t\t\tborderRadius: 8,\n\t\t\tborder: `1px solid ${COLORS.stroke.primary}`,\n\t\t\tbackgroundColor: COLORS.surface.standard,\n\t\t\t...wrapperStyle,\n\t\t}}\n\t>\n\t\t{title && (\n\t\t\t<TitleRegular color={COLORS.content.primary}>{title}</TitleRegular>\n\t\t)}\n\t\t{children}\n\t</div>\n);\n\ninterface ChartValueRowProps {\n\tvalue: ReactNode;\n\tchip?: ReactNode;\n}\n\nexport const ChartValueRow: React.FC<ChartValueRowProps> = ({\n\tvalue,\n\tchip,\n}) => (\n\t<div\n\t\tstyle={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}\n\t>\n\t\t<TitleMedium\n\t\t\tcolor={COLORS.content.primary}\n\t\t\tstyle={{ whiteSpace: 'nowrap' }}\n\t\t>\n\t\t\t{value}\n\t\t</TitleMedium>\n\t\t{chip && (\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: 'inline-flex',\n\t\t\t\t\talignItems: 'center',\n\t\t\t\t\tpadding: '4px 8px',\n\t\t\t\t\tborderRadius: 4,\n\t\t\t\t\tborder: `1px solid ${COLORS.stroke.primary}`,\n\t\t\t\t\tbackgroundColor: COLORS.surface.subdued,\n\t\t\t\t\twhiteSpace: 'nowrap',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<BodyCaption color={COLORS.content.secondary}>{chip}</BodyCaption>\n\t\t\t</div>\n\t\t)}\n\t</div>\n);\n"],"names":["ChartCard","title","padding","gap","dataTest","wrapperStyle","children","jsxs","COLORS","TitleRegular","ChartValueRow","value","chip","jsx","TitleMedium","BodyCaption"],"mappings":";;;AAiBO,MAAMA,IAAsC,CAAC;AAAA,EACnD,OAAAC;AAAA,EACA,SAAAC;AAAA,EACA,KAAAC;AAAA,EACA,UAAAC;AAAA,EACA,cAAAC;AAAA,EACA,UAAAC;AACD,MACC,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACA,aAAWH;AAAA,IACX,OAAO;AAAA,MACN,SAAS;AAAA,MACT,eAAe;AAAA,MACf,KAAAD;AAAA,MACA,OAAO;AAAA,MACP,SAAAD;AAAA,MACA,cAAc;AAAA,MACd,QAAQ,aAAaM,EAAO,OAAO,OAAO;AAAA,MAC1C,iBAAiBA,EAAO,QAAQ;AAAA,MAChC,GAAGH;AAAA,IAAA;AAAA,IAGH,UAAA;AAAA,MAAAJ,uBACCQ,GAAA,EAAa,OAAOD,EAAO,QAAQ,SAAU,UAAAP,GAAM;AAAA,MAEpDK;AAAA,IAAA;AAAA,EAAA;AACF,GAQYI,IAA8C,CAAC;AAAA,EAC3D,OAAAC;AAAA,EACA,MAAAC;AACD,MACC,gBAAAL;AAAA,EAAC;AAAA,EAAA;AAAA,IACA,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,GAAG,UAAU,OAAA;AAAA,IAElE,UAAA;AAAA,MAAA,gBAAAM;AAAA,QAACC;AAAA,QAAA;AAAA,UACA,OAAON,EAAO,QAAQ;AAAA,UACtB,OAAO,EAAE,YAAY,SAAA;AAAA,UAEpB,UAAAG;AAAA,QAAA;AAAA,MAAA;AAAA,MAEDC,KACA,gBAAAC;AAAA,QAAC;AAAA,QAAA;AAAA,UACA,OAAO;AAAA,YACN,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,SAAS;AAAA,YACT,cAAc;AAAA,YACd,QAAQ,aAAaL,EAAO,OAAO,OAAO;AAAA,YAC1C,iBAAiBA,EAAO,QAAQ;AAAA,YAChC,YAAY;AAAA,UAAA;AAAA,UAGb,4BAACO,GAAA,EAAY,OAAOP,EAAO,QAAQ,WAAY,UAAAI,EAAA,CAAK;AAAA,QAAA;AAAA,MAAA;AAAA,IACrD;AAAA,EAAA;AAEF;"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { jsx as e, jsxs as s } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo as R, useState as g } from "react";
|
|
3
|
+
import { BodyCaption as y } from "../../../TypographyStyle.js";
|
|
4
|
+
import { COLORS as $ } from "../../../../constants/Theme.js";
|
|
5
|
+
import { ChartCard as w, ChartValueRow as A } from "../ChartLayout.js";
|
|
6
|
+
import { pickColor as O, COMPARISON_BAR_COLORS as M } from "../chartPalette.js";
|
|
7
|
+
import { toChartValue as i, formatPercent as S, clamp as k, formatChartValue as T } from "../formatChartValue.js";
|
|
8
|
+
import { BarRowLayout as x, BarLabelColumn as _, BarArea as E, BarTrack as H, BarFill as I, BarTooltip as P, BarTooltipArrow as V } from "./ComparisonBarChart.styled.js";
|
|
9
|
+
const b = Array.from(
|
|
10
|
+
{ length: 2 },
|
|
11
|
+
(r, n) => ({ key: `placeholder-${n}`, label: "", value: 0 })
|
|
12
|
+
), j = ({
|
|
13
|
+
row: { bar: r, fillWidth: n, color: c, percentageLabel: l },
|
|
14
|
+
labelWidth: m,
|
|
15
|
+
barHeight: p,
|
|
16
|
+
showTooltip: h,
|
|
17
|
+
locale: d
|
|
18
|
+
}) => {
|
|
19
|
+
const [u, o] = g(!1);
|
|
20
|
+
return /* @__PURE__ */ s(x, { children: [
|
|
21
|
+
/* @__PURE__ */ s(_, { $width: m, children: [
|
|
22
|
+
/* @__PURE__ */ e(y, { color: $.content.secondary, children: r.label }),
|
|
23
|
+
/* @__PURE__ */ e(
|
|
24
|
+
A,
|
|
25
|
+
{
|
|
26
|
+
value: r.valueLabel ?? T(i(r.value), d),
|
|
27
|
+
chip: l
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
] }),
|
|
31
|
+
/* @__PURE__ */ s(
|
|
32
|
+
E,
|
|
33
|
+
{
|
|
34
|
+
"data-test": `comparison-bar-chart-bar-${r.key}`,
|
|
35
|
+
onMouseEnter: () => o(!0),
|
|
36
|
+
onMouseLeave: () => o(!1),
|
|
37
|
+
$height: p,
|
|
38
|
+
children: [
|
|
39
|
+
/* @__PURE__ */ e(H, { "data-test": `comparison-bar-chart-track-${r.key}`, children: /* @__PURE__ */ e(
|
|
40
|
+
I,
|
|
41
|
+
{
|
|
42
|
+
"data-test": `comparison-bar-chart-fill-${r.key}`,
|
|
43
|
+
$width: n,
|
|
44
|
+
$color: c
|
|
45
|
+
}
|
|
46
|
+
) }),
|
|
47
|
+
h && u && /* @__PURE__ */ s(
|
|
48
|
+
P,
|
|
49
|
+
{
|
|
50
|
+
"data-test": `comparison-bar-chart-tooltip-${r.key}`,
|
|
51
|
+
$left: k(n / 2, 8, 92),
|
|
52
|
+
children: [
|
|
53
|
+
/* @__PURE__ */ e(V, {}),
|
|
54
|
+
/* @__PURE__ */ e(y, { color: $.content.primaryInverse, children: l })
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
] });
|
|
62
|
+
}, Q = ({
|
|
63
|
+
bars: r = [],
|
|
64
|
+
title: n,
|
|
65
|
+
total: c,
|
|
66
|
+
colors: l = M,
|
|
67
|
+
labelWidth: m = 180,
|
|
68
|
+
barHeight: p = 52,
|
|
69
|
+
locale: h,
|
|
70
|
+
showTooltip: d = !0,
|
|
71
|
+
wrapperStyle: u
|
|
72
|
+
}) => {
|
|
73
|
+
const o = r.some((t) => i(t.value) > 0), f = r.length ? r : b, L = R(() => {
|
|
74
|
+
const t = c !== void 0 ? i(c) : f.reduce((a, v) => a + i(v.value), 0);
|
|
75
|
+
return f.map((a, v) => {
|
|
76
|
+
const C = a.percentage ?? (t > 0 ? i(a.value) / t * 100 : 0), B = Number.isFinite(C) ? Math.max(C, 0) : 0;
|
|
77
|
+
return {
|
|
78
|
+
bar: a,
|
|
79
|
+
fillWidth: k(B, 0, 100),
|
|
80
|
+
color: o ? a.color ?? O(l, v) : void 0,
|
|
81
|
+
percentageLabel: o ? a.percentageLabel ?? `${S(B)}%` : ""
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
}, [f, c, l, o]);
|
|
85
|
+
return /* @__PURE__ */ e(
|
|
86
|
+
w,
|
|
87
|
+
{
|
|
88
|
+
dataTest: "comparison-bar-chart",
|
|
89
|
+
title: n,
|
|
90
|
+
padding: 24,
|
|
91
|
+
gap: 24,
|
|
92
|
+
wrapperStyle: u,
|
|
93
|
+
children: L.map((t) => /* @__PURE__ */ e(
|
|
94
|
+
j,
|
|
95
|
+
{
|
|
96
|
+
row: t,
|
|
97
|
+
labelWidth: m,
|
|
98
|
+
barHeight: p,
|
|
99
|
+
showTooltip: d && o,
|
|
100
|
+
locale: h
|
|
101
|
+
},
|
|
102
|
+
t.bar.key
|
|
103
|
+
))
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
};
|
|
107
|
+
export {
|
|
108
|
+
Q as ComparisonBarChart
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=ComparisonBarChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComparisonBarChart.js","sources":["../../../../../../src/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\nimport { BodyCaption } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport { ChartCard, ChartValueRow } from '../ChartLayout';\nimport { COMPARISON_BAR_COLORS, pickColor } from '../chartPalette';\nimport {\n\tclamp,\n\tformatChartValue,\n\tformatPercent,\n\ttoChartValue,\n} from '../formatChartValue';\nimport type {\n\tComparisonBarChartI,\n\tComparisonBarI,\n} from './ComparisonBarChart.model';\nimport {\n\tBarArea,\n\tBarFill,\n\tBarLabelColumn,\n\tBarRowLayout,\n\tBarTooltip,\n\tBarTooltipArrow,\n\tBarTrack,\n} from './ComparisonBarChart.styled';\n\nconst PLACEHOLDER_BARS: ComparisonBarI[] = Array.from(\n\t{ length: 2 },\n\t(_, index) => ({ key: `placeholder-${index}`, label: '', value: 0 }),\n);\n\ninterface PreparedBar {\n\tbar: ComparisonBarI;\n\tfillWidth: number;\n\tcolor?: string;\n\tpercentageLabel: string;\n}\n\ninterface BarRowProps {\n\trow: PreparedBar;\n\tlabelWidth: number;\n\tbarHeight: number;\n\tshowTooltip: boolean;\n\tlocale?: string;\n}\n\nconst BarRow: React.FC<BarRowProps> = ({\n\trow: { bar, fillWidth, color, percentageLabel },\n\tlabelWidth,\n\tbarHeight,\n\tshowTooltip,\n\tlocale,\n}) => {\n\tconst [isHovered, setIsHovered] = useState(false);\n\n\treturn (\n\t\t<BarRowLayout>\n\t\t\t<BarLabelColumn $width={labelWidth}>\n\t\t\t\t<BodyCaption color={COLORS.content.secondary}>{bar.label}</BodyCaption>\n\t\t\t\t<ChartValueRow\n\t\t\t\t\tvalue={\n\t\t\t\t\t\tbar.valueLabel ?? formatChartValue(toChartValue(bar.value), locale)\n\t\t\t\t\t}\n\t\t\t\t\tchip={percentageLabel}\n\t\t\t\t/>\n\t\t\t</BarLabelColumn>\n\n\t\t\t<BarArea\n\t\t\t\tdata-test={`comparison-bar-chart-bar-${bar.key}`}\n\t\t\t\tonMouseEnter={() => setIsHovered(true)}\n\t\t\t\tonMouseLeave={() => setIsHovered(false)}\n\t\t\t\t$height={barHeight}\n\t\t\t>\n\t\t\t\t<BarTrack data-test={`comparison-bar-chart-track-${bar.key}`}>\n\t\t\t\t\t<BarFill\n\t\t\t\t\t\tdata-test={`comparison-bar-chart-fill-${bar.key}`}\n\t\t\t\t\t\t$width={fillWidth}\n\t\t\t\t\t\t$color={color}\n\t\t\t\t\t/>\n\t\t\t\t</BarTrack>\n\t\t\t\t{showTooltip && isHovered && (\n\t\t\t\t\t<BarTooltip\n\t\t\t\t\t\tdata-test={`comparison-bar-chart-tooltip-${bar.key}`}\n\t\t\t\t\t\t$left={clamp(fillWidth / 2, 8, 92)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<BarTooltipArrow />\n\t\t\t\t\t\t<BodyCaption color={COLORS.content.primaryInverse}>\n\t\t\t\t\t\t\t{percentageLabel}\n\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t</BarTooltip>\n\t\t\t\t)}\n\t\t\t</BarArea>\n\t\t</BarRowLayout>\n\t);\n};\n\nexport const ComparisonBarChart: React.FC<ComparisonBarChartI> = ({\n\tbars = [],\n\ttitle,\n\ttotal,\n\tcolors = COMPARISON_BAR_COLORS,\n\tlabelWidth = 180,\n\tbarHeight = 52,\n\tlocale,\n\tshowTooltip = true,\n\twrapperStyle,\n}) => {\n\tconst hasData = bars.some((bar) => toChartValue(bar.value) > 0);\n\tconst visibleBars = bars.length ? bars : PLACEHOLDER_BARS;\n\n\tconst rows = useMemo<PreparedBar[]>(() => {\n\t\tconst denominator =\n\t\t\ttotal !== undefined\n\t\t\t\t? toChartValue(total)\n\t\t\t\t: visibleBars.reduce((sum, bar) => sum + toChartValue(bar.value), 0);\n\n\t\treturn visibleBars.map((bar, index) => {\n\t\t\tconst percentage =\n\t\t\t\tbar.percentage ??\n\t\t\t\t(denominator > 0 ? (toChartValue(bar.value) / denominator) * 100 : 0);\n\t\t\tconst share = Number.isFinite(percentage) ? Math.max(percentage, 0) : 0;\n\t\t\treturn {\n\t\t\t\tbar,\n\t\t\t\tfillWidth: clamp(share, 0, 100),\n\t\t\t\tcolor: hasData ? bar.color ?? pickColor(colors, index) : undefined,\n\t\t\t\tpercentageLabel: hasData\n\t\t\t\t\t? bar.percentageLabel ?? `${formatPercent(share)}%`\n\t\t\t\t\t: '',\n\t\t\t};\n\t\t});\n\t}, [visibleBars, total, colors, hasData]);\n\n\treturn (\n\t\t<ChartCard\n\t\t\tdataTest=\"comparison-bar-chart\"\n\t\t\ttitle={title}\n\t\t\tpadding={24}\n\t\t\tgap={24}\n\t\t\twrapperStyle={wrapperStyle}\n\t\t>\n\t\t\t{rows.map((row) => (\n\t\t\t\t<BarRow\n\t\t\t\t\tkey={row.bar.key}\n\t\t\t\t\trow={row}\n\t\t\t\t\tlabelWidth={labelWidth}\n\t\t\t\t\tbarHeight={barHeight}\n\t\t\t\t\tshowTooltip={showTooltip && hasData}\n\t\t\t\t\tlocale={locale}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</ChartCard>\n\t);\n};\n"],"names":["PLACEHOLDER_BARS","_","index","BarRow","bar","fillWidth","color","percentageLabel","labelWidth","barHeight","showTooltip","locale","isHovered","setIsHovered","useState","BarRowLayout","jsxs","BarLabelColumn","jsx","BodyCaption","COLORS","ChartValueRow","formatChartValue","toChartValue","BarArea","BarTrack","BarFill","BarTooltip","clamp","BarTooltipArrow","ComparisonBarChart","bars","title","total","colors","COMPARISON_BAR_COLORS","wrapperStyle","hasData","visibleBars","rows","useMemo","denominator","sum","percentage","share","pickColor","formatPercent","ChartCard","row"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
export interface ComparisonBarI {
|
|
3
|
+
key: string;
|
|
4
|
+
label: string;
|
|
5
|
+
value: number;
|
|
6
|
+
valueLabel?: string;
|
|
7
|
+
percentage?: number;
|
|
8
|
+
percentageLabel?: string;
|
|
9
|
+
color?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ComparisonBarChartI {
|
|
12
|
+
bars: ComparisonBarI[];
|
|
13
|
+
title?: string;
|
|
14
|
+
total?: number;
|
|
15
|
+
colors?: string[];
|
|
16
|
+
labelWidth?: number;
|
|
17
|
+
barHeight?: number;
|
|
18
|
+
locale?: string;
|
|
19
|
+
showTooltip?: boolean;
|
|
20
|
+
wrapperStyle?: CSSProperties;
|
|
21
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const BarRowLayout: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
2
|
+
export declare const BarLabelColumn: import('styled-components').StyledComponent<"div", any, {
|
|
3
|
+
$width: number;
|
|
4
|
+
}, never>;
|
|
5
|
+
export declare const BarArea: import('styled-components').StyledComponent<"div", any, {
|
|
6
|
+
$height: number;
|
|
7
|
+
}, never>;
|
|
8
|
+
export declare const BarTrack: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
9
|
+
export declare const BarFill: import('styled-components').StyledComponent<"div", any, {
|
|
10
|
+
$width: number;
|
|
11
|
+
$color?: string | undefined;
|
|
12
|
+
}, never>;
|
|
13
|
+
export declare const BarTooltip: import('styled-components').StyledComponent<"div", any, {
|
|
14
|
+
$left: number;
|
|
15
|
+
}, never>;
|
|
16
|
+
export declare const BarTooltipArrow: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import t from "styled-components";
|
|
2
|
+
import { COLORS as r } from "../../../../constants/Theme.js";
|
|
3
|
+
const a = t.div`
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
gap: 32px;
|
|
7
|
+
`, n = t.div`
|
|
8
|
+
width: ${(o) => o.$width}px;
|
|
9
|
+
flex-shrink: 0;
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
gap: 8px;
|
|
13
|
+
`, p = t.div`
|
|
14
|
+
position: relative;
|
|
15
|
+
flex: 1;
|
|
16
|
+
height: ${(o) => o.$height}px;
|
|
17
|
+
`, s = t.div`
|
|
18
|
+
position: absolute;
|
|
19
|
+
inset: 0;
|
|
20
|
+
border-radius: 4px;
|
|
21
|
+
border: 1px solid ${r.stroke.primary};
|
|
22
|
+
background-color: ${r.surface.standard};
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
`, d = t.div`
|
|
25
|
+
position: absolute;
|
|
26
|
+
top: 0;
|
|
27
|
+
left: 0;
|
|
28
|
+
bottom: 0;
|
|
29
|
+
width: ${(o) => o.$width}%;
|
|
30
|
+
background-color: ${(o) => o.$color ?? "transparent"};
|
|
31
|
+
`, l = t.div`
|
|
32
|
+
position: absolute;
|
|
33
|
+
top: 50%;
|
|
34
|
+
left: ${(o) => o.$left}%;
|
|
35
|
+
transform: translate(-50%, -50%);
|
|
36
|
+
padding: 4px 8px;
|
|
37
|
+
border-radius: 4px;
|
|
38
|
+
background-color: ${r.content.primary};
|
|
39
|
+
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.12);
|
|
40
|
+
pointer-events: none;
|
|
41
|
+
`, x = t.div`
|
|
42
|
+
position: absolute;
|
|
43
|
+
top: -5px;
|
|
44
|
+
left: 50%;
|
|
45
|
+
transform: translateX(-50%);
|
|
46
|
+
width: 0;
|
|
47
|
+
height: 0;
|
|
48
|
+
border-left: 5px solid transparent;
|
|
49
|
+
border-right: 5px solid transparent;
|
|
50
|
+
border-bottom: 5px solid ${r.content.primary};
|
|
51
|
+
`;
|
|
52
|
+
export {
|
|
53
|
+
p as BarArea,
|
|
54
|
+
d as BarFill,
|
|
55
|
+
n as BarLabelColumn,
|
|
56
|
+
a as BarRowLayout,
|
|
57
|
+
l as BarTooltip,
|
|
58
|
+
x as BarTooltipArrow,
|
|
59
|
+
s as BarTrack
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=ComparisonBarChart.styled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComparisonBarChart.styled.js","sources":["../../../../../../src/components/analytics-chips-and-dropdowns/chart/ComparisonBarChart/ComparisonBarChart.styled.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '@src/constants/Theme';\n\nexport const BarRowLayout = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 32px;\n`;\n\nexport const BarLabelColumn = styled.div<{ $width: number }>`\n\twidth: ${(props) => props.$width}px;\n\tflex-shrink: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n`;\n\nexport const BarArea = styled.div<{ $height: number }>`\n\tposition: relative;\n\tflex: 1;\n\theight: ${(props) => props.$height}px;\n`;\n\nexport const BarTrack = styled.div`\n\tposition: absolute;\n\tinset: 0;\n\tborder-radius: 4px;\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tbackground-color: ${COLORS.surface.standard};\n\toverflow: hidden;\n`;\n\nexport const BarFill = styled.div<{ $width: number; $color?: string }>`\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: ${(props) => props.$width}%;\n\tbackground-color: ${(props) => props.$color ?? 'transparent'};\n`;\n\nexport const BarTooltip = styled.div<{ $left: number }>`\n\tposition: absolute;\n\ttop: 50%;\n\tleft: ${(props) => props.$left}%;\n\ttransform: translate(-50%, -50%);\n\tpadding: 4px 8px;\n\tborder-radius: 4px;\n\tbackground-color: ${COLORS.content.primary};\n\tbox-shadow: 0px 2px 4px rgba(0, 0, 0, 0.12);\n\tpointer-events: none;\n`;\n\nexport const BarTooltipArrow = styled.div`\n\tposition: absolute;\n\ttop: -5px;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\twidth: 0;\n\theight: 0;\n\tborder-left: 5px solid transparent;\n\tborder-right: 5px solid transparent;\n\tborder-bottom: 5px solid ${COLORS.content.primary};\n`;\n"],"names":["BarRowLayout","styled","BarLabelColumn","props","BarArea","BarTrack","COLORS","BarFill","BarTooltip","BarTooltipArrow"],"mappings":";;AAGO,MAAMA,IAAeC,EAAO;AAAA;AAAA;AAAA;AAAA,GAMtBC,IAAiBD,EAAO;AAAA,UAC3B,CAACE,MAAUA,EAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,GAOpBC,IAAUH,EAAO;AAAA;AAAA;AAAA,WAGnB,CAACE,MAAUA,EAAM,OAAO;AAAA,GAGtBE,IAAWJ,EAAO;AAAA;AAAA;AAAA;AAAA,qBAIVK,EAAO,OAAO,OAAO;AAAA,qBACrBA,EAAO,QAAQ,QAAQ;AAAA;AAAA,GAI/BC,IAAUN,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA,UAKpB,CAACE,MAAUA,EAAM,MAAM;AAAA,qBACZ,CAACA,MAAUA,EAAM,UAAU,aAAa;AAAA,GAGhDK,IAAaP,EAAO;AAAA;AAAA;AAAA,SAGxB,CAACE,MAAUA,EAAM,KAAK;AAAA;AAAA;AAAA;AAAA,qBAIVG,EAAO,QAAQ,OAAO;AAAA;AAAA;AAAA,GAK9BG,IAAkBR,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BASVK,EAAO,QAAQ,OAAO;AAAA;"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { jsx as o, jsxs as y } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo as s } from "react";
|
|
3
|
+
import { BodyTiny as C } from "../../../TypographyStyle.js";
|
|
4
|
+
import { COLORS as S } from "../../../../constants/Theme.js";
|
|
5
|
+
import { ChartCard as k, ChartValueRow as w } from "../ChartLayout.js";
|
|
6
|
+
import { pickColor as g, FUNNEL_BAND_COLORS as E } from "../chartPalette.js";
|
|
7
|
+
import { toChartValue as m, formatPercent as O, formatChartValue as R } from "../formatChartValue.js";
|
|
8
|
+
import { PlotArea as A, BandsSvg as _, SeparatorLine as v, HeaderRow as B, StageHeaderColumn as D, StageLabelRow as N, StageColorDot as P } from "./FunnelChart.styled.js";
|
|
9
|
+
import { buildFunnelLayout as V, FUNNEL_VIEW_WIDTH as L } from "./funnelGeometry.js";
|
|
10
|
+
const F = Array.from(
|
|
11
|
+
{ length: 4 },
|
|
12
|
+
(r, n) => ({ key: `placeholder-${n}`, label: "", value: 0 })
|
|
13
|
+
), T = (r, n) => {
|
|
14
|
+
const a = r[n];
|
|
15
|
+
if (a.percentageLabel !== void 0)
|
|
16
|
+
return a.percentageLabel;
|
|
17
|
+
if (n === 0)
|
|
18
|
+
return m(a.value) > 0 ? "100%" : "";
|
|
19
|
+
const t = a.branchOf ? r.find((u) => u.key === a.branchOf) : r[n - 1], l = m(t?.value);
|
|
20
|
+
if (!t || l === 0)
|
|
21
|
+
return "";
|
|
22
|
+
const h = m(a.value) / l * 100;
|
|
23
|
+
return `${O(h)}% of ${t.label}`;
|
|
24
|
+
}, j = ({
|
|
25
|
+
stage: r,
|
|
26
|
+
color: n,
|
|
27
|
+
chip: a,
|
|
28
|
+
locale: t
|
|
29
|
+
}) => /* @__PURE__ */ y(D, { "data-test": `funnel-chart-header-${r.key}`, children: [
|
|
30
|
+
r.label && /* @__PURE__ */ y(N, { children: [
|
|
31
|
+
/* @__PURE__ */ o(P, { $color: n }),
|
|
32
|
+
/* @__PURE__ */ o(C, { color: S.content.secondary, children: r.label })
|
|
33
|
+
] }),
|
|
34
|
+
/* @__PURE__ */ o(
|
|
35
|
+
w,
|
|
36
|
+
{
|
|
37
|
+
value: r.valueLabel ?? R(m(r.value), t),
|
|
38
|
+
chip: a
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
] }), K = ({
|
|
42
|
+
stages: r = [],
|
|
43
|
+
title: n,
|
|
44
|
+
plotHeight: a = 291,
|
|
45
|
+
headerHeight: t = 83,
|
|
46
|
+
colors: l = E,
|
|
47
|
+
locale: h,
|
|
48
|
+
wrapperStyle: u
|
|
49
|
+
}) => {
|
|
50
|
+
const c = r.length ? r : F, i = s(
|
|
51
|
+
() => V(c, { plotHeight: a, headerHeight: t }),
|
|
52
|
+
[c, a, t]
|
|
53
|
+
), p = !i.isEmpty, $ = (e) => `${e / L * 100}%`, d = s(
|
|
54
|
+
() => c.map((e, f) => ({
|
|
55
|
+
stage: e,
|
|
56
|
+
color: p ? e.color ?? g(l, f) : S.content.inactive,
|
|
57
|
+
chip: p ? T(c, f) : ""
|
|
58
|
+
})),
|
|
59
|
+
[c, l, p]
|
|
60
|
+
), b = s(
|
|
61
|
+
() => new Map(d.map(({ stage: e, color: f }) => [e.key, f])),
|
|
62
|
+
[d]
|
|
63
|
+
);
|
|
64
|
+
return /* @__PURE__ */ o(
|
|
65
|
+
k,
|
|
66
|
+
{
|
|
67
|
+
dataTest: "funnel-chart",
|
|
68
|
+
title: n,
|
|
69
|
+
padding: "18px 24px",
|
|
70
|
+
gap: 14,
|
|
71
|
+
wrapperStyle: { overflow: "hidden", ...u },
|
|
72
|
+
children: /* @__PURE__ */ y(A, { $height: a, children: [
|
|
73
|
+
/* @__PURE__ */ o(
|
|
74
|
+
_,
|
|
75
|
+
{
|
|
76
|
+
width: "100%",
|
|
77
|
+
height: "100%",
|
|
78
|
+
viewBox: `0 0 ${L} ${a}`,
|
|
79
|
+
preserveAspectRatio: "none",
|
|
80
|
+
"aria-hidden": !0,
|
|
81
|
+
children: i.bands.map((e) => /* @__PURE__ */ o(
|
|
82
|
+
"path",
|
|
83
|
+
{
|
|
84
|
+
"data-test": `funnel-chart-band-${e.key}`,
|
|
85
|
+
d: e.d,
|
|
86
|
+
fill: p ? b.get(e.key) : "transparent"
|
|
87
|
+
},
|
|
88
|
+
e.key
|
|
89
|
+
))
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
i.separators.full.map((e) => /* @__PURE__ */ o(v, { $left: $(e) }, `full-${e}`)),
|
|
93
|
+
i.separators.header.map((e) => /* @__PURE__ */ o(
|
|
94
|
+
v,
|
|
95
|
+
{
|
|
96
|
+
$left: $(e),
|
|
97
|
+
$height: t
|
|
98
|
+
},
|
|
99
|
+
`header-${e}`
|
|
100
|
+
)),
|
|
101
|
+
/* @__PURE__ */ o(B, { $height: t, children: d.map((e) => /* @__PURE__ */ o(j, { ...e, locale: h }, e.stage.key)) })
|
|
102
|
+
] })
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
export {
|
|
107
|
+
K as FunnelChart
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=FunnelChart.js.map
|
package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FunnelChart.js","sources":["../../../../../../src/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport { BodyTiny } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport { ChartCard, ChartValueRow } from '../ChartLayout';\nimport { FUNNEL_BAND_COLORS, pickColor } from '../chartPalette';\nimport {\n\tformatChartValue,\n\tformatPercent,\n\ttoChartValue,\n} from '../formatChartValue';\nimport type { FunnelChartI, FunnelStageI } from './FunnelChart.model';\nimport {\n\tBandsSvg,\n\tHeaderRow,\n\tPlotArea,\n\tSeparatorLine,\n\tStageColorDot,\n\tStageHeaderColumn,\n\tStageLabelRow,\n} from './FunnelChart.styled';\nimport { buildFunnelLayout, FUNNEL_VIEW_WIDTH } from './funnelGeometry';\n\nconst PLACEHOLDER_STAGES: FunnelStageI[] = Array.from(\n\t{ length: 4 },\n\t(_, index) => ({ key: `placeholder-${index}`, label: '', value: 0 }),\n);\n\nconst derivePercentageLabel = (\n\tstages: FunnelStageI[],\n\tindex: number,\n): string => {\n\tconst stage = stages[index];\n\tif (stage.percentageLabel !== undefined) {\n\t\treturn stage.percentageLabel;\n\t}\n\tif (index === 0) {\n\t\treturn toChartValue(stage.value) > 0 ? '100%' : '';\n\t}\n\tconst reference = stage.branchOf\n\t\t? stages.find((candidate) => candidate.key === stage.branchOf)\n\t\t: stages[index - 1];\n\tconst referenceValue = toChartValue(reference?.value);\n\tif (!reference || referenceValue === 0) {\n\t\treturn '';\n\t}\n\tconst share = (toChartValue(stage.value) / referenceValue) * 100;\n\treturn `${formatPercent(share)}% of ${reference.label}`;\n};\n\ninterface StageHeaderProps {\n\tstage: FunnelStageI;\n\tcolor?: string;\n\tchip: string;\n\tlocale?: string;\n}\n\nconst StageHeader: React.FC<StageHeaderProps> = ({\n\tstage,\n\tcolor,\n\tchip,\n\tlocale,\n}) => (\n\t<StageHeaderColumn data-test={`funnel-chart-header-${stage.key}`}>\n\t\t{stage.label && (\n\t\t\t<StageLabelRow>\n\t\t\t\t<StageColorDot $color={color} />\n\t\t\t\t<BodyTiny color={COLORS.content.secondary}>{stage.label}</BodyTiny>\n\t\t\t</StageLabelRow>\n\t\t)}\n\t\t<ChartValueRow\n\t\t\tvalue={\n\t\t\t\tstage.valueLabel ?? formatChartValue(toChartValue(stage.value), locale)\n\t\t\t}\n\t\t\tchip={chip}\n\t\t/>\n\t</StageHeaderColumn>\n);\n\nexport const FunnelChart: React.FC<FunnelChartI> = ({\n\tstages = [],\n\ttitle,\n\tplotHeight = 291,\n\theaderHeight = 83,\n\tcolors = FUNNEL_BAND_COLORS,\n\tlocale,\n\twrapperStyle,\n}) => {\n\tconst visibleStages = stages.length ? stages : PLACEHOLDER_STAGES;\n\n\tconst layout = useMemo(\n\t\t() => buildFunnelLayout(visibleStages, { plotHeight, headerHeight }),\n\t\t[visibleStages, plotHeight, headerHeight],\n\t);\n\n\tconst hasData = !layout.isEmpty;\n\tconst toPercent = (x: number) => `${(x / FUNNEL_VIEW_WIDTH) * 100}%`;\n\n\tconst headers = useMemo(\n\t\t() =>\n\t\t\tvisibleStages.map((stage, index) => ({\n\t\t\t\tstage,\n\t\t\t\tcolor: hasData\n\t\t\t\t\t? stage.color ?? pickColor(colors, index)\n\t\t\t\t\t: COLORS.content.inactive,\n\t\t\t\tchip: hasData ? derivePercentageLabel(visibleStages, index) : '',\n\t\t\t})),\n\t\t[visibleStages, colors, hasData],\n\t);\n\n\tconst colorByStage = useMemo(\n\t\t() => new Map(headers.map(({ stage, color }) => [stage.key, color])),\n\t\t[headers],\n\t);\n\n\treturn (\n\t\t<ChartCard\n\t\t\tdataTest=\"funnel-chart\"\n\t\t\ttitle={title}\n\t\t\tpadding=\"18px 24px\"\n\t\t\tgap={14}\n\t\t\twrapperStyle={{ overflow: 'hidden', ...wrapperStyle }}\n\t\t>\n\t\t\t<PlotArea $height={plotHeight}>\n\t\t\t\t<BandsSvg\n\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\theight=\"100%\"\n\t\t\t\t\tviewBox={`0 0 ${FUNNEL_VIEW_WIDTH} ${plotHeight}`}\n\t\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\t\taria-hidden\n\t\t\t\t>\n\t\t\t\t\t{layout.bands.map((band) => (\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\tkey={band.key}\n\t\t\t\t\t\t\tdata-test={`funnel-chart-band-${band.key}`}\n\t\t\t\t\t\t\td={band.d}\n\t\t\t\t\t\t\tfill={hasData ? colorByStage.get(band.key) : 'transparent'}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</BandsSvg>\n\n\t\t\t\t{layout.separators.full.map((x) => (\n\t\t\t\t\t<SeparatorLine key={`full-${x}`} $left={toPercent(x)} />\n\t\t\t\t))}\n\t\t\t\t{layout.separators.header.map((x) => (\n\t\t\t\t\t<SeparatorLine\n\t\t\t\t\t\tkey={`header-${x}`}\n\t\t\t\t\t\t$left={toPercent(x)}\n\t\t\t\t\t\t$height={headerHeight}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\n\t\t\t\t<HeaderRow $height={headerHeight}>\n\t\t\t\t\t{headers.map((header) => (\n\t\t\t\t\t\t<StageHeader key={header.stage.key} {...header} locale={locale} />\n\t\t\t\t\t))}\n\t\t\t\t</HeaderRow>\n\t\t\t</PlotArea>\n\t\t</ChartCard>\n\t);\n};\n"],"names":["PLACEHOLDER_STAGES","_","index","derivePercentageLabel","stages","stage","toChartValue","reference","candidate","referenceValue","share","formatPercent","StageHeader","color","chip","locale","StageHeaderColumn","StageLabelRow","jsx","StageColorDot","BodyTiny","COLORS","ChartValueRow","formatChartValue","FunnelChart","title","plotHeight","headerHeight","colors","FUNNEL_BAND_COLORS","wrapperStyle","visibleStages","layout","useMemo","buildFunnelLayout","hasData","toPercent","x","FUNNEL_VIEW_WIDTH","headers","pickColor","colorByStage","ChartCard","jsxs","PlotArea","BandsSvg","band","SeparatorLine","HeaderRow","header"],"mappings":";;;;;;;;;AAsBA,MAAMA,IAAqC,MAAM;AAAA,EAChD,EAAE,QAAQ,EAAA;AAAA,EACV,CAACC,GAAGC,OAAW,EAAE,KAAK,eAAeA,CAAK,IAAI,OAAO,IAAI,OAAO,EAAA;AACjE,GAEMC,IAAwB,CAC7BC,GACAF,MACY;AACZ,QAAMG,IAAQD,EAAOF,CAAK;AAC1B,MAAIG,EAAM,oBAAoB;AAC7B,WAAOA,EAAM;AAEd,MAAIH,MAAU;AACb,WAAOI,EAAaD,EAAM,KAAK,IAAI,IAAI,SAAS;AAEjD,QAAME,IAAYF,EAAM,WACrBD,EAAO,KAAK,CAACI,MAAcA,EAAU,QAAQH,EAAM,QAAQ,IAC3DD,EAAOF,IAAQ,CAAC,GACbO,IAAiBH,EAAaC,GAAW,KAAK;AACpD,MAAI,CAACA,KAAaE,MAAmB;AACpC,WAAO;AAER,QAAMC,IAASJ,EAAaD,EAAM,KAAK,IAAII,IAAkB;AAC7D,SAAO,GAAGE,EAAcD,CAAK,CAAC,QAAQH,EAAU,KAAK;AACtD,GASMK,IAA0C,CAAC;AAAA,EAChD,OAAAP;AAAA,EACA,OAAAQ;AAAA,EACA,MAAAC;AAAA,EACA,QAAAC;AACD,wBACEC,GAAA,EAAkB,aAAW,uBAAuBX,EAAM,GAAG,IAC5D,UAAA;AAAA,EAAAA,EAAM,2BACLY,GAAA,EACA,UAAA;AAAA,IAAA,gBAAAC,EAACC,GAAA,EAAc,QAAQN,EAAA,CAAO;AAAA,sBAC7BO,GAAA,EAAS,OAAOC,EAAO,QAAQ,WAAY,YAAM,MAAA,CAAM;AAAA,EAAA,GACzD;AAAA,EAED,gBAAAH;AAAA,IAACI;AAAA,IAAA;AAAA,MACA,OACCjB,EAAM,cAAckB,EAAiBjB,EAAaD,EAAM,KAAK,GAAGU,CAAM;AAAA,MAEvE,MAAAD;AAAA,IAAA;AAAA,EAAA;AACD,GACD,GAGYU,IAAsC,CAAC;AAAA,EACnD,QAAApB,IAAS,CAAA;AAAA,EACT,OAAAqB;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,cAAAC,IAAe;AAAA,EACf,QAAAC,IAASC;AAAA,EACT,QAAAd;AAAA,EACA,cAAAe;AACD,MAAM;AACL,QAAMC,IAAgB3B,EAAO,SAASA,IAASJ,GAEzCgC,IAASC;AAAA,IACd,MAAMC,EAAkBH,GAAe,EAAE,YAAAL,GAAY,cAAAC,GAAc;AAAA,IACnE,CAACI,GAAeL,GAAYC,CAAY;AAAA,EAAA,GAGnCQ,IAAU,CAACH,EAAO,SAClBI,IAAY,CAACC,MAAc,GAAIA,IAAIC,IAAqB,GAAG,KAE3DC,IAAUN;AAAA,IACf,MACCF,EAAc,IAAI,CAAC1B,GAAOH,OAAW;AAAA,MACpC,OAAAG;AAAA,MACA,OAAO8B,IACJ9B,EAAM,SAASmC,EAAUZ,GAAQ1B,CAAK,IACtCmB,EAAO,QAAQ;AAAA,MAClB,MAAMc,IAAUhC,EAAsB4B,GAAe7B,CAAK,IAAI;AAAA,IAAA,EAC7D;AAAA,IACH,CAAC6B,GAAeH,GAAQO,CAAO;AAAA,EAAA,GAG1BM,IAAeR;AAAA,IACpB,MAAM,IAAI,IAAIM,EAAQ,IAAI,CAAC,EAAE,OAAAlC,GAAO,OAAAQ,EAAA,MAAY,CAACR,EAAM,KAAKQ,CAAK,CAAC,CAAC;AAAA,IACnE,CAAC0B,CAAO;AAAA,EAAA;AAGT,SACC,gBAAArB;AAAA,IAACwB;AAAA,IAAA;AAAA,MACA,UAAS;AAAA,MACT,OAAAjB;AAAA,MACA,SAAQ;AAAA,MACR,KAAK;AAAA,MACL,cAAc,EAAE,UAAU,UAAU,GAAGK,EAAA;AAAA,MAEvC,UAAA,gBAAAa,EAACC,GAAA,EAAS,SAASlB,GAClB,UAAA;AAAA,QAAA,gBAAAR;AAAA,UAAC2B;AAAA,UAAA;AAAA,YACA,OAAM;AAAA,YACN,QAAO;AAAA,YACP,SAAS,OAAOP,CAAiB,IAAIZ,CAAU;AAAA,YAC/C,qBAAoB;AAAA,YACpB,eAAW;AAAA,YAEV,UAAAM,EAAO,MAAM,IAAI,CAACc,MAClB,gBAAA5B;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEA,aAAW,qBAAqB4B,EAAK,GAAG;AAAA,gBACxC,GAAGA,EAAK;AAAA,gBACR,MAAMX,IAAUM,EAAa,IAAIK,EAAK,GAAG,IAAI;AAAA,cAAA;AAAA,cAHxCA,EAAK;AAAA,YAAA,CAKX;AAAA,UAAA;AAAA,QAAA;AAAA,QAGDd,EAAO,WAAW,KAAK,IAAI,CAACK,MAC5B,gBAAAnB,EAAC6B,GAAA,EAAgC,OAAOX,EAAUC,CAAC,EAAA,GAA/B,QAAQA,CAAC,EAAyB,CACtD;AAAA,QACAL,EAAO,WAAW,OAAO,IAAI,CAACK,MAC9B,gBAAAnB;AAAA,UAAC6B;AAAA,UAAA;AAAA,YAEA,OAAOX,EAAUC,CAAC;AAAA,YAClB,SAASV;AAAA,UAAA;AAAA,UAFJ,UAAUU,CAAC;AAAA,QAAA,CAIjB;AAAA,0BAEAW,GAAA,EAAU,SAASrB,GAClB,UAAAY,EAAQ,IAAI,CAACU,MACb,gBAAA/B,EAACN,GAAA,EAAoC,GAAGqC,GAAQ,QAAAlC,EAAA,GAA9BkC,EAAO,MAAM,GAAiC,CAChE,EAAA,CACF;AAAA,MAAA,EAAA,CACD;AAAA,IAAA;AAAA,EAAA;AAGH;"}
|
package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.model.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
export interface FunnelStageI {
|
|
3
|
+
key: string;
|
|
4
|
+
label: string;
|
|
5
|
+
value: number;
|
|
6
|
+
valueLabel?: string;
|
|
7
|
+
percentageLabel?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
branchOf?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface FunnelChartI {
|
|
12
|
+
stages: FunnelStageI[];
|
|
13
|
+
title?: string;
|
|
14
|
+
plotHeight?: number;
|
|
15
|
+
headerHeight?: number;
|
|
16
|
+
colors?: string[];
|
|
17
|
+
locale?: string;
|
|
18
|
+
wrapperStyle?: CSSProperties;
|
|
19
|
+
}
|
package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.styled.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const SeparatorLine: import('styled-components').StyledComponent<"div", any, {
|
|
2
|
+
$left: string;
|
|
3
|
+
$height?: number | undefined;
|
|
4
|
+
}, never>;
|
|
5
|
+
export declare const PlotArea: import('styled-components').StyledComponent<"div", any, {
|
|
6
|
+
$height: number;
|
|
7
|
+
}, never>;
|
|
8
|
+
export declare const BandsSvg: import('styled-components').StyledComponent<"svg", any, {}, never>;
|
|
9
|
+
export declare const HeaderRow: import('styled-components').StyledComponent<"div", any, {
|
|
10
|
+
$height: number;
|
|
11
|
+
}, never>;
|
|
12
|
+
export declare const StageHeaderColumn: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
13
|
+
export declare const StageLabelRow: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
14
|
+
export declare const StageColorDot: import('styled-components').StyledComponent<"span", any, {
|
|
15
|
+
$color?: string | undefined;
|
|
16
|
+
}, never>;
|
package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.styled.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import i from "styled-components";
|
|
2
|
+
import { COLORS as o } from "../../../../constants/Theme.js";
|
|
3
|
+
const p = i.div`
|
|
4
|
+
position: absolute;
|
|
5
|
+
top: 0;
|
|
6
|
+
${(t) => t.$height === void 0 ? "bottom: 0;" : `height: ${t.$height}px;`}
|
|
7
|
+
left: ${(t) => t.$left};
|
|
8
|
+
width: 1px;
|
|
9
|
+
background-color: ${o.stroke.primary};
|
|
10
|
+
`, r = i.div`
|
|
11
|
+
position: relative;
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: ${(t) => t.$height}px;
|
|
14
|
+
`, l = i.svg`
|
|
15
|
+
position: absolute;
|
|
16
|
+
inset: 0;
|
|
17
|
+
`, n = i.div`
|
|
18
|
+
position: absolute;
|
|
19
|
+
top: 0;
|
|
20
|
+
left: 0;
|
|
21
|
+
right: 0;
|
|
22
|
+
height: ${(t) => t.$height}px;
|
|
23
|
+
display: flex;
|
|
24
|
+
`, s = i.div`
|
|
25
|
+
flex: 1;
|
|
26
|
+
min-width: 0;
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
gap: 8px;
|
|
30
|
+
align-items: flex-start;
|
|
31
|
+
padding: 0 8px 0 12px;
|
|
32
|
+
`, d = i.div`
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
gap: 8px;
|
|
36
|
+
width: 100%;
|
|
37
|
+
opacity: 0.8;
|
|
38
|
+
`, h = i.span`
|
|
39
|
+
width: 16px;
|
|
40
|
+
height: 16px;
|
|
41
|
+
border-radius: 2.667px;
|
|
42
|
+
background-color: ${(t) => t.$color ?? "transparent"};
|
|
43
|
+
flex-shrink: 0;
|
|
44
|
+
`;
|
|
45
|
+
export {
|
|
46
|
+
l as BandsSvg,
|
|
47
|
+
n as HeaderRow,
|
|
48
|
+
r as PlotArea,
|
|
49
|
+
p as SeparatorLine,
|
|
50
|
+
h as StageColorDot,
|
|
51
|
+
s as StageHeaderColumn,
|
|
52
|
+
d as StageLabelRow
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=FunnelChart.styled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FunnelChart.styled.js","sources":["../../../../../../src/components/analytics-chips-and-dropdowns/chart/FunnelChart/FunnelChart.styled.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '@src/constants/Theme';\n\nexport const SeparatorLine = styled.div<{ $left: string; $height?: number }>`\n\tposition: absolute;\n\ttop: 0;\n\t${(props) =>\n\t\tprops.$height === undefined ? 'bottom: 0;' : `height: ${props.$height}px;`}\n\tleft: ${(props) => props.$left};\n\twidth: 1px;\n\tbackground-color: ${COLORS.stroke.primary};\n`;\n\nexport const PlotArea = styled.div<{ $height: number }>`\n\tposition: relative;\n\twidth: 100%;\n\theight: ${(props) => props.$height}px;\n`;\n\nexport const BandsSvg = styled.svg`\n\tposition: absolute;\n\tinset: 0;\n`;\n\nexport const HeaderRow = styled.div<{ $height: number }>`\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\theight: ${(props) => props.$height}px;\n\tdisplay: flex;\n`;\n\nexport const StageHeaderColumn = styled.div`\n\tflex: 1;\n\tmin-width: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\talign-items: flex-start;\n\tpadding: 0 8px 0 12px;\n`;\n\nexport const StageLabelRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\twidth: 100%;\n\topacity: 0.8;\n`;\n\nexport const StageColorDot = styled.span<{ $color?: string }>`\n\twidth: 16px;\n\theight: 16px;\n\tborder-radius: 2.667px;\n\tbackground-color: ${(props) => props.$color ?? 'transparent'};\n\tflex-shrink: 0;\n`;\n"],"names":["SeparatorLine","styled","props","COLORS","PlotArea","BandsSvg","HeaderRow","StageHeaderColumn","StageLabelRow","StageColorDot"],"mappings":";;AAGO,MAAMA,IAAgBC,EAAO;AAAA;AAAA;AAAA,GAGjC,CAACC,MACFA,EAAM,YAAY,SAAY,eAAe,WAAWA,EAAM,OAAO,KAAK;AAAA,SACnE,CAACA,MAAUA,EAAM,KAAK;AAAA;AAAA,qBAEVC,EAAO,OAAO,OAAO;AAAA,GAG7BC,IAAWH,EAAO;AAAA;AAAA;AAAA,WAGpB,CAACC,MAAUA,EAAM,OAAO;AAAA,GAGtBG,IAAWJ,EAAO;AAAA;AAAA;AAAA,GAKlBK,IAAYL,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA,WAKrB,CAACC,MAAUA,EAAM,OAAO;AAAA;AAAA,GAItBK,IAAoBN,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAU3BO,IAAgBP,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAQvBQ,IAAgBR,EAAO;AAAA;AAAA;AAAA;AAAA,qBAIf,CAACC,MAAUA,EAAM,UAAU,aAAa;AAAA;AAAA;"}
|
package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/funnelGeometry.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const FUNNEL_VIEW_WIDTH = 1000;
|
|
2
|
+
export interface FunnelGeometryStage {
|
|
3
|
+
key: string;
|
|
4
|
+
value: number;
|
|
5
|
+
branchOf?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface FunnelGeometryOptions {
|
|
8
|
+
plotHeight: number;
|
|
9
|
+
headerHeight: number;
|
|
10
|
+
}
|
|
11
|
+
export interface FunnelBandLayout {
|
|
12
|
+
key: string;
|
|
13
|
+
d: string;
|
|
14
|
+
}
|
|
15
|
+
export interface FunnelLayout {
|
|
16
|
+
bands: FunnelBandLayout[];
|
|
17
|
+
separators: {
|
|
18
|
+
full: number[];
|
|
19
|
+
header: number[];
|
|
20
|
+
};
|
|
21
|
+
isEmpty: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare const buildFunnelLayout: (stages: FunnelGeometryStage[], { plotHeight, headerHeight }: FunnelGeometryOptions) => FunnelLayout;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { toChartValue as x, clamp as k } from "../formatChartValue.js";
|
|
2
|
+
const B = 1e3, a = (n) => Math.round(n * 100) / 100, F = (n) => n.reduce((c, s, o) => {
|
|
3
|
+
const r = c[c.length - 1];
|
|
4
|
+
return s.branchOf && r?.branchOf === s.branchOf ? r.stageIndexes.push(o) : c.push({ branchOf: s.branchOf, stageIndexes: [o] }), c;
|
|
5
|
+
}, []), N = (n, { plotHeight: c, headerHeight: s }) => {
|
|
6
|
+
const o = Math.max(c - s, 0), r = s + o / 2, b = x(n[0]?.value), $ = n.length === 0 || b === 0 || o === 0, p = (t) => a(t / n.length * B), g = (t) => $ ? 0 : k(t / b * o, 0, o), l = F(n);
|
|
7
|
+
let m = 0;
|
|
8
|
+
const h = l.map((t) => {
|
|
9
|
+
const e = p(m);
|
|
10
|
+
return m += t.stageIndexes.length, { x0: e, x1: p(m) };
|
|
11
|
+
}), I = l.map(
|
|
12
|
+
(t) => t.stageIndexes.reduce(
|
|
13
|
+
(e, u) => e + x(n[u].value),
|
|
14
|
+
0
|
|
15
|
+
)
|
|
16
|
+
), O = [];
|
|
17
|
+
return l.forEach((t, e) => {
|
|
18
|
+
const { x0: u, x1: T } = h[e], f = I[e], V = I[e + 1] ?? f, E = g(f), L = g(V);
|
|
19
|
+
let i = r - E / 2, d = r - L / 2;
|
|
20
|
+
t.stageIndexes.forEach((y) => {
|
|
21
|
+
const M = f > 0 ? x(n[y].value) / f : 0, v = i + E * M, C = d + L * M;
|
|
22
|
+
O.push({
|
|
23
|
+
key: n[y].key,
|
|
24
|
+
d: [
|
|
25
|
+
`M${u} ${a(i)}`,
|
|
26
|
+
`L${T} ${a(d)}`,
|
|
27
|
+
`L${T} ${a(C)}`,
|
|
28
|
+
`L${u} ${a(v)}`,
|
|
29
|
+
"Z"
|
|
30
|
+
].join(" ")
|
|
31
|
+
}), i = v, d = C;
|
|
32
|
+
});
|
|
33
|
+
}), {
|
|
34
|
+
bands: O,
|
|
35
|
+
separators: {
|
|
36
|
+
full: h.length ? [h[0].x0, ...h.map((t) => t.x1)] : [],
|
|
37
|
+
header: l.flatMap(
|
|
38
|
+
(t) => t.stageIndexes.slice(1).map((e) => p(e))
|
|
39
|
+
)
|
|
40
|
+
},
|
|
41
|
+
isEmpty: $
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
export {
|
|
45
|
+
B as FUNNEL_VIEW_WIDTH,
|
|
46
|
+
N as buildFunnelLayout
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=funnelGeometry.js.map
|
package/dist/esm/components/analytics-chips-and-dropdowns/chart/FunnelChart/funnelGeometry.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"funnelGeometry.js","sources":["../../../../../../src/components/analytics-chips-and-dropdowns/chart/FunnelChart/funnelGeometry.ts"],"sourcesContent":["import { clamp, toChartValue } from '../formatChartValue';\n\nexport const FUNNEL_VIEW_WIDTH = 1000;\n\nexport interface FunnelGeometryStage {\n\tkey: string;\n\tvalue: number;\n\tbranchOf?: string;\n}\n\nexport interface FunnelGeometryOptions {\n\tplotHeight: number;\n\theaderHeight: number;\n}\n\nexport interface FunnelBandLayout {\n\tkey: string;\n\td: string;\n}\n\nexport interface FunnelLayout {\n\tbands: FunnelBandLayout[];\n\tseparators: {\n\t\tfull: number[];\n\t\theader: number[];\n\t};\n\tisEmpty: boolean;\n}\n\ninterface ColumnGroup {\n\tbranchOf?: string;\n\tstageIndexes: number[];\n}\n\nconst round = (value: number) => Math.round(value * 100) / 100;\n\n// Consecutive stages sharing a `branchOf` share one column, stacked vertically within it.\nconst groupIntoColumns = (stages: FunnelGeometryStage[]): ColumnGroup[] =>\n\tstages.reduce<ColumnGroup[]>((groups, stage, index) => {\n\t\tconst current = groups[groups.length - 1];\n\t\tif (stage.branchOf && current?.branchOf === stage.branchOf) {\n\t\t\tcurrent.stageIndexes.push(index);\n\t\t} else {\n\t\t\tgroups.push({ branchOf: stage.branchOf, stageIndexes: [index] });\n\t\t}\n\t\treturn groups;\n\t}, []);\n\nexport const buildFunnelLayout = (\n\tstages: FunnelGeometryStage[],\n\t{ plotHeight, headerHeight }: FunnelGeometryOptions,\n): FunnelLayout => {\n\tconst bandArea = Math.max(plotHeight - headerHeight, 0);\n\tconst centerY = headerHeight + bandArea / 2;\n\t// Every height is a fraction of the first stage, so it always fills the full band area.\n\tconst baseValue = toChartValue(stages[0]?.value);\n\tconst isEmpty = stages.length === 0 || baseValue === 0 || bandArea === 0;\n\n\tconst toX = (cellIndex: number) =>\n\t\tround((cellIndex / stages.length) * FUNNEL_VIEW_WIDTH);\n\tconst heightOf = (value: number) =>\n\t\tisEmpty ? 0 : clamp((value / baseValue) * bandArea, 0, bandArea);\n\n\tconst groups = groupIntoColumns(stages);\n\tlet cellCursor = 0;\n\tconst columns = groups.map((group) => {\n\t\tconst x0 = toX(cellCursor);\n\t\tcellCursor += group.stageIndexes.length;\n\t\treturn { x0, x1: toX(cellCursor) };\n\t});\n\n\tconst columnTotals = groups.map((group) =>\n\t\tgroup.stageIndexes.reduce(\n\t\t\t(total, index) => total + toChartValue(stages[index].value),\n\t\t\t0,\n\t\t),\n\t);\n\n\tconst bands: FunnelBandLayout[] = [];\n\tgroups.forEach((group, columnIndex) => {\n\t\tconst { x0, x1 } = columns[columnIndex];\n\t\tconst leftTotal = columnTotals[columnIndex];\n\t\tconst rightTotal = columnTotals[columnIndex + 1] ?? leftTotal;\n\t\tconst leftHeight = heightOf(leftTotal);\n\t\tconst rightHeight = heightOf(rightTotal);\n\n\t\tlet leftTop = centerY - leftHeight / 2;\n\t\tlet rightTop = centerY - rightHeight / 2;\n\n\t\t// Each stage takes its share of the column edge, stacking downward from the previous one,\n\t\t// so a band's left and right edges line up with its neighbours in adjacent columns.\n\t\tgroup.stageIndexes.forEach((stageIndex) => {\n\t\t\tconst share =\n\t\t\t\tleftTotal > 0 ? toChartValue(stages[stageIndex].value) / leftTotal : 0;\n\t\t\tconst leftBottom = leftTop + leftHeight * share;\n\t\t\tconst rightBottom = rightTop + rightHeight * share;\n\t\t\tbands.push({\n\t\t\t\tkey: stages[stageIndex].key,\n\t\t\t\td: [\n\t\t\t\t\t`M${x0} ${round(leftTop)}`,\n\t\t\t\t\t`L${x1} ${round(rightTop)}`,\n\t\t\t\t\t`L${x1} ${round(rightBottom)}`,\n\t\t\t\t\t`L${x0} ${round(leftBottom)}`,\n\t\t\t\t\t'Z',\n\t\t\t\t].join(' '),\n\t\t\t});\n\t\t\tleftTop = leftBottom;\n\t\t\trightTop = rightBottom;\n\t\t});\n\t});\n\n\treturn {\n\t\tbands,\n\t\tseparators: {\n\t\t\tfull: columns.length ? [columns[0].x0, ...columns.map((c) => c.x1)] : [],\n\t\t\theader: groups.flatMap((group) =>\n\t\t\t\tgroup.stageIndexes.slice(1).map((index) => toX(index)),\n\t\t\t),\n\t\t},\n\t\tisEmpty,\n\t};\n};\n"],"names":["FUNNEL_VIEW_WIDTH","round","value","groupIntoColumns","stages","groups","stage","index","current","buildFunnelLayout","plotHeight","headerHeight","bandArea","centerY","baseValue","toChartValue","isEmpty","toX","cellIndex","heightOf","clamp","cellCursor","columns","group","x0","columnTotals","total","bands","columnIndex","x1","leftTotal","rightTotal","leftHeight","rightHeight","leftTop","rightTop","stageIndex","share","leftBottom","rightBottom","c"],"mappings":"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"}
|