@servicetitan/marketing-ui 5.11.1 → 6.0.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/dist/components/charts/common/color-tag.d.ts +15 -0
- package/dist/components/charts/common/color-tag.d.ts.map +1 -0
- package/dist/components/charts/common/color-tag.js +79 -0
- package/dist/components/charts/common/color-tag.js.map +1 -0
- package/dist/components/charts/common/color-tag.module.less +23 -0
- package/dist/components/charts/common/color-tag.module.less.d.ts +6 -0
- package/dist/components/charts/common/index.d.ts +2 -0
- package/dist/components/charts/common/index.d.ts.map +1 -0
- package/dist/components/charts/common/index.js +3 -0
- package/dist/components/charts/common/index.js.map +1 -0
- package/dist/components/charts/funnel-chart/components/funnel-chart.d.ts.map +1 -1
- package/dist/components/charts/funnel-chart/components/funnel-chart.js +115 -70
- package/dist/components/charts/funnel-chart/components/funnel-chart.js.map +1 -1
- package/dist/components/charts/funnel-chart/components/funnel-chart.module.less +28 -10
- package/dist/components/charts/funnel-chart/components/funnel-chart.module.less.d.ts +3 -1
- package/dist/components/charts/funnel-chart/components/funnel-svg.d.ts +2 -0
- package/dist/components/charts/funnel-chart/components/funnel-svg.d.ts.map +1 -1
- package/dist/components/charts/funnel-chart/components/funnel-svg.js +72 -31
- package/dist/components/charts/funnel-chart/components/funnel-svg.js.map +1 -1
- package/dist/components/charts/funnel-chart/funnel-chart.stories.d.ts.map +1 -1
- package/dist/components/charts/funnel-chart/utils/const.d.ts +1 -1
- package/dist/components/charts/funnel-chart/utils/const.js +1 -1
- package/dist/components/charts/funnel-chart/utils/const.js.map +1 -1
- package/dist/components/charts/funnel-chart/utils/interface.d.ts +1 -0
- package/dist/components/charts/funnel-chart/utils/interface.d.ts.map +1 -1
- package/dist/components/charts/funnel-chart/utils/interface.js.map +1 -1
- package/dist/components/charts/funnel-chart/utils/svg-rounded-path.d.ts +2 -0
- package/dist/components/charts/funnel-chart/utils/svg-rounded-path.d.ts.map +1 -0
- package/dist/components/charts/funnel-chart/utils/svg-rounded-path.js +47 -0
- package/dist/components/charts/funnel-chart/utils/svg-rounded-path.js.map +1 -0
- package/dist/components/charts/line-chart/components/hover-popover.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/hover-popover.js +13 -7
- package/dist/components/charts/line-chart/components/hover-popover.js.map +1 -1
- package/dist/components/charts/line-chart/components/hover-popover.module.less +10 -0
- package/dist/components/charts/line-chart/components/hover-popover.module.less.d.ts +2 -0
- package/dist/components/charts/line-chart/components/stuff.d.ts +0 -8
- package/dist/components/charts/line-chart/components/stuff.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/stuff.js +6 -20
- package/dist/components/charts/line-chart/components/stuff.js.map +1 -1
- package/dist/components/charts/line-chart/components/stuff.module.less +0 -16
- package/dist/components/charts/line-chart/components/stuff.module.less.d.ts +0 -3
- package/dist/components/charts/line-chart/components/svg-bars.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/svg-bars.js +97 -13
- package/dist/components/charts/line-chart/components/svg-bars.js.map +1 -1
- package/dist/components/charts/line-chart/line-chart.stories.d.ts.map +1 -1
- package/dist/components/charts/line-chart/stores/line-chart.store.d.ts +5 -0
- package/dist/components/charts/line-chart/stores/line-chart.store.d.ts.map +1 -1
- package/dist/components/charts/line-chart/stores/line-chart.store.js +41 -1
- package/dist/components/charts/line-chart/stores/line-chart.store.js.map +1 -1
- package/dist/components/charts/line-chart/utils/interfaces.d.ts +4 -0
- package/dist/components/charts/line-chart/utils/interfaces.d.ts.map +1 -1
- package/dist/components/charts/line-chart/utils/interfaces.js.map +1 -1
- package/dist/components/charts/line-chart/utils/labels.js +1 -1
- package/dist/components/charts/line-chart/utils/labels.js.map +1 -1
- package/dist/components/charts/pie-chart/components/pie-chart.d.ts.map +1 -1
- package/dist/components/charts/pie-chart/components/pie-chart.js +24 -13
- package/dist/components/charts/pie-chart/components/pie-chart.js.map +1 -1
- package/dist/components/charts/pie-chart/components/pie-chart.module.less +15 -0
- package/dist/components/charts/pie-chart/components/pie-chart.module.less.d.ts +1 -0
- package/dist/components/charts/pie-chart/components/pie.d.ts.map +1 -1
- package/dist/components/charts/pie-chart/components/pie.js +105 -28
- package/dist/components/charts/pie-chart/components/pie.js.map +1 -1
- package/dist/components/charts/pie-chart/pie-chart.stories.d.ts.map +1 -1
- package/dist/components/charts/pie-chart/utils/const.js +1 -1
- package/dist/components/charts/pie-chart/utils/const.js.map +1 -1
- package/dist/components/stat/stat-card.d.ts.map +1 -1
- package/dist/components/stat/stat-card.js +28 -12
- package/dist/components/stat/stat-card.js.map +1 -1
- package/package.json +5 -3
- package/src/components/charts/common/color-tag.module.less +23 -0
- package/src/components/charts/common/color-tag.module.less.d.ts +6 -0
- package/src/components/charts/common/color-tag.tsx +92 -0
- package/src/components/charts/common/index.ts +1 -0
- package/src/components/charts/funnel-chart/components/funnel-chart.module.less +28 -10
- package/src/components/charts/funnel-chart/components/funnel-chart.module.less.d.ts +3 -1
- package/src/components/charts/funnel-chart/components/funnel-chart.tsx +107 -78
- package/src/components/charts/funnel-chart/components/funnel-svg.tsx +91 -23
- package/src/components/charts/funnel-chart/funnel-chart.stories.tsx +3 -1
- package/src/components/charts/funnel-chart/utils/const.ts +1 -1
- package/src/components/charts/funnel-chart/utils/interface.ts +1 -0
- package/src/components/charts/funnel-chart/utils/svg-rounded-path.ts +86 -0
- package/src/components/charts/line-chart/components/hover-popover.module.less +10 -0
- package/src/components/charts/line-chart/components/hover-popover.module.less.d.ts +2 -0
- package/src/components/charts/line-chart/components/hover-popover.tsx +29 -9
- package/src/components/charts/line-chart/components/stuff.module.less +0 -16
- package/src/components/charts/line-chart/components/stuff.module.less.d.ts +0 -3
- package/src/components/charts/line-chart/components/stuff.tsx +4 -30
- package/src/components/charts/line-chart/components/svg-bars.tsx +106 -9
- package/src/components/charts/line-chart/line-chart.stories.tsx +13 -8
- package/src/components/charts/line-chart/stores/line-chart.store.ts +39 -1
- package/src/components/charts/line-chart/utils/interfaces.ts +4 -0
- package/src/components/charts/line-chart/utils/labels.ts +1 -1
- package/src/components/charts/pie-chart/components/pie-chart.module.less +15 -0
- package/src/components/charts/pie-chart/components/pie-chart.module.less.d.ts +1 -0
- package/src/components/charts/pie-chart/components/pie-chart.tsx +23 -13
- package/src/components/charts/pie-chart/components/pie.tsx +106 -40
- package/src/components/charts/pie-chart/pie-chart.stories.tsx +3 -4
- package/src/components/charts/pie-chart/utils/const.ts +1 -1
- package/src/components/stat/stat-card.tsx +34 -16
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from 'react';
|
|
2
|
+
import { useMemo, useEffect } from 'react';
|
|
3
3
|
import { tokens } from '@servicetitan/tokens/core';
|
|
4
4
|
import { defaultBottomSideLength, defaultTopSideLength } from '../utils/const';
|
|
5
|
+
import { roundedPath } from '../utils/svg-rounded-path';
|
|
5
6
|
const st = (v)=>v.toFixed(2);
|
|
6
|
-
export const FunnelPyramidSvg = ({ colors, topSideLength = defaultTopSideLength, bottomSideLength = defaultBottomSideLength })=>{
|
|
7
|
+
export const FunnelPyramidSvg = ({ colors, topSideLength = defaultTopSideLength, bottomSideLength = defaultBottomSideLength, outlineColors, onRowAnchors })=>{
|
|
7
8
|
const sections = useMemo(()=>{
|
|
8
9
|
if (!colors.length) {
|
|
9
10
|
return [];
|
|
@@ -28,40 +29,49 @@ export const FunnelPyramidSvg = ({ colors, topSideLength = defaultTopSideLength,
|
|
|
28
29
|
topSideLength,
|
|
29
30
|
bottomSideLength
|
|
30
31
|
]);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
useEffect(()=>{
|
|
33
|
+
onRowAnchors === null || onRowAnchors === void 0 ? void 0 : onRowAnchors(sections.map((s)=>(s.yt + s.yb) / 2));
|
|
34
|
+
}, [
|
|
35
|
+
onRowAnchors,
|
|
36
|
+
sections
|
|
37
|
+
]);
|
|
38
|
+
const pointAlong = (start, end, t)=>(1 - t) * start + t * end;
|
|
39
|
+
const pxToViewBoxUnits = (px)=>px / 200 * 100;
|
|
40
|
+
const GAP_PX = 4;
|
|
41
|
+
const SEAM_PX = 1;
|
|
42
|
+
const gapVU = pxToViewBoxUnits(GAP_PX);
|
|
43
|
+
const seamVU = pxToViewBoxUnits(SEAM_PX);
|
|
44
|
+
const lines = useMemo(()=>{
|
|
45
|
+
return sections.map((section, i)=>{
|
|
46
|
+
const y = (section.yt + section.yb) / 2;
|
|
47
|
+
const height = section.yb - section.yt;
|
|
48
|
+
const t = (y - section.yt) / height;
|
|
49
|
+
const xLeftAtMid = pointAlong(section.xtl, section.xbl, t);
|
|
50
|
+
const x2 = Math.max(0, xLeftAtMid - gapVU);
|
|
42
51
|
return {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
id: i,
|
|
53
|
+
y,
|
|
54
|
+
x2
|
|
46
55
|
};
|
|
47
56
|
});
|
|
48
57
|
}, [
|
|
49
|
-
sections
|
|
50
|
-
|
|
51
|
-
const lines = useMemo(()=>sections.slice(1).map((s, ind)=>[
|
|
52
|
-
ind,
|
|
53
|
-
s.xtr,
|
|
54
|
-
s.yt
|
|
55
|
-
]), [
|
|
56
|
-
sections
|
|
58
|
+
sections,
|
|
59
|
+
gapVU
|
|
57
60
|
]);
|
|
61
|
+
const seams = sections.slice(0, -1).map((s, i)=>({
|
|
62
|
+
key: i,
|
|
63
|
+
x1: s.xbl,
|
|
64
|
+
x2: s.xbr,
|
|
65
|
+
yTopEdge: s.yb - gapVU / 2 + seamVU / 2,
|
|
66
|
+
color: outlineColors === null || outlineColors === void 0 ? void 0 : outlineColors[i]
|
|
67
|
+
}));
|
|
58
68
|
return /*#__PURE__*/ _jsxs("svg", {
|
|
59
69
|
width: "100%",
|
|
60
70
|
height: "100%",
|
|
61
71
|
preserveAspectRatio: "none",
|
|
62
72
|
xmlns: "http://www.w3.org/2000/svg",
|
|
63
73
|
children: [
|
|
64
|
-
/*#__PURE__*/
|
|
74
|
+
/*#__PURE__*/ _jsxs("svg", {
|
|
65
75
|
width: "100%",
|
|
66
76
|
height: "100%",
|
|
67
77
|
x: "0%",
|
|
@@ -69,10 +79,41 @@ export const FunnelPyramidSvg = ({ colors, topSideLength = defaultTopSideLength,
|
|
|
69
79
|
viewBox: "0 0 100 100",
|
|
70
80
|
preserveAspectRatio: "none",
|
|
71
81
|
xmlns: "http://www.w3.org/2000/svg",
|
|
72
|
-
children:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
82
|
+
children: [
|
|
83
|
+
sections.map((section, i)=>{
|
|
84
|
+
const isTop = i === 0;
|
|
85
|
+
const isBottom = i === sections.length - 1;
|
|
86
|
+
const d = roundedPath(section.xtl, section.xtr, section.xbr, section.xbl, section.yt, section.yb, isTop, isBottom, 2.5);
|
|
87
|
+
return /*#__PURE__*/ _jsx("path", {
|
|
88
|
+
d: d,
|
|
89
|
+
fill: colors[i],
|
|
90
|
+
stroke: outlineColors === null || outlineColors === void 0 ? void 0 : outlineColors[i],
|
|
91
|
+
strokeWidth: 1,
|
|
92
|
+
vectorEffect: "non-scaling-stroke",
|
|
93
|
+
strokeLinejoin: "round"
|
|
94
|
+
}, `section-${section.xbl}-${section.yb}-${section.xbr}-${section.yb}`);
|
|
95
|
+
}),
|
|
96
|
+
sections.slice(0, -1).map((section)=>/*#__PURE__*/ _jsx("line", {
|
|
97
|
+
x1: st(section.xbl),
|
|
98
|
+
y1: st(section.yb),
|
|
99
|
+
x2: st(section.xbr),
|
|
100
|
+
y2: st(section.yb),
|
|
101
|
+
stroke: "#fff",
|
|
102
|
+
strokeWidth: GAP_PX,
|
|
103
|
+
vectorEffect: "non-scaling-stroke",
|
|
104
|
+
strokeLinecap: "round"
|
|
105
|
+
}, `gap-${section.xbl}-${section.yb}-${section.xbr}-${section.yb}`)),
|
|
106
|
+
seams.map(({ key, x1, x2, yTopEdge, color })=>color ? /*#__PURE__*/ _jsx("line", {
|
|
107
|
+
x1: st(x1),
|
|
108
|
+
y1: st(yTopEdge),
|
|
109
|
+
x2: st(x2),
|
|
110
|
+
y2: st(yTopEdge),
|
|
111
|
+
stroke: color,
|
|
112
|
+
strokeWidth: SEAM_PX,
|
|
113
|
+
vectorEffect: "non-scaling-stroke",
|
|
114
|
+
strokeLinecap: "round"
|
|
115
|
+
}, `seam-${key}`) : null)
|
|
116
|
+
]
|
|
76
117
|
}),
|
|
77
118
|
/*#__PURE__*/ _jsx("svg", {
|
|
78
119
|
width: "100%",
|
|
@@ -82,10 +123,10 @@ export const FunnelPyramidSvg = ({ colors, topSideLength = defaultTopSideLength,
|
|
|
82
123
|
viewBox: "0 0 100 100",
|
|
83
124
|
preserveAspectRatio: "none",
|
|
84
125
|
xmlns: "http://www.w3.org/2000/svg",
|
|
85
|
-
children: lines.map((
|
|
126
|
+
children: lines.map(({ id, x2, y })=>/*#__PURE__*/ _jsx("line", {
|
|
86
127
|
x1: "0",
|
|
87
128
|
y1: st(y),
|
|
88
|
-
x2: st(
|
|
129
|
+
x2: st(x2),
|
|
89
130
|
y2: st(y),
|
|
90
131
|
stroke: tokens.colorNeutral60,
|
|
91
132
|
strokeWidth: 0.5
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/charts/funnel-chart/components/funnel-svg.tsx"],"sourcesContent":["import { useMemo, FC } from 'react';\nimport { tokens } from '@servicetitan/tokens/core';\nimport { defaultBottomSideLength, defaultTopSideLength } from '../utils/const';\n\nconst st = (v: number) => v.toFixed(2);\n\nexport interface FunnelPyramidSvgProps {\n colors: string[];\n topSideLength?: number;\n bottomSideLength?: number;\n}\n\nexport const FunnelPyramidSvg: FC<FunnelPyramidSvgProps> = ({\n colors,\n topSideLength = defaultTopSideLength,\n bottomSideLength = defaultBottomSideLength,\n}) => {\n const sections = useMemo(() => {\n if (!colors.length) {\n return [];\n }\n\n const len = colors.length;\n const yStep = 100 / len;\n const lStep = (topSideLength - Math.min(bottomSideLength, topSideLength)) / (len * 2);\n const xOffset = 100 - topSideLength;\n\n return colors.map((color, ind) => {\n return {\n yt: yStep * ind,\n yb: ind === len - 1 ? 100 : yStep * (ind + 1),\n xtl: xOffset + lStep * ind,\n xtr: 100 - lStep * ind,\n xbr: 100 - lStep * (ind + 1),\n xbl: xOffset + lStep * (ind + 1),\n c: color,\n };\n });\n }, [colors, topSideLength, bottomSideLength]);\n\n const paths = useMemo(() => {\n if (!sections.length) {\n return [];\n }\n\n return sections.map((s, ind) => {\n let path = '';\n\n path += `M${st(s.xtl)},${st(s.yt)} `;\n path += `L${st(s.xtr)},${st(s.yt)} `;\n path += `L${st(s.xbr)},${st(s.yb)} `;\n path += `L${st(s.xbl)},${st(s.yb)} `;\n path += 'Z';\n\n return {\n key: ind.toString(),\n path,\n color: s.c,\n };\n });\n }, [sections]);\n\n const lines = useMemo(() => sections.slice(1).map((s, ind) => [ind, s.xtr, s.yt]), [sections]);\n\n return (\n <svg\n width=\"100%\"\n height=\"100%\"\n preserveAspectRatio=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <svg\n width=\"100%\"\n height=\"100%\"\n x=\"0%\"\n y=\"0\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {paths.map(({ key, path, color }) => (\n <path key={key} d={path} fill={color} />\n ))}\n </svg>\n <svg\n width=\"100%\"\n height=\"100%\"\n x=\"0\"\n y=\"0\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {lines.map(([id, x, y]) => (\n <line\n key={id}\n x1=\"0\"\n y1={st(y)}\n x2={st(x)}\n y2={st(y)}\n stroke={tokens.colorNeutral60}\n strokeWidth={0.5}\n />\n ))}\n </svg>\n </svg>\n );\n};\n"],"names":["useMemo","tokens","defaultBottomSideLength","defaultTopSideLength","st","v","toFixed","FunnelPyramidSvg","colors","topSideLength","bottomSideLength","sections","length","len","yStep","lStep","Math","min","xOffset","map","color","ind","yt","yb","xtl","xtr","xbr","xbl","c","paths","s","path","key","toString","lines","slice","svg","width","height","preserveAspectRatio","xmlns","x","y","viewBox","d","fill","id","line","x1","y1","x2","y2","stroke","colorNeutral60","strokeWidth"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/charts/funnel-chart/components/funnel-svg.tsx"],"sourcesContent":["import { useMemo, FC, useEffect } from 'react';\nimport { tokens } from '@servicetitan/tokens/core';\nimport { defaultBottomSideLength, defaultTopSideLength } from '../utils/const';\nimport { roundedPath } from '../utils/svg-rounded-path';\n\nconst st = (v: number) => v.toFixed(2);\n\nexport interface FunnelPyramidSvgProps {\n colors: string[];\n topSideLength?: number;\n bottomSideLength?: number;\n outlineColors?: (string | undefined)[];\n onRowAnchors?: (ysPct: number[]) => void;\n}\n\nexport const FunnelPyramidSvg: FC<FunnelPyramidSvgProps> = ({\n colors,\n topSideLength = defaultTopSideLength,\n bottomSideLength = defaultBottomSideLength,\n outlineColors,\n onRowAnchors,\n}) => {\n const sections = useMemo(() => {\n if (!colors.length) {\n return [];\n }\n\n const len = colors.length;\n const yStep = 100 / len;\n const lStep = (topSideLength - Math.min(bottomSideLength, topSideLength)) / (len * 2);\n const xOffset = 100 - topSideLength;\n\n return colors.map((color, ind) => {\n return {\n yt: yStep * ind,\n yb: ind === len - 1 ? 100 : yStep * (ind + 1),\n xtl: xOffset + lStep * ind,\n xtr: 100 - lStep * ind,\n xbr: 100 - lStep * (ind + 1),\n xbl: xOffset + lStep * (ind + 1),\n c: color,\n };\n });\n }, [colors, topSideLength, bottomSideLength]);\n\n useEffect(() => {\n onRowAnchors?.(sections.map(s => (s.yt + s.yb) / 2));\n }, [onRowAnchors, sections]);\n\n const pointAlong = (start: number, end: number, t: number) => (1 - t) * start + t * end;\n const pxToViewBoxUnits = (px: number) => (px / 200) * 100;\n\n const GAP_PX = 4;\n const SEAM_PX = 1;\n\n const gapVU = pxToViewBoxUnits(GAP_PX);\n const seamVU = pxToViewBoxUnits(SEAM_PX);\n\n const lines = useMemo(() => {\n return sections.map((section, i) => {\n const y = (section.yt + section.yb) / 2;\n\n const height = section.yb - section.yt;\n const t = (y - section.yt) / height;\n const xLeftAtMid = pointAlong(section.xtl, section.xbl, t);\n const x2 = Math.max(0, xLeftAtMid - gapVU);\n\n return { id: i, y, x2 };\n });\n }, [sections, gapVU]);\n\n const seams = sections.slice(0, -1).map((s, i) => ({\n key: i,\n x1: s.xbl,\n x2: s.xbr,\n yTopEdge: s.yb - gapVU / 2 + seamVU / 2,\n color: outlineColors?.[i],\n }));\n\n return (\n <svg\n width=\"100%\"\n height=\"100%\"\n preserveAspectRatio=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <svg\n width=\"100%\"\n height=\"100%\"\n x=\"0%\"\n y=\"0\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {sections.map((section, i) => {\n const isTop = i === 0;\n const isBottom = i === sections.length - 1;\n\n const d = roundedPath(\n section.xtl,\n section.xtr,\n section.xbr,\n section.xbl,\n section.yt,\n section.yb,\n isTop,\n isBottom,\n 2.5\n );\n\n return (\n <path\n key={`section-${section.xbl}-${section.yb}-${section.xbr}-${section.yb}`}\n d={d}\n fill={colors[i]}\n stroke={outlineColors?.[i]}\n strokeWidth={1}\n vectorEffect=\"non-scaling-stroke\"\n strokeLinejoin=\"round\"\n />\n );\n })}\n {sections.slice(0, -1).map(section => (\n <line\n key={`gap-${section.xbl}-${section.yb}-${section.xbr}-${section.yb}`}\n x1={st(section.xbl)}\n y1={st(section.yb)}\n x2={st(section.xbr)}\n y2={st(section.yb)}\n stroke=\"#fff\"\n strokeWidth={GAP_PX}\n vectorEffect=\"non-scaling-stroke\"\n strokeLinecap=\"round\"\n />\n ))}\n {seams.map(({ key, x1, x2, yTopEdge, color }) =>\n color ? (\n <line\n key={`seam-${key}`}\n x1={st(x1)}\n y1={st(yTopEdge)}\n x2={st(x2)}\n y2={st(yTopEdge)}\n stroke={color}\n strokeWidth={SEAM_PX}\n vectorEffect=\"non-scaling-stroke\"\n strokeLinecap=\"round\"\n />\n ) : null\n )}\n </svg>\n <svg\n width=\"100%\"\n height=\"100%\"\n x=\"0\"\n y=\"0\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {lines.map(({ id, x2, y }) => (\n <line\n key={id}\n x1=\"0\"\n y1={st(y)}\n x2={st(x2)}\n y2={st(y)}\n stroke={tokens.colorNeutral60}\n strokeWidth={0.5}\n />\n ))}\n </svg>\n </svg>\n );\n};\n"],"names":["useMemo","useEffect","tokens","defaultBottomSideLength","defaultTopSideLength","roundedPath","st","v","toFixed","FunnelPyramidSvg","colors","topSideLength","bottomSideLength","outlineColors","onRowAnchors","sections","length","len","yStep","lStep","Math","min","xOffset","map","color","ind","yt","yb","xtl","xtr","xbr","xbl","c","s","pointAlong","start","end","t","pxToViewBoxUnits","px","GAP_PX","SEAM_PX","gapVU","seamVU","lines","section","i","y","height","xLeftAtMid","x2","max","id","seams","slice","key","x1","yTopEdge","svg","width","preserveAspectRatio","xmlns","x","viewBox","isTop","isBottom","d","path","fill","stroke","strokeWidth","vectorEffect","strokeLinejoin","line","y1","y2","strokeLinecap","colorNeutral60"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"funnel-chart.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/charts/funnel-chart/funnel-chart.stories.tsx"],"names":[],"mappings":";;;;;AAIA,wBAIE;
|
|
1
|
+
{"version":3,"file":"funnel-chart.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/charts/funnel-chart/funnel-chart.stories.tsx"],"names":[],"mappings":";;;;;AAIA,wBAIE;AA6CF,eAAO,MAAM,oBAAoB,+CAE/B,CAAC;AAEH,eAAO,MAAM,oBAAoB,+CAuC/B,CAAC;AAEH,eAAO,MAAM,wBAAwB,+CAQnC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/charts/funnel-chart/utils/const.ts"],"sourcesContent":["export const defaultTopSideLength =
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/charts/funnel-chart/utils/const.ts"],"sourcesContent":["export const defaultTopSideLength = 70;\nexport const defaultBottomSideLength = 30;\n"],"names":["defaultTopSideLength","defaultBottomSideLength"],"mappings":"AAAA,OAAO,MAAMA,uBAAuB,GAAG;AACvC,OAAO,MAAMC,0BAA0B,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../../../src/components/charts/funnel-chart/utils/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,CAAC,CAAC;CACZ;AAED,MAAM,MAAM,6BAA6B,CAAC,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,CAAC,CAAC;CACZ,CAAC,CAAC;AAEH,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,GAAG;IACrC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,cAAc,CAAC,EAAE,6BAA6B,CAAC,CAAC,CAAC,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../../../src/components/charts/funnel-chart/utils/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,CAAC,CAAC;CACZ;AAED,MAAM,MAAM,6BAA6B,CAAC,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,CAAC,CAAC;CACZ,CAAC,CAAC;AAEH,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,GAAG;IACrC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,cAAc,CAAC,EAAE,6BAA6B,CAAC,CAAC,CAAC,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/charts/funnel-chart/utils/interface.ts"],"sourcesContent":["import { FC } from 'react';\nimport { NumberFormatter } from '../../../../utils/formatters';\n\nexport interface FunnelChartSection<T> {\n id: number;\n title: string;\n description: string;\n value: number;\n prev?: number;\n color: string;\n textClass?: string;\n data?: T;\n}\n\nexport type FunnelChartPopoverContentType<T = any> = FC<{\n id: number;\n value: number;\n text: string;\n data?: T;\n}>;\n\nexport interface FunnelChartProps<T = any> {\n sections: FunnelChartSection<T>[];\n format: NumberFormatter;\n popoverContent?: FunnelChartPopoverContentType<T>;\n topSideLength?: number;\n bottomSideLength?: number;\n loading?: boolean;\n className?: string;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/charts/funnel-chart/utils/interface.ts"],"sourcesContent":["import { FC } from 'react';\nimport { NumberFormatter } from '../../../../utils/formatters';\n\nexport interface FunnelChartSection<T> {\n id: number;\n title: string;\n description: string;\n value: number;\n prev?: number;\n color: string;\n outlineColor?: string;\n textClass?: string;\n data?: T;\n}\n\nexport type FunnelChartPopoverContentType<T = any> = FC<{\n id: number;\n value: number;\n text: string;\n data?: T;\n}>;\n\nexport interface FunnelChartProps<T = any> {\n sections: FunnelChartSection<T>[];\n format: NumberFormatter;\n popoverContent?: FunnelChartPopoverContentType<T>;\n topSideLength?: number;\n bottomSideLength?: number;\n loading?: boolean;\n className?: string;\n}\n"],"names":[],"mappings":"AAsBA,WAQC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-rounded-path.d.ts","sourceRoot":"","sources":["../../../../../src/components/charts/funnel-chart/utils/svg-rounded-path.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,WAAW,GACpB,UAAU,MAAM,EAChB,WAAW,MAAM,EACjB,cAAc,MAAM,EACpB,aAAa,MAAM,EACnB,MAAM,MAAM,EACZ,SAAS,MAAM,EACf,UAAU,OAAO,EACjB,aAAa,OAAO,EACpB,QAAQ,MAAM,WA4DjB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const cornerRadius = (xTopLeft, xTopRight, xBottomRight, xBottomLeft, yTop, yBottom, radius)=>{
|
|
2
|
+
const topWidth = Math.max(0, xTopRight - xTopLeft);
|
|
3
|
+
const bottomWidth = Math.max(0, xBottomRight - xBottomLeft);
|
|
4
|
+
const height = Math.max(0, yBottom - yTop);
|
|
5
|
+
const maxAllowed = Math.min(topWidth / 2, bottomWidth / 2, height / 2);
|
|
6
|
+
return Math.max(0, Math.min(radius, maxAllowed));
|
|
7
|
+
};
|
|
8
|
+
export const roundedPath = (xTopLeft, xTopRight, xBottomRight, xBottomLeft, yTop, yBottom, roundTop, roundBottom, radius)=>{
|
|
9
|
+
const effectiveRadius = cornerRadius(xTopLeft, xTopRight, xBottomRight, xBottomLeft, yTop, yBottom, roundBottom ? radius / 2 : radius);
|
|
10
|
+
const insetTop = roundTop ? effectiveRadius : 0;
|
|
11
|
+
const insetBottom = roundBottom ? effectiveRadius : 0;
|
|
12
|
+
const fmt = (n)=>n.toFixed(2);
|
|
13
|
+
const M = (x, y)=>`M${fmt(x)},${fmt(y)}`;
|
|
14
|
+
const L = (x, y)=>`L${fmt(x)},${fmt(y)}`;
|
|
15
|
+
const Q = (cx, cy, x, y)=>`Q${fmt(cx)},${fmt(cy)} ${fmt(x)},${fmt(y)}`;
|
|
16
|
+
const path = [];
|
|
17
|
+
// top-left
|
|
18
|
+
path.push(M(xTopLeft + insetTop, yTop));
|
|
19
|
+
// Top edge → to top-right
|
|
20
|
+
path.push(L(xTopRight - insetTop, yTop));
|
|
21
|
+
// Top-right corner
|
|
22
|
+
if (roundTop && effectiveRadius > 0) {
|
|
23
|
+
path.push(Q(xTopRight, yTop, xTopRight, yTop + effectiveRadius));
|
|
24
|
+
}
|
|
25
|
+
// Right edge → down to bottom
|
|
26
|
+
path.push(L(xBottomRight, yBottom - insetBottom));
|
|
27
|
+
// Bottom-right corner
|
|
28
|
+
if (roundBottom && effectiveRadius > 0) {
|
|
29
|
+
path.push(Q(xBottomRight, yBottom, xBottomRight - effectiveRadius, yBottom));
|
|
30
|
+
}
|
|
31
|
+
// Bottom edge → to bottom-left
|
|
32
|
+
path.push(L(xBottomLeft + insetBottom, yBottom));
|
|
33
|
+
// Bottom-left corner
|
|
34
|
+
if (roundBottom && effectiveRadius > 0) {
|
|
35
|
+
path.push(Q(xBottomLeft, yBottom, xBottomLeft, yBottom - effectiveRadius));
|
|
36
|
+
}
|
|
37
|
+
// Left edge → up to top
|
|
38
|
+
path.push(L(xTopLeft, yTop + insetTop));
|
|
39
|
+
// Top-left corner
|
|
40
|
+
if (roundTop && effectiveRadius > 0) {
|
|
41
|
+
path.push(Q(xTopLeft, yTop, xTopLeft + effectiveRadius, yTop));
|
|
42
|
+
}
|
|
43
|
+
path.push('Z');
|
|
44
|
+
return path.join(' ');
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=svg-rounded-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/charts/funnel-chart/utils/svg-rounded-path.ts"],"sourcesContent":["const cornerRadius = (\n xTopLeft: number,\n xTopRight: number,\n xBottomRight: number,\n xBottomLeft: number,\n yTop: number,\n yBottom: number,\n radius: number\n) => {\n const topWidth = Math.max(0, xTopRight - xTopLeft);\n const bottomWidth = Math.max(0, xBottomRight - xBottomLeft);\n const height = Math.max(0, yBottom - yTop);\n const maxAllowed = Math.min(topWidth / 2, bottomWidth / 2, height / 2);\n return Math.max(0, Math.min(radius, maxAllowed));\n};\n\nexport const roundedPath = (\n xTopLeft: number,\n xTopRight: number,\n xBottomRight: number,\n xBottomLeft: number,\n yTop: number,\n yBottom: number,\n roundTop: boolean,\n roundBottom: boolean,\n radius: number\n) => {\n const effectiveRadius = cornerRadius(\n xTopLeft,\n xTopRight,\n xBottomRight,\n xBottomLeft,\n yTop,\n yBottom,\n roundBottom ? radius / 2 : radius\n );\n\n const insetTop = roundTop ? effectiveRadius : 0;\n const insetBottom = roundBottom ? effectiveRadius : 0;\n\n const fmt = (n: number) => n.toFixed(2);\n const M = (x: number, y: number) => `M${fmt(x)},${fmt(y)}`;\n const L = (x: number, y: number) => `L${fmt(x)},${fmt(y)}`;\n const Q = (cx: number, cy: number, x: number, y: number) =>\n `Q${fmt(cx)},${fmt(cy)} ${fmt(x)},${fmt(y)}`;\n\n const path: string[] = [];\n\n // top-left\n path.push(M(xTopLeft + insetTop, yTop));\n\n // Top edge → to top-right\n path.push(L(xTopRight - insetTop, yTop));\n\n // Top-right corner\n if (roundTop && effectiveRadius > 0) {\n path.push(Q(xTopRight, yTop, xTopRight, yTop + effectiveRadius));\n }\n\n // Right edge → down to bottom\n path.push(L(xBottomRight, yBottom - insetBottom));\n\n // Bottom-right corner\n if (roundBottom && effectiveRadius > 0) {\n path.push(Q(xBottomRight, yBottom, xBottomRight - effectiveRadius, yBottom));\n }\n\n // Bottom edge → to bottom-left\n path.push(L(xBottomLeft + insetBottom, yBottom));\n\n // Bottom-left corner\n if (roundBottom && effectiveRadius > 0) {\n path.push(Q(xBottomLeft, yBottom, xBottomLeft, yBottom - effectiveRadius));\n }\n\n // Left edge → up to top\n path.push(L(xTopLeft, yTop + insetTop));\n\n // Top-left corner\n if (roundTop && effectiveRadius > 0) {\n path.push(Q(xTopLeft, yTop, xTopLeft + effectiveRadius, yTop));\n }\n\n path.push('Z');\n return path.join(' ');\n};\n"],"names":["cornerRadius","xTopLeft","xTopRight","xBottomRight","xBottomLeft","yTop","yBottom","radius","topWidth","Math","max","bottomWidth","height","maxAllowed","min","roundedPath","roundTop","roundBottom","effectiveRadius","insetTop","insetBottom","fmt","n","toFixed","M","x","y","L","Q","cx","cy","path","push","join"],"mappings":"AAAA,MAAMA,eAAe,CACjBC,UACAC,WACAC,cACAC,aACAC,MACAC,SACAC;IAEA,MAAMC,WAAWC,KAAKC,GAAG,CAAC,GAAGR,YAAYD;IACzC,MAAMU,cAAcF,KAAKC,GAAG,CAAC,GAAGP,eAAeC;IAC/C,MAAMQ,SAASH,KAAKC,GAAG,CAAC,GAAGJ,UAAUD;IACrC,MAAMQ,aAAaJ,KAAKK,GAAG,CAACN,WAAW,GAAGG,cAAc,GAAGC,SAAS;IACpE,OAAOH,KAAKC,GAAG,CAAC,GAAGD,KAAKK,GAAG,CAACP,QAAQM;AACxC;AAEA,OAAO,MAAME,cAAc,CACvBd,UACAC,WACAC,cACAC,aACAC,MACAC,SACAU,UACAC,aACAV;IAEA,MAAMW,kBAAkBlB,aACpBC,UACAC,WACAC,cACAC,aACAC,MACAC,SACAW,cAAcV,SAAS,IAAIA;IAG/B,MAAMY,WAAWH,WAAWE,kBAAkB;IAC9C,MAAME,cAAcH,cAAcC,kBAAkB;IAEpD,MAAMG,MAAM,CAACC,IAAcA,EAAEC,OAAO,CAAC;IACrC,MAAMC,IAAI,CAACC,GAAWC,IAAc,CAAC,CAAC,EAAEL,IAAII,GAAG,CAAC,EAAEJ,IAAIK,IAAI;IAC1D,MAAMC,IAAI,CAACF,GAAWC,IAAc,CAAC,CAAC,EAAEL,IAAII,GAAG,CAAC,EAAEJ,IAAIK,IAAI;IAC1D,MAAME,IAAI,CAACC,IAAYC,IAAYL,GAAWC,IAC1C,CAAC,CAAC,EAAEL,IAAIQ,IAAI,CAAC,EAAER,IAAIS,IAAI,CAAC,EAAET,IAAII,GAAG,CAAC,EAAEJ,IAAIK,IAAI;IAEhD,MAAMK,OAAiB,EAAE;IAEzB,WAAW;IACXA,KAAKC,IAAI,CAACR,EAAEvB,WAAWkB,UAAUd;IAEjC,0BAA0B;IAC1B0B,KAAKC,IAAI,CAACL,EAAEzB,YAAYiB,UAAUd;IAElC,mBAAmB;IACnB,IAAIW,YAAYE,kBAAkB,GAAG;QACjCa,KAAKC,IAAI,CAACJ,EAAE1B,WAAWG,MAAMH,WAAWG,OAAOa;IACnD;IAEA,8BAA8B;IAC9Ba,KAAKC,IAAI,CAACL,EAAExB,cAAcG,UAAUc;IAEpC,sBAAsB;IACtB,IAAIH,eAAeC,kBAAkB,GAAG;QACpCa,KAAKC,IAAI,CAACJ,EAAEzB,cAAcG,SAASH,eAAee,iBAAiBZ;IACvE;IAEA,+BAA+B;IAC/ByB,KAAKC,IAAI,CAACL,EAAEvB,cAAcgB,aAAad;IAEvC,qBAAqB;IACrB,IAAIW,eAAeC,kBAAkB,GAAG;QACpCa,KAAKC,IAAI,CAACJ,EAAExB,aAAaE,SAASF,aAAaE,UAAUY;IAC7D;IAEA,wBAAwB;IACxBa,KAAKC,IAAI,CAACL,EAAE1B,UAAUI,OAAOc;IAE7B,kBAAkB;IAClB,IAAIH,YAAYE,kBAAkB,GAAG;QACjCa,KAAKC,IAAI,CAACJ,EAAE3B,UAAUI,MAAMJ,WAAWiB,iBAAiBb;IAC5D;IAEA0B,KAAKC,IAAI,CAAC;IACV,OAAOD,KAAKE,IAAI,CAAC;AACrB,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hover-popover.d.ts","sourceRoot":"","sources":["../../../../../src/components/charts/line-chart/components/hover-popover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwB,EAAE,EAAY,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"hover-popover.d.ts","sourceRoot":"","sources":["../../../../../src/components/charts/line-chart/components/hover-popover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwB,EAAE,EAAY,MAAM,OAAO,CAAC;AAa3D,eAAO,MAAM,YAAY,EAAE,EAoFzB,CAAC"}
|
|
@@ -9,9 +9,10 @@ import { SvgStore } from '../stores/svg.store';
|
|
|
9
9
|
import { getFormatter } from '../utils/formatters';
|
|
10
10
|
import { periodDateTitleFormatter } from '../utils/labels';
|
|
11
11
|
import * as Styles from './hover-popover.module.less';
|
|
12
|
-
import { ColorTag } from '
|
|
12
|
+
import { ColorTag } from '../../common';
|
|
13
|
+
import { Text } from '@servicetitan/anvil2';
|
|
13
14
|
export const HoverPopover = observer(()=>{
|
|
14
|
-
const [{ periods, resolution, hoveredIndex, metrics, display }, svgStore] = useDependencies(LineChartStore, SvgStore);
|
|
15
|
+
const [{ periods, resolution, hoveredIndex, metrics, display, formattedTotalAt, totalLabel, stackedTotals }, svgStore] = useDependencies(LineChartStore, SvgStore);
|
|
15
16
|
const formatDateTitle = useMemo(()=>periodDateTitleFormatter[resolution], [
|
|
16
17
|
resolution
|
|
17
18
|
]);
|
|
@@ -50,10 +51,11 @@ export const HoverPopover = observer(()=>{
|
|
|
50
51
|
className: classNames(Styles.popover, 'bg-white border border-radius-1 p-1'),
|
|
51
52
|
style: popoverStyle,
|
|
52
53
|
children: [
|
|
53
|
-
/*#__PURE__*/ _jsx(
|
|
54
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
54
55
|
size: "small",
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
variant: "headline",
|
|
57
|
+
el: "h6",
|
|
58
|
+
children: stackedTotals ? `${formattedTotalAt(hoveredIndex)} ${totalLabel} | ${formatDateTitle(period)}` : formatDateTitle(period)
|
|
57
59
|
}),
|
|
58
60
|
partialWeek && /*#__PURE__*/ _jsx(BodyText, {
|
|
59
61
|
size: "xsmall",
|
|
@@ -61,13 +63,17 @@ export const HoverPopover = observer(()=>{
|
|
|
61
63
|
children: "Partial week"
|
|
62
64
|
}),
|
|
63
65
|
metrics.map((m)=>{
|
|
64
|
-
var _m_opts;
|
|
66
|
+
var _m_opts, _m_opts1, _m_opts2, _m_opts3, _m_opts4;
|
|
65
67
|
return m.values[hoveredIndex] !== undefined && /*#__PURE__*/ _jsx(ColorTag, {
|
|
68
|
+
small: true,
|
|
66
69
|
label: formatValue(m.title, m.values[hoveredIndex], m.isRight),
|
|
67
70
|
color: m.color,
|
|
68
71
|
className: "m-t-1",
|
|
69
72
|
dashed: (_m_opts = m.opts) === null || _m_opts === void 0 ? void 0 : _m_opts.dashed,
|
|
70
|
-
|
|
73
|
+
pattern: (_m_opts1 = m.opts) === null || _m_opts1 === void 0 ? void 0 : _m_opts1.pattern,
|
|
74
|
+
outlineColor: (_m_opts2 = m.opts) === null || _m_opts2 === void 0 ? void 0 : _m_opts2.outlineColor,
|
|
75
|
+
strokeColor: (_m_opts3 = m.opts) === null || _m_opts3 === void 0 ? void 0 : _m_opts3.strokeColor,
|
|
76
|
+
colorTagClassName: ((_m_opts4 = m.opts) === null || _m_opts4 === void 0 ? void 0 : _m_opts4.pattern) === 'outline' ? Styles.colorTagOutlined : Styles.colorTag
|
|
71
77
|
}, m.title);
|
|
72
78
|
})
|
|
73
79
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/charts/line-chart/components/hover-popover.tsx"],"sourcesContent":["import { useCallback, useMemo, FC, Fragment } from 'react';\nimport classNames from 'classnames';\nimport { observer } from 'mobx-react';\nimport { useDependencies } from '@servicetitan/react-ioc';\nimport { BodyText } from '@servicetitan/design-system';\nimport { LineChartStore } from '../stores/line-chart.store';\nimport { SvgStore } from '../stores/svg.store';\nimport { getFormatter } from '../utils/formatters';\nimport { periodDateTitleFormatter } from '../utils/labels';\nimport * as Styles from './hover-popover.module.less';\nimport { ColorTag } from '
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/charts/line-chart/components/hover-popover.tsx"],"sourcesContent":["import { useCallback, useMemo, FC, Fragment } from 'react';\nimport classNames from 'classnames';\nimport { observer } from 'mobx-react';\nimport { useDependencies } from '@servicetitan/react-ioc';\nimport { BodyText } from '@servicetitan/design-system';\nimport { LineChartStore } from '../stores/line-chart.store';\nimport { SvgStore } from '../stores/svg.store';\nimport { getFormatter } from '../utils/formatters';\nimport { periodDateTitleFormatter } from '../utils/labels';\nimport * as Styles from './hover-popover.module.less';\nimport { ColorTag } from '../../common';\nimport { Text } from '@servicetitan/anvil2';\n\nexport const HoverPopover: FC = observer(() => {\n const [\n {\n periods,\n resolution,\n hoveredIndex,\n metrics,\n display,\n formattedTotalAt,\n totalLabel,\n stackedTotals,\n },\n svgStore,\n ] = useDependencies(LineChartStore, SvgStore);\n\n const formatDateTitle = useMemo(() => periodDateTitleFormatter[resolution], [resolution]);\n const formatValue = useCallback(\n (title: string, value: number, isRight: boolean) =>\n getFormatter(isRight ? display.metricsRightFormat : display.metricsLeftFormat)(value) +\n ' ' +\n title,\n [display]\n );\n const popoverStyle = useMemo(() => {\n const pos = svgStore.periodX(hoveredIndex);\n\n if (hoveredIndex < periods.length / 2) {\n return { left: `${svgStore.fpx(pos + 2)}%` };\n }\n\n return { right: `${svgStore.fpx(102 - pos)}%` };\n }, [svgStore, hoveredIndex, periods.length]);\n\n if (hoveredIndex < 0 || hoveredIndex >= periods.length) {\n return null;\n }\n\n const period = periods[hoveredIndex]!;\n const partialWeek = !!period.partial;\n\n return (\n <Fragment>\n <div\n className={Styles.line}\n style={{ left: svgStore.fpx(svgStore.periodX(hoveredIndex)) + '%' }}\n />\n <div\n className={classNames(Styles.popover, 'bg-white border border-radius-1 p-1')}\n style={popoverStyle}\n >\n <Text size=\"small\" variant=\"headline\" el=\"h6\">\n {stackedTotals\n ? `${formattedTotalAt(hoveredIndex)} ${totalLabel} | ${formatDateTitle(period)}`\n : formatDateTitle(period)}\n </Text>\n {partialWeek && (\n <BodyText size=\"xsmall\" subdued>\n Partial week\n </BodyText>\n )}\n {metrics.map(\n m =>\n m.values[hoveredIndex] !== undefined && (\n <ColorTag\n small\n label={formatValue(m.title, m.values[hoveredIndex], m.isRight)}\n color={m.color}\n key={m.title}\n className=\"m-t-1\"\n dashed={m.opts?.dashed}\n pattern={m.opts?.pattern}\n outlineColor={m.opts?.outlineColor}\n strokeColor={m.opts?.strokeColor}\n colorTagClassName={\n m.opts?.pattern === 'outline'\n ? Styles.colorTagOutlined\n : Styles.colorTag\n }\n />\n )\n )}\n </div>\n </Fragment>\n );\n});\n"],"names":["useCallback","useMemo","Fragment","classNames","observer","useDependencies","BodyText","LineChartStore","SvgStore","getFormatter","periodDateTitleFormatter","Styles","ColorTag","Text","HoverPopover","periods","resolution","hoveredIndex","metrics","display","formattedTotalAt","totalLabel","stackedTotals","svgStore","formatDateTitle","formatValue","title","value","isRight","metricsRightFormat","metricsLeftFormat","popoverStyle","pos","periodX","length","left","fpx","right","period","partialWeek","partial","div","className","line","style","popover","size","variant","el","subdued","map","m","values","undefined","small","label","color","dashed","opts","pattern","outlineColor","strokeColor","colorTagClassName","colorTagOutlined","colorTag"],"mappings":";AAAA,SAASA,WAAW,EAAEC,OAAO,EAAMC,QAAQ,QAAQ,QAAQ;AAC3D,OAAOC,gBAAgB,aAAa;AACpC,SAASC,QAAQ,QAAQ,aAAa;AACtC,SAASC,eAAe,QAAQ,0BAA0B;AAC1D,SAASC,QAAQ,QAAQ,8BAA8B;AACvD,SAASC,cAAc,QAAQ,6BAA6B;AAC5D,SAASC,QAAQ,QAAQ,sBAAsB;AAC/C,SAASC,YAAY,QAAQ,sBAAsB;AACnD,SAASC,wBAAwB,QAAQ,kBAAkB;AAC3D,YAAYC,YAAY,8BAA8B;AACtD,SAASC,QAAQ,QAAQ,eAAe;AACxC,SAASC,IAAI,QAAQ,uBAAuB;AAE5C,OAAO,MAAMC,eAAmBV,SAAS;IACrC,MAAM,CACF,EACIW,OAAO,EACPC,UAAU,EACVC,YAAY,EACZC,OAAO,EACPC,OAAO,EACPC,gBAAgB,EAChBC,UAAU,EACVC,aAAa,EAChB,EACDC,SACH,GAAGlB,gBAAgBE,gBAAgBC;IAEpC,MAAMgB,kBAAkBvB,QAAQ,IAAMS,wBAAwB,CAACM,WAAW,EAAE;QAACA;KAAW;IACxF,MAAMS,cAAczB,YAChB,CAAC0B,OAAeC,OAAeC,UAC3BnB,aAAamB,UAAUT,QAAQU,kBAAkB,GAAGV,QAAQW,iBAAiB,EAAEH,SAC/E,MACAD,OACJ;QAACP;KAAQ;IAEb,MAAMY,eAAe9B,QAAQ;QACzB,MAAM+B,MAAMT,SAASU,OAAO,CAAChB;QAE7B,IAAIA,eAAeF,QAAQmB,MAAM,GAAG,GAAG;YACnC,OAAO;gBAAEC,MAAM,GAAGZ,SAASa,GAAG,CAACJ,MAAM,GAAG,CAAC,CAAC;YAAC;QAC/C;QAEA,OAAO;YAAEK,OAAO,GAAGd,SAASa,GAAG,CAAC,MAAMJ,KAAK,CAAC,CAAC;QAAC;IAClD,GAAG;QAACT;QAAUN;QAAcF,QAAQmB,MAAM;KAAC;IAE3C,IAAIjB,eAAe,KAAKA,gBAAgBF,QAAQmB,MAAM,EAAE;QACpD,OAAO;IACX;IAEA,MAAMI,SAASvB,OAAO,CAACE,aAAa;IACpC,MAAMsB,cAAc,CAAC,CAACD,OAAOE,OAAO;IAEpC,qBACI,MAACtC;;0BACG,KAACuC;gBACGC,WAAW/B,OAAOgC,IAAI;gBACtBC,OAAO;oBAAET,MAAMZ,SAASa,GAAG,CAACb,SAASU,OAAO,CAAChB,iBAAiB;gBAAI;;0BAEtE,MAACwB;gBACGC,WAAWvC,WAAWQ,OAAOkC,OAAO,EAAE;gBACtCD,OAAOb;;kCAEP,KAAClB;wBAAKiC,MAAK;wBAAQC,SAAQ;wBAAWC,IAAG;kCACpC1B,gBACK,GAAGF,iBAAiBH,cAAc,CAAC,EAAEI,WAAW,GAAG,EAAEG,gBAAgBc,SAAS,GAC9Ed,gBAAgBc;;oBAEzBC,6BACG,KAACjC;wBAASwC,MAAK;wBAASG,OAAO;kCAAC;;oBAInC/B,QAAQgC,GAAG,CACRC,CAAAA;4BAQoBA,SACCA,UACKA,UACDA,UAETA;+BAZZA,EAAEC,MAAM,CAACnC,aAAa,KAAKoC,2BACvB,KAACzC;4BACG0C,KAAK;4BACLC,OAAO9B,YAAY0B,EAAEzB,KAAK,EAAEyB,EAAEC,MAAM,CAACnC,aAAa,EAAEkC,EAAEvB,OAAO;4BAC7D4B,OAAOL,EAAEK,KAAK;4BAEdd,WAAU;4BACVe,MAAM,GAAEN,UAAAA,EAAEO,IAAI,cAANP,8BAAAA,QAAQM,MAAM;4BACtBE,OAAO,GAAER,WAAAA,EAAEO,IAAI,cAANP,+BAAAA,SAAQQ,OAAO;4BACxBC,YAAY,GAAET,WAAAA,EAAEO,IAAI,cAANP,+BAAAA,SAAQS,YAAY;4BAClCC,WAAW,GAAEV,WAAAA,EAAEO,IAAI,cAANP,+BAAAA,SAAQU,WAAW;4BAChCC,mBACIX,EAAAA,WAAAA,EAAEO,IAAI,cAANP,+BAAAA,SAAQQ,OAAO,MAAK,YACdhD,OAAOoD,gBAAgB,GACvBpD,OAAOqD,QAAQ;2BATpBb,EAAEzB,KAAK;;;;;;AAiB5C,GAAG"}
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { LineChartMetric } from '../utils/interfaces';
|
|
3
3
|
import { ChartXLabels } from '../utils/internal-interfaces';
|
|
4
|
-
interface ColorTagProps {
|
|
5
|
-
label: string;
|
|
6
|
-
color: string;
|
|
7
|
-
className?: string;
|
|
8
|
-
small?: boolean;
|
|
9
|
-
dashed?: boolean;
|
|
10
|
-
}
|
|
11
|
-
export declare const ColorTag: FC<ColorTagProps>;
|
|
12
4
|
interface MetricsTitleProps {
|
|
13
5
|
metrics: LineChartMetric[];
|
|
14
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stuff.d.ts","sourceRoot":"","sources":["../../../../../src/components/charts/line-chart/components/stuff.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA0B,EAAE,EAAE,MAAM,OAAO,CAAC;AAInD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"stuff.d.ts","sourceRoot":"","sources":["../../../../../src/components/charts/line-chart/components/stuff.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA0B,EAAE,EAAE,MAAM,OAAO,CAAC;AAInD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG5D,UAAU,iBAAiB;IACvB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAe9C,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CACpB,CAsEA,CAAC"}
|
|
@@ -1,34 +1,20 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
import { BodyText, Stack } from '@servicetitan/design-system';
|
|
5
5
|
import * as Styles from './stuff.module.less';
|
|
6
|
-
|
|
7
|
-
alignItems: "center",
|
|
8
|
-
className: className,
|
|
9
|
-
children: [
|
|
10
|
-
/*#__PURE__*/ _jsx("div", {
|
|
11
|
-
style: dashed ? {
|
|
12
|
-
borderColor: color
|
|
13
|
-
} : {
|
|
14
|
-
backgroundColor: color
|
|
15
|
-
},
|
|
16
|
-
className: classNames(Styles.colorTag, dashed && Styles.colorTagDashed, small && Styles.colorTagSmall)
|
|
17
|
-
}),
|
|
18
|
-
/*#__PURE__*/ _jsx(BodyText, {
|
|
19
|
-
size: small ? 'xsmall' : 'small',
|
|
20
|
-
children: label
|
|
21
|
-
})
|
|
22
|
-
]
|
|
23
|
-
});
|
|
6
|
+
import { ColorTag } from '../../common';
|
|
24
7
|
export const MetricsTitle = ({ metrics })=>/*#__PURE__*/ _jsx(Stack, {
|
|
25
8
|
alignItems: "center",
|
|
26
9
|
children: metrics.map((m)=>{
|
|
27
|
-
var _m_opts;
|
|
10
|
+
var _m_opts, _m_opts1, _m_opts2, _m_opts3;
|
|
28
11
|
return /*#__PURE__*/ _jsx(ColorTag, {
|
|
29
12
|
label: m.title,
|
|
30
13
|
color: m.color,
|
|
31
14
|
dashed: (_m_opts = m.opts) === null || _m_opts === void 0 ? void 0 : _m_opts.dashed,
|
|
15
|
+
pattern: (_m_opts1 = m.opts) === null || _m_opts1 === void 0 ? void 0 : _m_opts1.pattern,
|
|
16
|
+
outlineColor: (_m_opts2 = m.opts) === null || _m_opts2 === void 0 ? void 0 : _m_opts2.outlineColor,
|
|
17
|
+
strokeColor: (_m_opts3 = m.opts) === null || _m_opts3 === void 0 ? void 0 : _m_opts3.strokeColor,
|
|
32
18
|
className: "m-r-4"
|
|
33
19
|
}, m.id);
|
|
34
20
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/charts/line-chart/components/stuff.tsx"],"sourcesContent":["import { CSSProperties, useMemo, FC } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Stack } from '@servicetitan/design-system';\nimport * as Styles from './stuff.module.less';\nimport { LineChartMetric } from '../utils/interfaces';\nimport { ChartXLabels } from '../utils/internal-interfaces';\
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/charts/line-chart/components/stuff.tsx"],"sourcesContent":["import { CSSProperties, useMemo, FC } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Stack } from '@servicetitan/design-system';\nimport * as Styles from './stuff.module.less';\nimport { LineChartMetric } from '../utils/interfaces';\nimport { ChartXLabels } from '../utils/internal-interfaces';\nimport { ColorTag } from '../../common';\n\ninterface MetricsTitleProps {\n metrics: LineChartMetric[];\n}\n\nexport const MetricsTitle: FC<MetricsTitleProps> = ({ metrics }) => (\n <Stack alignItems=\"center\">\n {metrics.map(m => (\n <ColorTag\n key={m.id}\n label={m.title}\n color={m.color}\n dashed={m.opts?.dashed}\n pattern={m.opts?.pattern}\n outlineColor={m.opts?.outlineColor}\n strokeColor={m.opts?.strokeColor}\n className=\"m-r-4\"\n />\n ))}\n </Stack>\n);\n\nexport const XAxisLabels: FC<{\n labels: ChartXLabels;\n width: number;\n left: number;\n right: number;\n labelsMerged: boolean;\n hasBars: boolean;\n}> = ({ labels, width, left, right, labelsMerged, hasBars }) => {\n const data = useMemo(() => {\n const styles: CSSProperties = {};\n const labelsMapped = labels.map(([text, flex], ind) => ({\n text,\n flex,\n key: `${ind}${text}`,\n className: '',\n }));\n\n if (hasBars) {\n // when we have bars, all labels will get space equally, so no need to calculate margins\n styles.marginLeft = `${left}px`;\n styles.marginRight = `${right}px`;\n } else if (labels.length && !!width && !labelsMerged) {\n // when we have only lines, we should calculate available space for first and last label\n\n const labelWidth = (width - left - right) / labels.length;\n const labelHalfWidth = labelWidth / 2;\n\n if (left) {\n if (left > labelHalfWidth) {\n styles.marginLeft = `${left - labelHalfWidth}px`;\n } else {\n labelsMapped[0].flex = (left + labelHalfWidth) / labelWidth;\n }\n } else {\n labelsMapped[0].flex = 0.5;\n labelsMapped[0].className = 't-truncate';\n }\n\n if (right) {\n if (right > labelHalfWidth) {\n styles.marginRight = `${right - labelHalfWidth}px`;\n } else {\n labelsMapped[labels.length - 1].flex = (right + labelHalfWidth) / labelWidth;\n }\n } else {\n labelsMapped[labels.length - 1].flex = 0.5;\n labelsMapped[labels.length - 1].className = 't-truncate';\n }\n }\n\n return {\n labels: labelsMapped,\n styles,\n };\n }, [labels, left, right, labelsMerged, width, hasBars]);\n\n return (\n <div style={data.styles}>\n <Stack\n direction=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n className=\"m-t-1\"\n >\n {data.labels.map(({ text, flex, key, className }) => (\n <div key={key} style={{ flex }} className={className}>\n <BodyText\n size=\"xsmall\"\n className={classNames(Styles.xAxisLabel, 'ta-center')}\n >\n {text}\n </BodyText>\n </div>\n ))}\n </Stack>\n </div>\n );\n};\n"],"names":["useMemo","classNames","BodyText","Stack","Styles","ColorTag","MetricsTitle","metrics","alignItems","map","m","label","title","color","dashed","opts","pattern","outlineColor","strokeColor","className","id","XAxisLabels","labels","width","left","right","labelsMerged","hasBars","data","styles","labelsMapped","text","flex","ind","key","marginLeft","marginRight","length","labelWidth","labelHalfWidth","div","style","direction","justifyContent","size","xAxisLabel"],"mappings":"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"}
|
|
@@ -1,21 +1,5 @@
|
|
|
1
1
|
@import (reference) '~@servicetitan/tokens/core/tokens.less';
|
|
2
2
|
|
|
3
|
-
.color-tag {
|
|
4
|
-
width: @spacing-3;
|
|
5
|
-
margin-right: @spacing-1;
|
|
6
|
-
height: 3px;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.color-tag-dashed {
|
|
10
|
-
height: 0;
|
|
11
|
-
border-top-style: dashed;
|
|
12
|
-
border-top-width: 3px;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.color-tag-small {
|
|
16
|
-
width: @spacing-2;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
3
|
.x-axis-label {
|
|
20
4
|
font-size: @typescale-0;
|
|
21
5
|
color: @color-neutral-90;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svg-bars.d.ts","sourceRoot":"","sources":["../../../../../src/components/charts/line-chart/components/svg-bars.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAG3B,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAI3D,UAAU,YAAY;IAClB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,OAAO,EAAE,EAAE,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"svg-bars.d.ts","sourceRoot":"","sources":["../../../../../src/components/charts/line-chart/components/svg-bars.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAG3B,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAI3D,UAAU,YAAY;IAClB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,OAAO,EAAE,EAAE,CAAC,YAAY,CAqKpC,CAAC;AAEF,UAAU,iBAAiB;IACvB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAyB7C,CAAC"}
|