@servicetitan/marketing-ui 7.2.0 → 7.4.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.
Files changed (43) hide show
  1. package/dist/components/ads/ads-stat.js +2 -4
  2. package/dist/components/ads/ads-stat.js.map +1 -1
  3. package/dist/components/charts/common/color-tag.d.ts.map +1 -1
  4. package/dist/components/charts/common/color-tag.js +1 -0
  5. package/dist/components/charts/common/color-tag.js.map +1 -1
  6. package/dist/components/charts/funnel-chart/components/funnel-chart.js.map +1 -1
  7. package/dist/components/charts/line-chart/components/body.js +8 -8
  8. package/dist/components/charts/line-chart/components/body.js.map +1 -1
  9. package/dist/components/charts/line-chart/components/hover-popover.d.ts.map +1 -1
  10. package/dist/components/charts/line-chart/components/hover-popover.js +22 -13
  11. package/dist/components/charts/line-chart/components/hover-popover.js.map +1 -1
  12. package/dist/components/charts/line-chart/components/hover-popover.module.less +5 -0
  13. package/dist/components/charts/line-chart/components/hover-popover.module.less.d.ts +1 -0
  14. package/dist/components/charts/line-chart/components/svg-bars.d.ts.map +1 -1
  15. package/dist/components/charts/line-chart/components/svg-bars.js +19 -25
  16. package/dist/components/charts/line-chart/components/svg-bars.js.map +1 -1
  17. package/dist/components/charts/line-chart/components/svg-lines.js +2 -2
  18. package/dist/components/charts/line-chart/components/svg-lines.js.map +1 -1
  19. package/dist/components/charts/line-chart/stores/line-chart.store.js +2 -2
  20. package/dist/components/charts/line-chart/stores/line-chart.store.js.map +1 -1
  21. package/dist/components/charts/line-chart/utils/labels.js.map +1 -1
  22. package/dist/components/charts/pie-chart/components/pie.js +2 -2
  23. package/dist/components/charts/pie-chart/components/pie.js.map +1 -1
  24. package/dist/components/charts/pie-chart/utils/const.js +1 -1
  25. package/dist/components/charts/pie-chart/utils/const.js.map +1 -1
  26. package/dist/components/stat/stat-card.d.ts.map +1 -1
  27. package/dist/components/stat/stat-card.js +53 -33
  28. package/dist/components/stat/stat-card.js.map +1 -1
  29. package/dist/components/stat/stat-card.module.less +17 -2
  30. package/dist/components/stat/stat-card.module.less.d.ts +3 -1
  31. package/dist/components/ui/line-text/line-text.js.map +1 -1
  32. package/dist/utils/date/date-range-picker-state.d.ts.map +1 -1
  33. package/dist/utils/date/date-range-picker-state.js.map +1 -1
  34. package/package.json +3 -3
  35. package/src/components/charts/common/color-tag.tsx +5 -1
  36. package/src/components/charts/line-chart/components/hover-popover.module.less +5 -0
  37. package/src/components/charts/line-chart/components/hover-popover.module.less.d.ts +1 -0
  38. package/src/components/charts/line-chart/components/hover-popover.tsx +23 -12
  39. package/src/components/charts/line-chart/components/svg-bars.tsx +20 -37
  40. package/src/components/stat/stat-card.module.less +17 -2
  41. package/src/components/stat/stat-card.module.less.d.ts +3 -1
  42. package/src/components/stat/stat-card.tsx +44 -37
  43. package/src/utils/date/date-range-picker-state.ts +3 -2
@@ -4,9 +4,8 @@ import { StatExtendedCard } from '../stat/stat-extended-card';
4
4
  import { adsStatDescriptions } from '../../utils/ads-texts';
5
5
  import { camelCaseToTitleCase } from '../../utils/string-case';
6
6
  export const AdsPerformanceStatCard = (props)=>{
7
- var _props_title;
7
+ var _props_title, _props_description;
8
8
  const titleText = (_props_title = props.title) !== null && _props_title !== void 0 ? _props_title : camelCaseToTitleCase(props.stat);
9
- var _props_description;
10
9
  const hintText = (_props_description = props.description) !== null && _props_description !== void 0 ? _props_description : adsStatDescriptions[props.stat];
11
10
  return /*#__PURE__*/ _jsx(StatCard, {
12
11
  ...props,
@@ -15,9 +14,8 @@ export const AdsPerformanceStatCard = (props)=>{
15
14
  });
16
15
  };
17
16
  export const AdsPerformanceStatExtendedCard = (props)=>{
18
- var _props_title;
17
+ var _props_title, _props_description;
19
18
  const titleText = (_props_title = props.title) !== null && _props_title !== void 0 ? _props_title : camelCaseToTitleCase(props.stat);
20
- var _props_description;
21
19
  const hintText = (_props_description = props.description) !== null && _props_description !== void 0 ? _props_description : adsStatDescriptions[props.stat];
22
20
  return /*#__PURE__*/ _jsx(StatExtendedCard, {
23
21
  ...props,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ads/ads-stat.tsx"],"sourcesContent":["import { FC } from 'react';\nimport { StatCard, StatCardProps } from '../stat/stat-card';\nimport { StatExtendedCard, StatExtendedCardProps } from '../stat/stat-extended-card';\nimport { adsStatDescriptions, AdsStatType } from '../../utils/ads-texts';\nimport { camelCaseToTitleCase } from '../../utils/string-case';\n\nexport interface AdsPerformanceStatProps extends Omit<StatCardProps, 'title'> {\n stat: AdsStatType;\n title?: string;\n}\n\nexport const AdsPerformanceStatCard: FC<AdsPerformanceStatProps> = props => {\n const titleText = props.title ?? camelCaseToTitleCase(props.stat);\n const hintText = props.description ?? adsStatDescriptions[props.stat];\n\n return <StatCard {...props} title={titleText} description={hintText} />;\n};\n\nexport interface AdsPerformanceStatExtendedProps extends Omit<StatExtendedCardProps, 'title'> {\n stat: AdsStatType;\n title?: string;\n title2: string;\n}\n\nexport const AdsPerformanceStatExtendedCard: FC<AdsPerformanceStatExtendedProps> = props => {\n const titleText = props.title ?? camelCaseToTitleCase(props.stat);\n const hintText = props.description ?? adsStatDescriptions[props.stat];\n\n return <StatExtendedCard {...props} title={titleText} description={hintText} />;\n};\n"],"names":["StatCard","StatExtendedCard","adsStatDescriptions","camelCaseToTitleCase","AdsPerformanceStatCard","props","titleText","title","stat","hintText","description","AdsPerformanceStatExtendedCard"],"mappings":";AACA,SAASA,QAAQ,QAAuB,oBAAoB;AAC5D,SAASC,gBAAgB,QAA+B,6BAA6B;AACrF,SAASC,mBAAmB,QAAqB,wBAAwB;AACzE,SAASC,oBAAoB,QAAQ,0BAA0B;AAO/D,OAAO,MAAMC,yBAAsDC,CAAAA;QAC7CA;IAAlB,MAAMC,YAAYD,CAAAA,eAAAA,MAAME,KAAK,cAAXF,0BAAAA,eAAeF,qBAAqBE,MAAMG,IAAI;QAC/CH;IAAjB,MAAMI,WAAWJ,CAAAA,qBAAAA,MAAMK,WAAW,cAAjBL,gCAAAA,qBAAqBH,mBAAmB,CAACG,MAAMG,IAAI,CAAC;IAErE,qBAAO,KAACR;QAAU,GAAGK,KAAK;QAAEE,OAAOD;QAAWI,aAAaD;;AAC/D,EAAE;AAQF,OAAO,MAAME,iCAAsEN,CAAAA;QAC7DA;IAAlB,MAAMC,YAAYD,CAAAA,eAAAA,MAAME,KAAK,cAAXF,0BAAAA,eAAeF,qBAAqBE,MAAMG,IAAI;QAC/CH;IAAjB,MAAMI,WAAWJ,CAAAA,qBAAAA,MAAMK,WAAW,cAAjBL,gCAAAA,qBAAqBH,mBAAmB,CAACG,MAAMG,IAAI,CAAC;IAErE,qBAAO,KAACP;QAAkB,GAAGI,KAAK;QAAEE,OAAOD;QAAWI,aAAaD;;AACvE,EAAE"}
1
+ {"version":3,"sources":["../../../src/components/ads/ads-stat.tsx"],"sourcesContent":["import { FC } from 'react';\nimport { StatCard, StatCardProps } from '../stat/stat-card';\nimport { StatExtendedCard, StatExtendedCardProps } from '../stat/stat-extended-card';\nimport { adsStatDescriptions, AdsStatType } from '../../utils/ads-texts';\nimport { camelCaseToTitleCase } from '../../utils/string-case';\n\nexport interface AdsPerformanceStatProps extends Omit<StatCardProps, 'title'> {\n stat: AdsStatType;\n title?: string;\n}\n\nexport const AdsPerformanceStatCard: FC<AdsPerformanceStatProps> = props => {\n const titleText = props.title ?? camelCaseToTitleCase(props.stat);\n const hintText = props.description ?? adsStatDescriptions[props.stat];\n\n return <StatCard {...props} title={titleText} description={hintText} />;\n};\n\nexport interface AdsPerformanceStatExtendedProps extends Omit<StatExtendedCardProps, 'title'> {\n stat: AdsStatType;\n title?: string;\n title2: string;\n}\n\nexport const AdsPerformanceStatExtendedCard: FC<AdsPerformanceStatExtendedProps> = props => {\n const titleText = props.title ?? camelCaseToTitleCase(props.stat);\n const hintText = props.description ?? adsStatDescriptions[props.stat];\n\n return <StatExtendedCard {...props} title={titleText} description={hintText} />;\n};\n"],"names":["StatCard","StatExtendedCard","adsStatDescriptions","camelCaseToTitleCase","AdsPerformanceStatCard","props","titleText","title","stat","hintText","description","AdsPerformanceStatExtendedCard"],"mappings":";AACA,SAASA,QAAQ,QAAuB,oBAAoB;AAC5D,SAASC,gBAAgB,QAA+B,6BAA6B;AACrF,SAASC,mBAAmB,QAAqB,wBAAwB;AACzE,SAASC,oBAAoB,QAAQ,0BAA0B;AAO/D,OAAO,MAAMC,yBAAsDC,CAAAA;QAC7CA,cACDA;IADjB,MAAMC,aAAYD,eAAAA,MAAME,KAAK,cAAXF,0BAAAA,eAAeF,qBAAqBE,MAAMG,IAAI;IAChE,MAAMC,YAAWJ,qBAAAA,MAAMK,WAAW,cAAjBL,gCAAAA,qBAAqBH,mBAAmB,CAACG,MAAMG,IAAI,CAAC;IAErE,qBAAO,KAACR;QAAU,GAAGK,KAAK;QAAEE,OAAOD;QAAWI,aAAaD;;AAC/D,EAAE;AAQF,OAAO,MAAME,iCAAsEN,CAAAA;QAC7DA,cACDA;IADjB,MAAMC,aAAYD,eAAAA,MAAME,KAAK,cAAXF,0BAAAA,eAAeF,qBAAqBE,MAAMG,IAAI;IAChE,MAAMC,YAAWJ,qBAAAA,MAAMK,WAAW,cAAjBL,gCAAAA,qBAAqBH,mBAAmB,CAACG,MAAMG,IAAI,CAAC;IAErE,qBAAO,KAACP;QAAkB,GAAGI,KAAK;QAAEE,OAAOD;QAAWI,aAAaD;;AACvE,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"file":"color-tag.d.ts","sourceRoot":"","sources":["../../../../src/components/charts/common/color-tag.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAS,MAAM,OAAO,CAAC;AAKlC,UAAU,aAAa;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;CAC7C;AAED,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CA0EtC,CAAC"}
1
+ {"version":3,"file":"color-tag.d.ts","sourceRoot":"","sources":["../../../../src/components/charts/common/color-tag.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAS,MAAM,OAAO,CAAC;AAKlC,UAAU,aAAa;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;CAC7C;AAED,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CA8EtC,CAAC"}
@@ -62,6 +62,7 @@ export const ColorTag = ({ label, color, className, small, dashed, outlineColor,
62
62
  borderColor: strokeColor !== null && strokeColor !== void 0 ? strokeColor : color
63
63
  } : pattern === 'outline' ? {
64
64
  borderColor: outlineColor !== null && outlineColor !== void 0 ? outlineColor : color,
65
+ backgroundColor: color,
65
66
  borderRadius: radius
66
67
  } : {
67
68
  backgroundColor: color,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/charts/common/color-tag.tsx"],"sourcesContent":["import { FC, useId } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Stack } from '@servicetitan/design-system';\nimport * as Styles from './color-tag.module.less';\n\ninterface ColorTagProps {\n label: string;\n color: string;\n className?: string;\n colorTagClassName?: string;\n small?: boolean;\n dashed?: boolean;\n strokeColor?: string;\n outlineColor?: string;\n pattern?: 'solid' | 'striped' | 'outline';\n}\n\nexport const ColorTag: FC<ColorTagProps> = ({\n label,\n color,\n className,\n small,\n dashed,\n outlineColor,\n pattern,\n strokeColor,\n colorTagClassName,\n}) => {\n const uid = useId();\n const patternId = `pattern-${uid}`;\n\n const width = small ? 50 : 22;\n const height = small ? 10 : 25;\n const radius = small ? 0 : 3;\n\n return (\n <Stack alignItems=\"center\" className={className} gap={1}>\n {pattern === 'striped' ? (\n <svg\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n className={classNames(Styles.colorTag, colorTagClassName)}\n aria-hidden\n >\n <defs>\n <pattern\n id={patternId}\n patternUnits=\"userSpaceOnUse\"\n width=\"8\"\n height=\"8\"\n patternTransform=\"rotate(45)\"\n >\n <rect width=\"4\" height=\"8\" fill={color} opacity=\"0.08\" />\n <rect width=\"2\" height=\"8\" fill={color} />\n </pattern>\n </defs>\n <rect\n x=\"0\"\n y=\"0\"\n width={width}\n height={height}\n rx={radius}\n ry={radius}\n fill={`url(#${patternId})`}\n stroke={strokeColor ?? color}\n strokeWidth={1}\n vectorEffect=\"non-scaling-stroke\"\n />\n </svg>\n ) : (\n <div\n className={classNames(\n Styles.colorTag,\n small && Styles.colorTagSmall,\n dashed && Styles.colorTagDashed,\n pattern === 'outline' && Styles.colorTagOutline,\n colorTagClassName\n )}\n style={\n dashed\n ? { borderColor: strokeColor ?? color }\n : pattern === 'outline'\n ? { borderColor: outlineColor ?? color, borderRadius: radius }\n : { backgroundColor: color, borderRadius: radius }\n }\n />\n )}\n <BodyText size={small ? 'xsmall' : 'small'}>{label}</BodyText>\n </Stack>\n );\n};\n"],"names":["useId","classNames","BodyText","Stack","Styles","ColorTag","label","color","className","small","dashed","outlineColor","pattern","strokeColor","colorTagClassName","uid","patternId","width","height","radius","alignItems","gap","svg","viewBox","colorTag","aria-hidden","defs","id","patternUnits","patternTransform","rect","fill","opacity","x","y","rx","ry","stroke","strokeWidth","vectorEffect","div","colorTagSmall","colorTagDashed","colorTagOutline","style","borderColor","borderRadius","backgroundColor","size"],"mappings":";AAAA,SAAaA,KAAK,QAAQ,QAAQ;AAClC,OAAOC,gBAAgB,aAAa;AACpC,SAASC,QAAQ,EAAEC,KAAK,QAAQ,8BAA8B;AAC9D,YAAYC,YAAY,0BAA0B;AAclD,OAAO,MAAMC,WAA8B,CAAC,EACxCC,KAAK,EACLC,KAAK,EACLC,SAAS,EACTC,KAAK,EACLC,MAAM,EACNC,YAAY,EACZC,OAAO,EACPC,WAAW,EACXC,iBAAiB,EACpB;IACG,MAAMC,MAAMf;IACZ,MAAMgB,YAAY,CAAC,QAAQ,EAAED,KAAK;IAElC,MAAME,QAAQR,QAAQ,KAAK;IAC3B,MAAMS,SAAST,QAAQ,KAAK;IAC5B,MAAMU,SAASV,QAAQ,IAAI;IAE3B,qBACI,MAACN;QAAMiB,YAAW;QAASZ,WAAWA;QAAWa,KAAK;;YACjDT,YAAY,0BACT,MAACU;gBACGL,OAAOA;gBACPC,QAAQA;gBACRK,SAAS,CAAC,IAAI,EAAEN,MAAM,CAAC,EAAEC,QAAQ;gBACjCV,WAAWP,WAAWG,OAAOoB,QAAQ,EAAEV;gBACvCW,aAAW;;kCAEX,KAACC;kCACG,cAAA,MAACd;4BACGe,IAAIX;4BACJY,cAAa;4BACbX,OAAM;4BACNC,QAAO;4BACPW,kBAAiB;;8CAEjB,KAACC;oCAAKb,OAAM;oCAAIC,QAAO;oCAAIa,MAAMxB;oCAAOyB,SAAQ;;8CAChD,KAACF;oCAAKb,OAAM;oCAAIC,QAAO;oCAAIa,MAAMxB;;;;;kCAGzC,KAACuB;wBACGG,GAAE;wBACFC,GAAE;wBACFjB,OAAOA;wBACPC,QAAQA;wBACRiB,IAAIhB;wBACJiB,IAAIjB;wBACJY,MAAM,CAAC,KAAK,EAAEf,UAAU,CAAC,CAAC;wBAC1BqB,QAAQxB,wBAAAA,yBAAAA,cAAeN;wBACvB+B,aAAa;wBACbC,cAAa;;;+BAIrB,KAACC;gBACGhC,WAAWP,WACPG,OAAOoB,QAAQ,EACff,SAASL,OAAOqC,aAAa,EAC7B/B,UAAUN,OAAOsC,cAAc,EAC/B9B,YAAY,aAAaR,OAAOuC,eAAe,EAC/C7B;gBAEJ8B,OACIlC,SACM;oBAAEmC,aAAahC,wBAAAA,yBAAAA,cAAeN;gBAAM,IACpCK,YAAY,YACV;oBAAEiC,aAAalC,yBAAAA,0BAAAA,eAAgBJ;oBAAOuC,cAAc3B;gBAAO,IAC3D;oBAAE4B,iBAAiBxC;oBAAOuC,cAAc3B;gBAAO;;0BAInE,KAACjB;gBAAS8C,MAAMvC,QAAQ,WAAW;0BAAUH;;;;AAGzD,EAAE"}
1
+ {"version":3,"sources":["../../../../src/components/charts/common/color-tag.tsx"],"sourcesContent":["import { FC, useId } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Stack } from '@servicetitan/design-system';\nimport * as Styles from './color-tag.module.less';\n\ninterface ColorTagProps {\n label: string;\n color: string;\n className?: string;\n colorTagClassName?: string;\n small?: boolean;\n dashed?: boolean;\n strokeColor?: string;\n outlineColor?: string;\n pattern?: 'solid' | 'striped' | 'outline';\n}\n\nexport const ColorTag: FC<ColorTagProps> = ({\n label,\n color,\n className,\n small,\n dashed,\n outlineColor,\n pattern,\n strokeColor,\n colorTagClassName,\n}) => {\n const uid = useId();\n const patternId = `pattern-${uid}`;\n\n const width = small ? 50 : 22;\n const height = small ? 10 : 25;\n const radius = small ? 0 : 3;\n\n return (\n <Stack alignItems=\"center\" className={className} gap={1}>\n {pattern === 'striped' ? (\n <svg\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n className={classNames(Styles.colorTag, colorTagClassName)}\n aria-hidden\n >\n <defs>\n <pattern\n id={patternId}\n patternUnits=\"userSpaceOnUse\"\n width=\"8\"\n height=\"8\"\n patternTransform=\"rotate(45)\"\n >\n <rect width=\"4\" height=\"8\" fill={color} opacity=\"0.08\" />\n <rect width=\"2\" height=\"8\" fill={color} />\n </pattern>\n </defs>\n <rect\n x=\"0\"\n y=\"0\"\n width={width}\n height={height}\n rx={radius}\n ry={radius}\n fill={`url(#${patternId})`}\n stroke={strokeColor ?? color}\n strokeWidth={1}\n vectorEffect=\"non-scaling-stroke\"\n />\n </svg>\n ) : (\n <div\n className={classNames(\n Styles.colorTag,\n small && Styles.colorTagSmall,\n dashed && Styles.colorTagDashed,\n pattern === 'outline' && Styles.colorTagOutline,\n colorTagClassName\n )}\n style={\n dashed\n ? { borderColor: strokeColor ?? color }\n : pattern === 'outline'\n ? {\n borderColor: outlineColor ?? color,\n backgroundColor: color,\n borderRadius: radius,\n }\n : { backgroundColor: color, borderRadius: radius }\n }\n />\n )}\n <BodyText size={small ? 'xsmall' : 'small'}>{label}</BodyText>\n </Stack>\n );\n};\n"],"names":["useId","classNames","BodyText","Stack","Styles","ColorTag","label","color","className","small","dashed","outlineColor","pattern","strokeColor","colorTagClassName","uid","patternId","width","height","radius","alignItems","gap","svg","viewBox","colorTag","aria-hidden","defs","id","patternUnits","patternTransform","rect","fill","opacity","x","y","rx","ry","stroke","strokeWidth","vectorEffect","div","colorTagSmall","colorTagDashed","colorTagOutline","style","borderColor","backgroundColor","borderRadius","size"],"mappings":";AAAA,SAAaA,KAAK,QAAQ,QAAQ;AAClC,OAAOC,gBAAgB,aAAa;AACpC,SAASC,QAAQ,EAAEC,KAAK,QAAQ,8BAA8B;AAC9D,YAAYC,YAAY,0BAA0B;AAclD,OAAO,MAAMC,WAA8B,CAAC,EACxCC,KAAK,EACLC,KAAK,EACLC,SAAS,EACTC,KAAK,EACLC,MAAM,EACNC,YAAY,EACZC,OAAO,EACPC,WAAW,EACXC,iBAAiB,EACpB;IACG,MAAMC,MAAMf;IACZ,MAAMgB,YAAY,CAAC,QAAQ,EAAED,KAAK;IAElC,MAAME,QAAQR,QAAQ,KAAK;IAC3B,MAAMS,SAAST,QAAQ,KAAK;IAC5B,MAAMU,SAASV,QAAQ,IAAI;IAE3B,qBACI,MAACN;QAAMiB,YAAW;QAASZ,WAAWA;QAAWa,KAAK;;YACjDT,YAAY,0BACT,MAACU;gBACGL,OAAOA;gBACPC,QAAQA;gBACRK,SAAS,CAAC,IAAI,EAAEN,MAAM,CAAC,EAAEC,QAAQ;gBACjCV,WAAWP,WAAWG,OAAOoB,QAAQ,EAAEV;gBACvCW,aAAW;;kCAEX,KAACC;kCACG,cAAA,MAACd;4BACGe,IAAIX;4BACJY,cAAa;4BACbX,OAAM;4BACNC,QAAO;4BACPW,kBAAiB;;8CAEjB,KAACC;oCAAKb,OAAM;oCAAIC,QAAO;oCAAIa,MAAMxB;oCAAOyB,SAAQ;;8CAChD,KAACF;oCAAKb,OAAM;oCAAIC,QAAO;oCAAIa,MAAMxB;;;;;kCAGzC,KAACuB;wBACGG,GAAE;wBACFC,GAAE;wBACFjB,OAAOA;wBACPC,QAAQA;wBACRiB,IAAIhB;wBACJiB,IAAIjB;wBACJY,MAAM,CAAC,KAAK,EAAEf,UAAU,CAAC,CAAC;wBAC1BqB,MAAM,EAAExB,wBAAAA,yBAAAA,cAAeN;wBACvB+B,aAAa;wBACbC,cAAa;;;+BAIrB,KAACC;gBACGhC,WAAWP,WACPG,OAAOoB,QAAQ,EACff,SAASL,OAAOqC,aAAa,EAC7B/B,UAAUN,OAAOsC,cAAc,EAC/B9B,YAAY,aAAaR,OAAOuC,eAAe,EAC/C7B;gBAEJ8B,OACIlC,SACM;oBAAEmC,WAAW,EAAEhC,wBAAAA,yBAAAA,cAAeN;gBAAM,IACpCK,YAAY,YACV;oBACIiC,WAAW,EAAElC,yBAAAA,0BAAAA,eAAgBJ;oBAC7BuC,iBAAiBvC;oBACjBwC,cAAc5B;gBAClB,IACA;oBAAE2B,iBAAiBvC;oBAAOwC,cAAc5B;gBAAO;;0BAInE,KAACjB;gBAAS8C,MAAMvC,QAAQ,WAAW;0BAAUH;;;;AAGzD,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/funnel-chart/components/funnel-chart.tsx"],"sourcesContent":["import { useMemo, useState, FC, Fragment } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Eyebrow, Icon, Mask, Stack, Tooltip } from '@servicetitan/design-system';\nimport { tokens } from '@servicetitan/tokens/core';\nimport { formatValue } from '../../../../utils/formatters';\nimport { StatDiff } from '../../../stat/stat-card';\nimport { FunnelChartProps } from '../utils/interface';\nimport { defaultBottomSideLength, defaultTopSideLength } from '../utils/const';\nimport { FunnelPyramidSvg } from './funnel-svg';\nimport * as Styles from './funnel-chart.module.less';\nimport { Popover } from '@servicetitan/anvil2';\nimport { ColorTag } from '../../common';\n\nexport const FunnelChart: FC<FunnelChartProps> = ({\n sections,\n format,\n topSideLength = defaultTopSideLength,\n bottomSideLength = defaultBottomSideLength,\n popoverContent: PopoverContent,\n loading,\n className,\n}) => {\n const [popoverShown, setPopoverShown] = useState<number | undefined>(undefined);\n const [rowYs, setRowYs] = useState<number[]>([]);\n const colors = useMemo(() => sections.map(s => s.color), [sections]);\n const outlineColors = useMemo(() => sections.map(s => s.outlineColor), [sections]);\n const hidePopover = () => setPopoverShown(undefined);\n\n const rightStyles = useMemo(\n () => ({\n left: `${100 - topSideLength}%`,\n }),\n [topSideLength]\n );\n\n return (\n <Mask\n className={classNames(\n 'h-100 bg-white border border-radius-2 p-3 of-hidden position-relative',\n className\n )}\n active={!!loading}\n >\n <div className={Styles.pyramidWrapper}>\n <FunnelPyramidSvg\n colors={colors}\n outlineColors={outlineColors}\n topSideLength={topSideLength}\n bottomSideLength={bottomSideLength}\n onRowAnchors={setRowYs}\n />\n </div>\n\n <div\n className={classNames(\n 'd-f flex-column justify-content-around',\n Styles.pyramidBoxRight\n )}\n style={rightStyles}\n >\n {sections.map(({ id, title, value, color, prev, data, outlineColor }) => (\n <Stack\n key={title}\n className={Styles.flex1}\n justifyContent=\"center\"\n alignItems=\"center\"\n onMouseEnter={() => setPopoverShown(id)}\n onMouseLeave={hidePopover}\n >\n <Popover open={popoverShown === id} openOnHover placement=\"right\">\n <Popover.Trigger>\n {props => (\n <span {...props}>\n <div className={Styles.percentTextWrapper}>\n <BodyText\n className={classNames(Styles.percentText)}\n data-cy={`marketing-funnel-section-${id}-value`}\n >\n {formatValue(value, format)}\n </BodyText>\n </div>\n </span>\n )}\n </Popover.Trigger>\n <Popover.Content>\n <Stack\n alignItems=\"flex-start\"\n justifyContent=\"flex-start\"\n direction=\"column\"\n data-cy={`marketing-funnel-popover-${id}-content`}\n >\n <Stack>\n <ColorTag\n label=\"\"\n color={color}\n outlineColor={outlineColor}\n pattern={outlineColor ? 'outline' : 'solid'}\n />\n <BodyText bold className=\"m-r-half\">\n {title} {formatValue(value, format)}\n </BodyText>\n </Stack>\n <Stack.Item>\n <StatDiff\n value={value}\n prev={prev}\n size=\"xsmall\"\n format={format}\n />\n </Stack.Item>\n </Stack>\n\n {!!PopoverContent && (\n <PopoverContent\n id={id}\n value={value}\n text={formatValue(value, format)}\n data={data}\n />\n )}\n </Popover.Content>\n </Popover>\n </Stack>\n ))}\n </div>\n <div className={Styles.pyramidBoxLeft} style={{ width: `${100 - topSideLength}%` }}>\n {sections.map((s, i) => {\n const y = rowYs[i] ?? 0;\n const TITLE_UP = 24;\n const DIFF_DOWN = 4;\n\n return (\n <Fragment key={s.id}>\n <div\n className={Styles.leftTitle}\n style={{ top: `calc(${y}% - ${TITLE_UP}px)` }}\n >\n <Eyebrow\n size=\"small\"\n className={classNames(Styles.statTitle, 'm-r-half')}\n >\n {s.title}\n </Eyebrow>\n <Tooltip direction=\"t\" portal text={s.description}>\n <Icon\n name=\"info\"\n className=\"m-r-1\"\n size=\"14px\"\n color={tokens.colorNeutral90}\n />\n </Tooltip>\n </div>\n\n <div\n className={Styles.leftDiff}\n style={{ top: `calc(${y}% + ${DIFF_DOWN}px)` }}\n >\n <StatDiff\n value={s.value}\n prev={s.prev}\n size=\"small\"\n format={format}\n />\n </div>\n </Fragment>\n );\n })}\n </div>\n </Mask>\n );\n};\n"],"names":["useMemo","useState","Fragment","classNames","BodyText","Eyebrow","Icon","Mask","Stack","Tooltip","tokens","formatValue","StatDiff","defaultBottomSideLength","defaultTopSideLength","FunnelPyramidSvg","Styles","Popover","ColorTag","FunnelChart","sections","format","topSideLength","bottomSideLength","popoverContent","PopoverContent","loading","className","popoverShown","setPopoverShown","undefined","rowYs","setRowYs","colors","map","s","color","outlineColors","outlineColor","hidePopover","rightStyles","left","active","div","pyramidWrapper","onRowAnchors","pyramidBoxRight","style","id","title","value","prev","data","flex1","justifyContent","alignItems","onMouseEnter","onMouseLeave","open","openOnHover","placement","Trigger","props","span","percentTextWrapper","percentText","data-cy","Content","direction","label","pattern","bold","Item","size","text","pyramidBoxLeft","width","i","y","TITLE_UP","DIFF_DOWN","leftTitle","top","statTitle","portal","description","name","colorNeutral90","leftDiff"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/funnel-chart/components/funnel-chart.tsx"],"sourcesContent":["import { useMemo, useState, FC, Fragment } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Eyebrow, Icon, Mask, Stack, Tooltip } from '@servicetitan/design-system';\nimport { tokens } from '@servicetitan/tokens/core';\nimport { formatValue } from '../../../../utils/formatters';\nimport { StatDiff } from '../../../stat/stat-card';\nimport { FunnelChartProps } from '../utils/interface';\nimport { defaultBottomSideLength, defaultTopSideLength } from '../utils/const';\nimport { FunnelPyramidSvg } from './funnel-svg';\nimport * as Styles from './funnel-chart.module.less';\nimport { Popover } from '@servicetitan/anvil2';\nimport { ColorTag } from '../../common';\n\nexport const FunnelChart: FC<FunnelChartProps> = ({\n sections,\n format,\n topSideLength = defaultTopSideLength,\n bottomSideLength = defaultBottomSideLength,\n popoverContent: PopoverContent,\n loading,\n className,\n}) => {\n const [popoverShown, setPopoverShown] = useState<number | undefined>(undefined);\n const [rowYs, setRowYs] = useState<number[]>([]);\n const colors = useMemo(() => sections.map(s => s.color), [sections]);\n const outlineColors = useMemo(() => sections.map(s => s.outlineColor), [sections]);\n const hidePopover = () => setPopoverShown(undefined);\n\n const rightStyles = useMemo(\n () => ({\n left: `${100 - topSideLength}%`,\n }),\n [topSideLength]\n );\n\n return (\n <Mask\n className={classNames(\n 'h-100 bg-white border border-radius-2 p-3 of-hidden position-relative',\n className\n )}\n active={!!loading}\n >\n <div className={Styles.pyramidWrapper}>\n <FunnelPyramidSvg\n colors={colors}\n outlineColors={outlineColors}\n topSideLength={topSideLength}\n bottomSideLength={bottomSideLength}\n onRowAnchors={setRowYs}\n />\n </div>\n\n <div\n className={classNames(\n 'd-f flex-column justify-content-around',\n Styles.pyramidBoxRight\n )}\n style={rightStyles}\n >\n {sections.map(({ id, title, value, color, prev, data, outlineColor }) => (\n <Stack\n key={title}\n className={Styles.flex1}\n justifyContent=\"center\"\n alignItems=\"center\"\n onMouseEnter={() => setPopoverShown(id)}\n onMouseLeave={hidePopover}\n >\n <Popover open={popoverShown === id} openOnHover placement=\"right\">\n <Popover.Trigger>\n {props => (\n <span {...props}>\n <div className={Styles.percentTextWrapper}>\n <BodyText\n className={classNames(Styles.percentText)}\n data-cy={`marketing-funnel-section-${id}-value`}\n >\n {formatValue(value, format)}\n </BodyText>\n </div>\n </span>\n )}\n </Popover.Trigger>\n <Popover.Content>\n <Stack\n alignItems=\"flex-start\"\n justifyContent=\"flex-start\"\n direction=\"column\"\n data-cy={`marketing-funnel-popover-${id}-content`}\n >\n <Stack>\n <ColorTag\n label=\"\"\n color={color}\n outlineColor={outlineColor}\n pattern={outlineColor ? 'outline' : 'solid'}\n />\n <BodyText bold className=\"m-r-half\">\n {title} {formatValue(value, format)}\n </BodyText>\n </Stack>\n <Stack.Item>\n <StatDiff\n value={value}\n prev={prev}\n size=\"xsmall\"\n format={format}\n />\n </Stack.Item>\n </Stack>\n\n {!!PopoverContent && (\n <PopoverContent\n id={id}\n value={value}\n text={formatValue(value, format)}\n data={data}\n />\n )}\n </Popover.Content>\n </Popover>\n </Stack>\n ))}\n </div>\n <div className={Styles.pyramidBoxLeft} style={{ width: `${100 - topSideLength}%` }}>\n {sections.map((s, i) => {\n const y = rowYs[i] ?? 0;\n const TITLE_UP = 24;\n const DIFF_DOWN = 4;\n\n return (\n <Fragment key={s.id}>\n <div\n className={Styles.leftTitle}\n style={{ top: `calc(${y}% - ${TITLE_UP}px)` }}\n >\n <Eyebrow\n size=\"small\"\n className={classNames(Styles.statTitle, 'm-r-half')}\n >\n {s.title}\n </Eyebrow>\n <Tooltip direction=\"t\" portal text={s.description}>\n <Icon\n name=\"info\"\n className=\"m-r-1\"\n size=\"14px\"\n color={tokens.colorNeutral90}\n />\n </Tooltip>\n </div>\n\n <div\n className={Styles.leftDiff}\n style={{ top: `calc(${y}% + ${DIFF_DOWN}px)` }}\n >\n <StatDiff\n value={s.value}\n prev={s.prev}\n size=\"small\"\n format={format}\n />\n </div>\n </Fragment>\n );\n })}\n </div>\n </Mask>\n );\n};\n"],"names":["useMemo","useState","Fragment","classNames","BodyText","Eyebrow","Icon","Mask","Stack","Tooltip","tokens","formatValue","StatDiff","defaultBottomSideLength","defaultTopSideLength","FunnelPyramidSvg","Styles","Popover","ColorTag","FunnelChart","sections","format","topSideLength","bottomSideLength","popoverContent","PopoverContent","loading","className","popoverShown","setPopoverShown","undefined","rowYs","setRowYs","colors","map","s","color","outlineColors","outlineColor","hidePopover","rightStyles","left","active","div","pyramidWrapper","onRowAnchors","pyramidBoxRight","style","id","title","value","prev","data","flex1","justifyContent","alignItems","onMouseEnter","onMouseLeave","open","openOnHover","placement","Trigger","props","span","percentTextWrapper","percentText","data-cy","Content","direction","label","pattern","bold","Item","size","text","pyramidBoxLeft","width","i","y","TITLE_UP","DIFF_DOWN","leftTitle","top","statTitle","portal","description","name","colorNeutral90","leftDiff"],"mappings":"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"}
@@ -18,10 +18,11 @@ export const Body = provide({
18
18
  SvgStore
19
19
  ]
20
20
  })(observer(({ classNameTitle })=>{
21
+ var _ref, _ref1, _ref2;
21
22
  const [{ display, metrics, left, right, periods, resolution, setHoveredIndex }, svgStore] = useDependencies(LineChartStore, SvgStore);
22
23
  useEffect(()=>{
23
- var _left_maxValue, _right_maxValue;
24
- svgStore.init(periods.length, metrics, (_left_maxValue = left === null || left === void 0 ? void 0 : left.maxValue) !== null && _left_maxValue !== void 0 ? _left_maxValue : 0, (_right_maxValue = right === null || right === void 0 ? void 0 : right.maxValue) !== null && _right_maxValue !== void 0 ? _right_maxValue : 0);
24
+ var _ref, _ref1;
25
+ svgStore.init(periods.length, metrics, (_ref = left === null || left === void 0 ? void 0 : left.maxValue) !== null && _ref !== void 0 ? _ref : 0, (_ref1 = right === null || right === void 0 ? void 0 : right.maxValue) !== null && _ref1 !== void 0 ? _ref1 : 0);
25
26
  }, [
26
27
  svgStore,
27
28
  periods,
@@ -37,15 +38,14 @@ export const Body = provide({
37
38
  setHoveredIndex
38
39
  ]);
39
40
  const labels = useMemo(()=>{
40
- var _rect_width;
41
- return display.xLabels ? getXLabels(periods, resolution, (_rect_width = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _rect_width !== void 0 ? _rect_width : 0) : [];
41
+ var _ref;
42
+ return display.xLabels ? getXLabels(periods, resolution, (_ref = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _ref !== void 0 ? _ref : 0) : [];
42
43
  }, [
43
44
  display,
44
45
  periods,
45
46
  resolution,
46
47
  rect
47
48
  ]);
48
- var _rect_width, _left_width, _right_width;
49
49
  return /*#__PURE__*/ _jsxs("div", {
50
50
  className: "d-f flex-column",
51
51
  children: [
@@ -104,9 +104,9 @@ export const Body = provide({
104
104
  }),
105
105
  display.xLabels && /*#__PURE__*/ _jsx(XAxisLabels, {
106
106
  labels: labels,
107
- width: (_rect_width = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _rect_width !== void 0 ? _rect_width : 0,
108
- left: (_left_width = left === null || left === void 0 ? void 0 : left.width) !== null && _left_width !== void 0 ? _left_width : 0,
109
- right: (_right_width = right === null || right === void 0 ? void 0 : right.width) !== null && _right_width !== void 0 ? _right_width : 0,
107
+ width: (_ref = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _ref !== void 0 ? _ref : 0,
108
+ left: (_ref1 = left === null || left === void 0 ? void 0 : left.width) !== null && _ref1 !== void 0 ? _ref1 : 0,
109
+ right: (_ref2 = right === null || right === void 0 ? void 0 : right.width) !== null && _ref2 !== void 0 ? _ref2 : 0,
110
110
  labelsMerged: periods.length !== labels.length,
111
111
  hasBars: !!metrics.filter((m)=>m.type === 'bar' || m.type === 'stacked-bar' || m.type === 'grouped-bar').length
112
112
  }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/body.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, FC, Fragment } from 'react';\nimport { observer } from 'mobx-react';\nimport classNames from 'classnames';\nimport { Stack } from '@servicetitan/design-system';\nimport { provide, useDependencies } from '@servicetitan/react-ioc';\n\nimport { useClientRect } from '../../../../utils/use-client-rect';\nimport { LineChartStore } from '../stores/line-chart.store';\nimport { SvgStore } from '../stores/svg.store';\nimport { getXLabels } from '../utils/labels';\n\nimport { Sidebar } from './sidebar';\nimport { MetricsTitle, XAxisLabels } from './stuff';\nimport { SvgBody, SvgBodyHover } from './svg-body';\nimport { HoverPopover } from './hover-popover';\nimport * as Styles from './body.module.less';\n\nexport const Body: FC<{ classNameTitle?: string }> = provide({ singletons: [SvgStore] })(\n observer(({ classNameTitle }) => {\n const [{ display, metrics, left, right, periods, resolution, setHoveredIndex }, svgStore] =\n useDependencies(LineChartStore, SvgStore);\n\n useEffect(() => {\n svgStore.init(periods.length, metrics, left?.maxValue ?? 0, right?.maxValue ?? 0);\n }, [svgStore, periods, metrics, left, right]);\n const [rect, ref] = useClientRect();\n\n const onBarHover = useCallback(\n (ind: number) => setHoveredIndex(ind, true),\n [setHoveredIndex]\n );\n\n const onBarLeave = useCallback(\n (ind: number) => setHoveredIndex(ind, false),\n [setHoveredIndex]\n );\n\n const labels = useMemo(\n () => (display.xLabels ? getXLabels(periods, resolution, rect?.width ?? 0) : []),\n [display, periods, resolution, rect]\n );\n\n return (\n <div className=\"d-f flex-column\">\n <Stack alignItems=\"stretch\">\n {left && <Sidebar settings={left} classNameTitle={classNameTitle} />}\n <Stack.Item fill>\n <div\n ref={ref}\n className={classNames(Styles.chartWrapper, 'border-bottom', {\n 'border-left': !!left && display.yLeft,\n 'border-right': !!right && display.yRight,\n })}\n >\n {periods.length ? (\n <Fragment>\n {periods.length !== labels.length && (\n <div className={Styles.labelBorders}>\n {labels\n .map(([text, flex], ind) => [flex, `${ind}${text}`])\n .map(([flex, key]) => (\n <div key={key} style={{ flex }} />\n ))}\n </div>\n )}\n\n <SvgBody horizontalGrid={display.yGrid} metrics={metrics} />\n <HoverPopover />\n <SvgBodyHover\n onValueHover={onBarHover}\n onValueLeave={onBarLeave}\n />\n </Fragment>\n ) : (\n <Stack\n className=\"h-100\"\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n No Data\n </Stack>\n )}\n </div>\n </Stack.Item>\n {right && <Sidebar settings={right} right classNameTitle={classNameTitle} />}\n </Stack>\n {display.xLabels && (\n <XAxisLabels\n labels={labels}\n width={rect?.width ?? 0}\n left={left?.width ?? 0}\n right={right?.width ?? 0}\n labelsMerged={periods.length !== labels.length}\n hasBars={\n !!metrics.filter(\n m =>\n m.type === 'bar' ||\n m.type === 'stacked-bar' ||\n m.type === 'grouped-bar'\n ).length\n }\n />\n )}\n {display.metricsTitlePosition === 'bottom' && (\n <Stack direction=\"row\" justifyContent=\"flex-start\" className=\"p-t-3 p-x-5\">\n <MetricsTitle metrics={metrics} />\n </Stack>\n )}\n </div>\n );\n })\n);\n"],"names":["useCallback","useEffect","useMemo","Fragment","observer","classNames","Stack","provide","useDependencies","useClientRect","LineChartStore","SvgStore","getXLabels","Sidebar","MetricsTitle","XAxisLabels","SvgBody","SvgBodyHover","HoverPopover","Styles","Body","singletons","classNameTitle","display","metrics","left","right","periods","resolution","setHoveredIndex","svgStore","init","length","maxValue","rect","ref","onBarHover","ind","onBarLeave","labels","xLabels","width","div","className","alignItems","settings","Item","fill","chartWrapper","yLeft","yRight","labelBorders","map","text","flex","key","style","horizontalGrid","yGrid","onValueHover","onValueLeave","justifyContent","labelsMerged","hasBars","filter","m","type","metricsTitlePosition","direction"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/body.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, FC, Fragment } from 'react';\nimport { observer } from 'mobx-react';\nimport classNames from 'classnames';\nimport { Stack } from '@servicetitan/design-system';\nimport { provide, useDependencies } from '@servicetitan/react-ioc';\n\nimport { useClientRect } from '../../../../utils/use-client-rect';\nimport { LineChartStore } from '../stores/line-chart.store';\nimport { SvgStore } from '../stores/svg.store';\nimport { getXLabels } from '../utils/labels';\n\nimport { Sidebar } from './sidebar';\nimport { MetricsTitle, XAxisLabels } from './stuff';\nimport { SvgBody, SvgBodyHover } from './svg-body';\nimport { HoverPopover } from './hover-popover';\nimport * as Styles from './body.module.less';\n\nexport const Body: FC<{ classNameTitle?: string }> = provide({ singletons: [SvgStore] })(\n observer(({ classNameTitle }) => {\n const [{ display, metrics, left, right, periods, resolution, setHoveredIndex }, svgStore] =\n useDependencies(LineChartStore, SvgStore);\n\n useEffect(() => {\n svgStore.init(periods.length, metrics, left?.maxValue ?? 0, right?.maxValue ?? 0);\n }, [svgStore, periods, metrics, left, right]);\n const [rect, ref] = useClientRect();\n\n const onBarHover = useCallback(\n (ind: number) => setHoveredIndex(ind, true),\n [setHoveredIndex]\n );\n\n const onBarLeave = useCallback(\n (ind: number) => setHoveredIndex(ind, false),\n [setHoveredIndex]\n );\n\n const labels = useMemo(\n () => (display.xLabels ? getXLabels(periods, resolution, rect?.width ?? 0) : []),\n [display, periods, resolution, rect]\n );\n\n return (\n <div className=\"d-f flex-column\">\n <Stack alignItems=\"stretch\">\n {left && <Sidebar settings={left} classNameTitle={classNameTitle} />}\n <Stack.Item fill>\n <div\n ref={ref}\n className={classNames(Styles.chartWrapper, 'border-bottom', {\n 'border-left': !!left && display.yLeft,\n 'border-right': !!right && display.yRight,\n })}\n >\n {periods.length ? (\n <Fragment>\n {periods.length !== labels.length && (\n <div className={Styles.labelBorders}>\n {labels\n .map(([text, flex], ind) => [flex, `${ind}${text}`])\n .map(([flex, key]) => (\n <div key={key} style={{ flex }} />\n ))}\n </div>\n )}\n\n <SvgBody horizontalGrid={display.yGrid} metrics={metrics} />\n <HoverPopover />\n <SvgBodyHover\n onValueHover={onBarHover}\n onValueLeave={onBarLeave}\n />\n </Fragment>\n ) : (\n <Stack\n className=\"h-100\"\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n No Data\n </Stack>\n )}\n </div>\n </Stack.Item>\n {right && <Sidebar settings={right} right classNameTitle={classNameTitle} />}\n </Stack>\n {display.xLabels && (\n <XAxisLabels\n labels={labels}\n width={rect?.width ?? 0}\n left={left?.width ?? 0}\n right={right?.width ?? 0}\n labelsMerged={periods.length !== labels.length}\n hasBars={\n !!metrics.filter(\n m =>\n m.type === 'bar' ||\n m.type === 'stacked-bar' ||\n m.type === 'grouped-bar'\n ).length\n }\n />\n )}\n {display.metricsTitlePosition === 'bottom' && (\n <Stack direction=\"row\" justifyContent=\"flex-start\" className=\"p-t-3 p-x-5\">\n <MetricsTitle metrics={metrics} />\n </Stack>\n )}\n </div>\n );\n })\n);\n"],"names":["useCallback","useEffect","useMemo","Fragment","observer","classNames","Stack","provide","useDependencies","useClientRect","LineChartStore","SvgStore","getXLabels","Sidebar","MetricsTitle","XAxisLabels","SvgBody","SvgBodyHover","HoverPopover","Styles","Body","singletons","classNameTitle","display","metrics","left","right","periods","resolution","setHoveredIndex","svgStore","init","length","maxValue","rect","ref","onBarHover","ind","onBarLeave","labels","xLabels","width","div","className","alignItems","settings","Item","fill","chartWrapper","yLeft","yRight","labelBorders","map","text","flex","key","style","horizontalGrid","yGrid","onValueHover","onValueLeave","justifyContent","labelsMerged","hasBars","filter","m","type","metricsTitlePosition","direction"],"mappings":"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"}
@@ -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,EAA2D,EAAE,EAAiB,MAAM,OAAO,CAAC;AAgBnG,eAAO,MAAM,YAAY,EAAE,EAuHzB,CAAC"}
1
+ {"version":3,"file":"hover-popover.d.ts","sourceRoot":"","sources":["../../../../../src/components/charts/line-chart/components/hover-popover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA2D,EAAE,EAAE,MAAM,OAAO,CAAC;AAgBpF,eAAO,MAAM,YAAY,EAAE,EAkIzB,CAAC"}
@@ -38,24 +38,30 @@ export const HoverPopover = observer(()=>{
38
38
  display,
39
39
  popH
40
40
  ]);
41
- const popoverStyle = useMemo(()=>{
41
+ const { popoverStyle, arrowPosition } = useMemo(()=>{
42
42
  const posX = svgStore.periodX(hoveredIndex);
43
43
  const yHeights = metrics.filter((m)=>m.values[hoveredIndex] !== undefined).map((m)=>svgStore.periodY(m, hoveredIndex));
44
44
  const barHeight = yHeights.length ? stackedTotals ? yHeights.reduce((a, b)=>a + b, 0) : Math.max(...yHeights) : 0;
45
45
  const barHeightPercentRaw = svgStore.fpy(Math.max(0, Math.min(100, barHeight)));
46
46
  const barHeightPercent = Math.max(0, Math.min(100, Number(barHeightPercentRaw) || 0));
47
- const barTopPositionPx = barHeightPercent / 100 * CHART_HEIGHT_PX;
48
- const availableSpaceBelow = Math.max(0, CHART_HEIGHT_PX - barTopPositionPx - popH);
49
- const popoverOffsetPx = Math.min(OFFSET_PX, availableSpaceBelow);
47
+ const barTopPx = barHeightPercent / 100 * CHART_HEIGHT_PX;
48
+ const idealTopPx = barTopPx + OFFSET_PX;
49
+ const maxTopPx = Math.max(0, CHART_HEIGHT_PX - popH);
50
+ const popoverRepositioned = idealTopPx > maxTopPx;
51
+ const clampedTopPx = Math.min(idealTopPx, maxTopPx);
52
+ const topPercent = clampedTopPx / CHART_HEIGHT_PX * 100;
50
53
  return {
51
- top: `${barHeightPercent}%`,
52
- transform: `translateY(${popoverOffsetPx}px)`,
53
- position: 'absolute',
54
- ...isChartLeftSide ? {
55
- left: `${svgStore.fpx(posX + 2)}%`
56
- } : {
57
- right: `${svgStore.fpx(102 - posX)}%`
58
- }
54
+ popoverStyle: {
55
+ top: `${topPercent.toFixed(1)}%`,
56
+ transform: 'translateY(0)',
57
+ position: 'absolute',
58
+ ...isChartLeftSide ? {
59
+ left: `${svgStore.fpx(posX + 2)}%`
60
+ } : {
61
+ right: `${svgStore.fpx(102 - posX)}%`
62
+ }
63
+ },
64
+ arrowPosition: popoverRepositioned ? 'bottom' : 'top'
59
65
  };
60
66
  }, [
61
67
  svgStore,
@@ -68,6 +74,9 @@ export const HoverPopover = observer(()=>{
68
74
  if (hoveredIndex < 0 || hoveredIndex >= periods.length) {
69
75
  return null;
70
76
  }
77
+ if ((stackedTotals === null || stackedTotals === void 0 ? void 0 : stackedTotals[hoveredIndex]) === 0) {
78
+ return null;
79
+ }
71
80
  const period = periods[hoveredIndex];
72
81
  const partialWeek = !!period.partial;
73
82
  return /*#__PURE__*/ _jsxs("div", {
@@ -76,7 +85,7 @@ export const HoverPopover = observer(()=>{
76
85
  style: popoverStyle,
77
86
  children: [
78
87
  /*#__PURE__*/ _jsx("div", {
79
- className: classNames(Styles.arrow, isChartLeftSide ? Styles.arrowLeft : Styles.arrowRight)
88
+ className: classNames(Styles.arrow, isChartLeftSide ? Styles.arrowLeft : Styles.arrowRight, arrowPosition === 'bottom' && Styles.arrowBottom)
80
89
  }),
81
90
  /*#__PURE__*/ _jsx(Text, {
82
91
  size: "small",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/hover-popover.tsx"],"sourcesContent":["import { useCallback, useMemo, useRef, useLayoutEffect, useState, FC, CSSProperties } 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\nconst CHART_HEIGHT_PX = 400;\nconst OFFSET_PX = 16;\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 const isChartLeftSide = hoveredIndex < periods.length / 2;\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\n const popRef = useRef<HTMLDivElement | null>(null);\n const [popH, setPopH] = useState(0);\n\n useLayoutEffect(() => {\n if (!popRef.current) {\n return;\n }\n const rect = popRef.current.getBoundingClientRect();\n if (rect.height && Math.abs(rect.height - popH) > 0.5) {\n setPopH(rect.height);\n }\n }, [hoveredIndex, metrics, display, popH]);\n\n const popoverStyle = useMemo<CSSProperties>(() => {\n const posX = svgStore.periodX(hoveredIndex);\n\n const yHeights = metrics\n .filter(m => m.values[hoveredIndex] !== undefined)\n .map(m => svgStore.periodY(m, hoveredIndex));\n\n const barHeight = yHeights.length\n ? stackedTotals\n ? yHeights.reduce((a, b) => a + b, 0)\n : Math.max(...yHeights)\n : 0;\n const barHeightPercentRaw = svgStore.fpy(Math.max(0, Math.min(100, barHeight)));\n const barHeightPercent = Math.max(0, Math.min(100, Number(barHeightPercentRaw) || 0));\n\n const barTopPositionPx = (barHeightPercent / 100) * CHART_HEIGHT_PX;\n const availableSpaceBelow = Math.max(0, CHART_HEIGHT_PX - barTopPositionPx - popH);\n const popoverOffsetPx = Math.min(OFFSET_PX, availableSpaceBelow);\n\n return {\n top: `${barHeightPercent}%`,\n transform: `translateY(${popoverOffsetPx}px)`,\n position: 'absolute',\n ...(isChartLeftSide\n ? { left: `${svgStore.fpx(posX + 2)}%` }\n : { right: `${svgStore.fpx(102 - posX)}%` }),\n };\n }, [svgStore, hoveredIndex, isChartLeftSide, metrics, stackedTotals, popH]);\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 <div\n ref={popRef}\n className={classNames(Styles.popover, 'border border-radius-1 p-1')}\n style={popoverStyle}\n >\n <div\n className={classNames(\n Styles.arrow,\n isChartLeftSide ? Styles.arrowLeft : Styles.arrowRight\n )}\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 );\n});\n"],"names":["useCallback","useMemo","useRef","useLayoutEffect","useState","classNames","observer","useDependencies","BodyText","LineChartStore","SvgStore","getFormatter","periodDateTitleFormatter","Styles","ColorTag","Text","CHART_HEIGHT_PX","OFFSET_PX","HoverPopover","periods","resolution","hoveredIndex","metrics","display","formattedTotalAt","totalLabel","stackedTotals","svgStore","isChartLeftSide","length","formatDateTitle","formatValue","title","value","isRight","metricsRightFormat","metricsLeftFormat","popRef","popH","setPopH","current","rect","getBoundingClientRect","height","Math","abs","popoverStyle","posX","periodX","yHeights","filter","m","values","undefined","map","periodY","barHeight","reduce","a","b","max","barHeightPercentRaw","fpy","min","barHeightPercent","Number","barTopPositionPx","availableSpaceBelow","popoverOffsetPx","top","transform","position","left","fpx","right","period","partialWeek","partial","div","ref","className","popover","style","arrow","arrowLeft","arrowRight","size","variant","el","subdued","small","label","color","dashed","opts","pattern","outlineColor","strokeColor","colorTagClassName","colorTagOutlined","colorTag"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/hover-popover.tsx"],"sourcesContent":["import { useCallback, useMemo, useRef, useLayoutEffect, useState, FC } 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\nconst CHART_HEIGHT_PX = 400;\nconst OFFSET_PX = 16;\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 const isChartLeftSide = hoveredIndex < periods.length / 2;\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\n const popRef = useRef<HTMLDivElement | null>(null);\n const [popH, setPopH] = useState(0);\n\n useLayoutEffect(() => {\n if (!popRef.current) {\n return;\n }\n const rect = popRef.current.getBoundingClientRect();\n if (rect.height && Math.abs(rect.height - popH) > 0.5) {\n setPopH(rect.height);\n }\n }, [hoveredIndex, metrics, display, popH]);\n\n const { popoverStyle, arrowPosition } = useMemo(() => {\n const posX = svgStore.periodX(hoveredIndex);\n\n const yHeights = metrics\n .filter(m => m.values[hoveredIndex] !== undefined)\n .map(m => svgStore.periodY(m, hoveredIndex));\n\n const barHeight = yHeights.length\n ? stackedTotals\n ? yHeights.reduce((a, b) => a + b, 0)\n : Math.max(...yHeights)\n : 0;\n const barHeightPercentRaw = svgStore.fpy(Math.max(0, Math.min(100, barHeight)));\n const barHeightPercent = Math.max(0, Math.min(100, Number(barHeightPercentRaw) || 0));\n\n const barTopPx = (barHeightPercent / 100) * CHART_HEIGHT_PX;\n const idealTopPx = barTopPx + OFFSET_PX;\n const maxTopPx = Math.max(0, CHART_HEIGHT_PX - popH);\n const popoverRepositioned = idealTopPx > maxTopPx;\n const clampedTopPx = Math.min(idealTopPx, maxTopPx);\n const topPercent = (clampedTopPx / CHART_HEIGHT_PX) * 100;\n\n return {\n popoverStyle: {\n top: `${topPercent.toFixed(1)}%`,\n transform: 'translateY(0)',\n position: 'absolute' as const,\n ...(isChartLeftSide\n ? { left: `${svgStore.fpx(posX + 2)}%` }\n : { right: `${svgStore.fpx(102 - posX)}%` }),\n },\n arrowPosition: popoverRepositioned ? 'bottom' : 'top',\n };\n }, [svgStore, hoveredIndex, isChartLeftSide, metrics, stackedTotals, popH]);\n\n if (hoveredIndex < 0 || hoveredIndex >= periods.length) {\n return null;\n }\n\n if (stackedTotals?.[hoveredIndex] === 0) {\n return null;\n }\n\n const period = periods[hoveredIndex]!;\n const partialWeek = !!period.partial;\n\n return (\n <div\n ref={popRef}\n className={classNames(Styles.popover, 'border border-radius-1 p-1')}\n style={popoverStyle}\n >\n <div\n className={classNames(\n Styles.arrow,\n isChartLeftSide ? Styles.arrowLeft : Styles.arrowRight,\n arrowPosition === 'bottom' && Styles.arrowBottom\n )}\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 );\n});\n"],"names":["useCallback","useMemo","useRef","useLayoutEffect","useState","classNames","observer","useDependencies","BodyText","LineChartStore","SvgStore","getFormatter","periodDateTitleFormatter","Styles","ColorTag","Text","CHART_HEIGHT_PX","OFFSET_PX","HoverPopover","periods","resolution","hoveredIndex","metrics","display","formattedTotalAt","totalLabel","stackedTotals","svgStore","isChartLeftSide","length","formatDateTitle","formatValue","title","value","isRight","metricsRightFormat","metricsLeftFormat","popRef","popH","setPopH","current","rect","getBoundingClientRect","height","Math","abs","popoverStyle","arrowPosition","posX","periodX","yHeights","filter","m","values","undefined","map","periodY","barHeight","reduce","a","b","max","barHeightPercentRaw","fpy","min","barHeightPercent","Number","barTopPx","idealTopPx","maxTopPx","popoverRepositioned","clampedTopPx","topPercent","top","toFixed","transform","position","left","fpx","right","period","partialWeek","partial","div","ref","className","popover","style","arrow","arrowLeft","arrowRight","arrowBottom","size","variant","el","subdued","small","label","color","dashed","opts","pattern","outlineColor","strokeColor","colorTagClassName","colorTagOutlined","colorTag"],"mappings":"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"}
@@ -44,6 +44,11 @@
44
44
  transform: rotate(135deg);
45
45
  }
46
46
 
47
+ .arrow-bottom {
48
+ top: auto;
49
+ bottom: 12px;
50
+ }
51
+
47
52
  .color-tag {
48
53
  width: 20px;
49
54
  height: 6px;
@@ -1,5 +1,6 @@
1
1
  export const __esModule: true;
2
2
  export const arrow: string;
3
+ export const arrowBottom: string;
3
4
  export const arrowLeft: string;
4
5
  export const arrowRight: string;
5
6
  export const colorTag: string;
@@ -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,CAuMpC,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"}
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,CAsLpC,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"}
@@ -41,11 +41,11 @@ export const SvgBars = observer(({ metrics, isStackedBarChart, isGroupedBarChart
41
41
  for(let i = 0; i < length; i++){
42
42
  const x = store.periodX(i);
43
43
  const values = metrics.map((m)=>{
44
+ var _ref;
44
45
  var _m_valuesOpts_i, _m_valuesOpts, _m_opts, _m_opts1, _m_opts2;
45
- var _m_valuesOpts_i_color;
46
46
  return {
47
47
  id: m.id,
48
- color: (_m_valuesOpts_i_color = (_m_valuesOpts = m.valuesOpts) === null || _m_valuesOpts === void 0 ? void 0 : (_m_valuesOpts_i = _m_valuesOpts[i]) === null || _m_valuesOpts_i === void 0 ? void 0 : _m_valuesOpts_i.color) !== null && _m_valuesOpts_i_color !== void 0 ? _m_valuesOpts_i_color : m.color,
48
+ color: (_ref = (_m_valuesOpts = m.valuesOpts) === null || _m_valuesOpts === void 0 ? void 0 : (_m_valuesOpts_i = _m_valuesOpts[i]) === null || _m_valuesOpts_i === void 0 ? void 0 : _m_valuesOpts_i.color) !== null && _ref !== void 0 ? _ref : m.color,
49
49
  opacity: m.opacity,
50
50
  val: store.periodY(m, i),
51
51
  pattern: (_m_opts = m.opts) === null || _m_opts === void 0 ? void 0 : _m_opts.pattern,
@@ -55,23 +55,13 @@ export const SvgBars = observer(({ metrics, isStackedBarChart, isGroupedBarChart
55
55
  };
56
56
  });
57
57
  if (isStackedBarChart) {
58
- // Use ORIGINAL calculations - keep all spacing/positioning unchanged
59
58
  const spacingBetweenSegments = 1;
60
- const totalSpacing = (values.length - 1) * spacingBetweenSegments;
61
- let stackedBarHeight = values.reduce((sum, curr)=>sum + curr.val, 0) + totalSpacing;
62
- // Find first/last non-zero indices for visual styling
59
+ const totalValue = values.reduce((sum, curr)=>sum + curr.value, 0);
60
+ const totalYValue = values.reduce((sum, curr)=>sum + curr.val, 0);
63
61
  const firstNonZeroIdx = values.findIndex((v)=>v.value > 0);
64
62
  const lastNonZeroIdx = values.reduce((last, v, idx)=>v.value > 0 ? idx : last, -1);
65
- // Count 0-value segments below first non-zero (for text position adjustment)
66
- const zeroSegmentsBelowFirst = firstNonZeroIdx >= 0 ? values.slice(firstNonZeroIdx + 1).filter((v)=>v.value <= 0).length : 0;
67
- const totalValue = values.reduce((sum, curr)=>sum + curr.value, 0);
68
63
  if (totalValue > 0) {
69
- /*
70
- * Adjust text position to maintain consistent gap with first rendered segment:
71
- * 1. Subtract spacing for skipped segments from fpy argument
72
- * 2. Add pixel offset for zeros below first non-zero
73
- */ const textStackedBarHeight = stackedBarHeight - (firstNonZeroIdx > 0 ? firstNonZeroIdx : 0) * spacingBetweenSegments;
74
- const yTop = +fpy(textStackedBarHeight) + zeroSegmentsBelowFirst * spacingBetweenSegments;
64
+ const yTop = +fpy(totalYValue) - 2;
75
65
  const scaleX = 0.3;
76
66
  const scaleY = 1;
77
67
  paths.push(/*#__PURE__*/ _jsx("g", {
@@ -93,20 +83,25 @@ export const SvgBars = observer(({ metrics, isStackedBarChart, isGroupedBarChart
93
83
  })
94
84
  }, `total-${i}`));
95
85
  }
86
+ let stackedBarHeight = totalYValue;
87
+ let isFirstRendered = true;
88
+ const nonZeroCount = values.filter((v)=>v.value > 0).length;
89
+ const bottomTrim = Math.max(0, nonZeroCount - 1) * spacingBetweenSegments;
96
90
  for(let j = 0; j < values.length; j++){
91
+ var _value_strokeColor;
97
92
  const value = values[j];
98
- stackedBarHeight -= spacingBetweenSegments;
99
- const TOP_RADIUS = 1;
100
- const xLeft = +fpx(x - barWidth / 2);
101
- const width = +fpx(barWidth);
102
93
  if (value.value <= 0) {
103
- stackedBarHeight -= value.val;
104
94
  continue;
105
95
  }
106
- const zeroSegments = values.slice(j + 1).filter((v)=>v.value <= 0).length;
107
- // Adjust yTop: move down by the space 0-value segments would occupy
108
- const yTop = +fpy(stackedBarHeight) + (values.length - 2) + zeroSegments * spacingBetweenSegments;
109
- const height = j === lastNonZeroIdx ? +fpx(value.val - 2) : +fpx(value.val);
96
+ if (!isFirstRendered) {
97
+ stackedBarHeight -= spacingBetweenSegments;
98
+ }
99
+ isFirstRendered = false;
100
+ const TOP_RADIUS = 1;
101
+ const xLeft = +fpx(x - barWidth / 2);
102
+ const width = +fpx(barWidth);
103
+ const yTop = +fpy(stackedBarHeight);
104
+ const height = j === lastNonZeroIdx ? +fpx(value.val - bottomTrim) : +fpx(value.val);
110
105
  const r = j === firstNonZeroIdx ? TOP_RADIUS : 0;
111
106
  const d = [
112
107
  `M ${xLeft} ${yTop + height}`,
@@ -117,7 +112,6 @@ export const SvgBars = observer(({ metrics, isStackedBarChart, isGroupedBarChart
117
112
  `L ${xLeft + width} ${yTop + height}`,
118
113
  'Z'
119
114
  ].join(' ');
120
- var _value_strokeColor;
121
115
  paths.push(/*#__PURE__*/ _jsx("path", {
122
116
  d: d,
123
117
  fill: value.pattern === 'striped' ? `url(#stripe-pattern-${value.id})` : value.color,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/svg-bars.tsx"],"sourcesContent":["import { FC } from 'react';\nimport { observer } from 'mobx-react';\nimport { useDependencies } from '@servicetitan/react-ioc';\nimport { ChartMetric } from '../utils/internal-interfaces';\nimport { keyVal } from '../utils/key';\nimport { SvgStore } from '../stores/svg.store';\n\ninterface SvgBarsProps {\n metrics: ChartMetric[];\n isStackedBarChart?: boolean;\n isGroupedBarChart?: boolean;\n}\n\nexport const SvgBars: FC<SvgBarsProps> = observer(\n ({ metrics, isStackedBarChart, isGroupedBarChart }) => {\n const [store] = useDependencies(SvgStore);\n const { fpx, fpy, barWidth, length } = store;\n const barWidthHalf = barWidth / 2;\n const paths = [];\n\n const patternDefs = metrics\n .filter(m => m.opts?.pattern === 'striped')\n .map(m => {\n const rotation = 20;\n const tileW = 0.6;\n const tileH = 0.6;\n const stripeWidth = Math.max(0.1, Math.floor(tileW / 20));\n const tintOpacity = 0.06;\n\n return (\n <pattern\n key={`pattern-${m.id}`}\n id={`stripe-pattern-${m.id}`}\n patternUnits=\"userSpaceOnUse\"\n width={tileW}\n height={tileH}\n patternTransform={`rotate(${rotation})`}\n >\n <rect width={tileW} height={tileH} fill={m.color} opacity={tintOpacity} />\n <rect width={stripeWidth} height={tileH} fill={m.color} />\n </pattern>\n );\n });\n\n for (let i = 0; i < length; i++) {\n const x = store.periodX(i);\n const values = metrics.map(m => ({\n id: m.id,\n color: m.valuesOpts?.[i]?.color ?? m.color,\n opacity: m.opacity,\n val: store.periodY(m, i),\n pattern: m.opts?.pattern,\n strokeColor: m.opts?.strokeColor,\n outlineColor: m.opts?.outlineColor,\n value: m.values[i],\n }));\n\n if (isStackedBarChart) {\n // Use ORIGINAL calculations - keep all spacing/positioning unchanged\n const spacingBetweenSegments = 1;\n const totalSpacing = (values.length - 1) * spacingBetweenSegments;\n let stackedBarHeight =\n values.reduce((sum, curr) => sum + curr.val, 0) + totalSpacing;\n\n // Find first/last non-zero indices for visual styling\n const firstNonZeroIdx = values.findIndex(v => v.value > 0);\n const lastNonZeroIdx = values.reduce(\n (last, v, idx) => (v.value > 0 ? idx : last),\n -1\n );\n\n // Count 0-value segments below first non-zero (for text position adjustment)\n const zeroSegmentsBelowFirst =\n firstNonZeroIdx >= 0\n ? values.slice(firstNonZeroIdx + 1).filter(v => v.value <= 0).length\n : 0;\n\n const totalValue = values.reduce((sum, curr) => sum + curr.value, 0);\n if (totalValue > 0) {\n /*\n * Adjust text position to maintain consistent gap with first rendered segment:\n * 1. Subtract spacing for skipped segments from fpy argument\n * 2. Add pixel offset for zeros below first non-zero\n */\n const textStackedBarHeight =\n stackedBarHeight -\n (firstNonZeroIdx > 0 ? firstNonZeroIdx : 0) * spacingBetweenSegments;\n const yTop =\n +fpy(textStackedBarHeight) +\n zeroSegmentsBelowFirst * spacingBetweenSegments;\n const scaleX = 0.3;\n const scaleY = 1;\n\n paths.push(\n <g\n key={`total-${i}`}\n transform={`translate(${x},${yTop}) scale(${scaleX},${scaleY})`}\n pointerEvents=\"none\"\n >\n <text\n x={0}\n y={0}\n textAnchor=\"middle\"\n dominantBaseline=\"alphabetic\"\n fontSize=\"2.5\"\n fontWeight={600}\n fill=\"#111827\"\n stroke=\"white\"\n strokeWidth={0.8}\n paintOrder=\"stroke\"\n fontFamily=\"Nunito Sans\"\n >\n {Math.round(totalValue)}\n </text>\n </g>\n );\n }\n\n for (let j = 0; j < values.length; j++) {\n const value = values[j];\n stackedBarHeight -= spacingBetweenSegments;\n\n const TOP_RADIUS = 1;\n const xLeft = +fpx(x - barWidth / 2);\n const width = +fpx(barWidth);\n\n if (value.value <= 0) {\n stackedBarHeight -= value.val;\n continue;\n }\n const zeroSegments = values.slice(j + 1).filter(v => v.value <= 0).length;\n\n // Adjust yTop: move down by the space 0-value segments would occupy\n const yTop =\n +fpy(stackedBarHeight) +\n (values.length - 2) +\n zeroSegments * spacingBetweenSegments;\n const height = j === lastNonZeroIdx ? +fpx(value.val - 2) : +fpx(value.val);\n const r = j === firstNonZeroIdx ? TOP_RADIUS : 0;\n\n const d = [\n `M ${xLeft} ${yTop + height}`, // bottom-left\n `L ${xLeft} ${yTop + r}`, // up left edge\n `Q ${xLeft} ${yTop} ${xLeft + r / 2} ${yTop}`, // top-left corner\n `L ${xLeft + width - r / 2} ${yTop}`, // across top\n `Q ${xLeft + width} ${yTop} ${xLeft + width} ${yTop + r}`, // top-right corner\n `L ${xLeft + width} ${yTop + height}`, // down right edge\n 'Z',\n ].join(' ');\n paths.push(\n <path\n key={keyVal(value.id, i)}\n d={d}\n fill={\n value.pattern === 'striped'\n ? `url(#stripe-pattern-${value.id})`\n : value.color\n }\n stroke={\n value.pattern === 'outline'\n ? value.outlineColor\n : (value.strokeColor ?? value.color)\n }\n strokeWidth={1}\n vectorEffect=\"non-scaling-stroke\"\n strokeLinejoin=\"round\"\n />\n );\n\n stackedBarHeight -= value.val;\n }\n } else if (isGroupedBarChart) {\n for (let j = 0; j < values.length; j++) {\n const groupedBarX = (j * barWidth) / values.length;\n const value = values[j];\n\n paths.push(\n <rect\n key={keyVal(value.id, i)}\n x={x + groupedBarX - barWidthHalf}\n y={fpy(value.val)}\n width={barWidth / values.length - 0.1}\n height={fpx(value.val)}\n fill={value.color}\n opacity={value.opacity}\n />\n );\n }\n } else {\n values.sort((a, b) => b.val - a.val);\n for (const value of values) {\n paths.push(\n <rect\n key={keyVal(value.id, i)}\n x={fpx(x - barWidthHalf)}\n y={fpy(value.val)}\n width={fpx(barWidth)}\n height={fpx(value.val)}\n fill={value.color}\n />\n );\n }\n }\n }\n\n return (\n <g>\n {patternDefs.length > 0 && <defs>{patternDefs}</defs>}\n {paths}\n </g>\n );\n }\n);\n\ninterface SvgBarsHoverProps {\n onHover(ind: number): void;\n onLeave(ind: number): void;\n}\n\nexport const SvgBarsHover: FC<SvgBarsHoverProps> = observer(({ onHover, onLeave }) => {\n const [store] = useDependencies(SvgStore);\n const { fpx, fpy, barWidth, length } = store;\n const barWidthHalf = barWidth / 2;\n const paths = [];\n\n for (let i = 0; i < length; i++) {\n const x = store.periodX(i);\n\n paths.push(\n <rect\n key={keyVal('_', i)}\n onMouseEnter={() => onHover(i)}\n onMouseLeave={() => onLeave(i)}\n x={fpx(x - barWidthHalf)}\n y={fpy(100)}\n width={fpx(barWidth)}\n height=\"100%\"\n fill=\"white\"\n fillOpacity=\"0\"\n />\n );\n }\n\n return <g>{paths}</g>;\n});\n"],"names":["observer","useDependencies","keyVal","SvgStore","SvgBars","metrics","isStackedBarChart","isGroupedBarChart","store","fpx","fpy","barWidth","length","barWidthHalf","paths","patternDefs","filter","m","opts","pattern","map","rotation","tileW","tileH","stripeWidth","Math","max","floor","tintOpacity","id","patternUnits","width","height","patternTransform","rect","fill","color","opacity","i","x","periodX","values","valuesOpts","val","periodY","strokeColor","outlineColor","value","spacingBetweenSegments","totalSpacing","stackedBarHeight","reduce","sum","curr","firstNonZeroIdx","findIndex","v","lastNonZeroIdx","last","idx","zeroSegmentsBelowFirst","slice","totalValue","textStackedBarHeight","yTop","scaleX","scaleY","push","g","transform","pointerEvents","text","y","textAnchor","dominantBaseline","fontSize","fontWeight","stroke","strokeWidth","paintOrder","fontFamily","round","j","TOP_RADIUS","xLeft","zeroSegments","r","d","join","path","vectorEffect","strokeLinejoin","groupedBarX","sort","a","b","defs","SvgBarsHover","onHover","onLeave","onMouseEnter","onMouseLeave","fillOpacity"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/svg-bars.tsx"],"sourcesContent":["import { FC } from 'react';\nimport { observer } from 'mobx-react';\nimport { useDependencies } from '@servicetitan/react-ioc';\nimport { ChartMetric } from '../utils/internal-interfaces';\nimport { keyVal } from '../utils/key';\nimport { SvgStore } from '../stores/svg.store';\n\ninterface SvgBarsProps {\n metrics: ChartMetric[];\n isStackedBarChart?: boolean;\n isGroupedBarChart?: boolean;\n}\n\nexport const SvgBars: FC<SvgBarsProps> = observer(\n ({ metrics, isStackedBarChart, isGroupedBarChart }) => {\n const [store] = useDependencies(SvgStore);\n const { fpx, fpy, barWidth, length } = store;\n const barWidthHalf = barWidth / 2;\n const paths = [];\n\n const patternDefs = metrics\n .filter(m => m.opts?.pattern === 'striped')\n .map(m => {\n const rotation = 20;\n const tileW = 0.6;\n const tileH = 0.6;\n const stripeWidth = Math.max(0.1, Math.floor(tileW / 20));\n const tintOpacity = 0.06;\n\n return (\n <pattern\n key={`pattern-${m.id}`}\n id={`stripe-pattern-${m.id}`}\n patternUnits=\"userSpaceOnUse\"\n width={tileW}\n height={tileH}\n patternTransform={`rotate(${rotation})`}\n >\n <rect width={tileW} height={tileH} fill={m.color} opacity={tintOpacity} />\n <rect width={stripeWidth} height={tileH} fill={m.color} />\n </pattern>\n );\n });\n\n for (let i = 0; i < length; i++) {\n const x = store.periodX(i);\n const values = metrics.map(m => ({\n id: m.id,\n color: m.valuesOpts?.[i]?.color ?? m.color,\n opacity: m.opacity,\n val: store.periodY(m, i),\n pattern: m.opts?.pattern,\n strokeColor: m.opts?.strokeColor,\n outlineColor: m.opts?.outlineColor,\n value: m.values[i],\n }));\n\n if (isStackedBarChart) {\n const spacingBetweenSegments = 1;\n const totalValue = values.reduce((sum, curr) => sum + curr.value, 0);\n const totalYValue = values.reduce((sum, curr) => sum + curr.val, 0);\n\n const firstNonZeroIdx = values.findIndex(v => v.value > 0);\n const lastNonZeroIdx = values.reduce(\n (last, v, idx) => (v.value > 0 ? idx : last),\n -1\n );\n\n if (totalValue > 0) {\n const yTop = +fpy(totalYValue) - 2;\n const scaleX = 0.3;\n const scaleY = 1;\n\n paths.push(\n <g\n key={`total-${i}`}\n transform={`translate(${x},${yTop}) scale(${scaleX},${scaleY})`}\n pointerEvents=\"none\"\n >\n <text\n x={0}\n y={0}\n textAnchor=\"middle\"\n dominantBaseline=\"alphabetic\"\n fontSize=\"2.5\"\n fontWeight={600}\n fill=\"#111827\"\n stroke=\"white\"\n strokeWidth={0.8}\n paintOrder=\"stroke\"\n fontFamily=\"Nunito Sans\"\n >\n {Math.round(totalValue)}\n </text>\n </g>\n );\n }\n\n let stackedBarHeight = totalYValue;\n let isFirstRendered = true;\n const nonZeroCount = values.filter(v => v.value > 0).length;\n const bottomTrim = Math.max(0, nonZeroCount - 1) * spacingBetweenSegments;\n\n for (let j = 0; j < values.length; j++) {\n const value = values[j];\n\n if (value.value <= 0) {\n continue;\n }\n\n if (!isFirstRendered) {\n stackedBarHeight -= spacingBetweenSegments;\n }\n isFirstRendered = false;\n\n const TOP_RADIUS = 1;\n const xLeft = +fpx(x - barWidth / 2);\n const width = +fpx(barWidth);\n const yTop = +fpy(stackedBarHeight);\n const height =\n j === lastNonZeroIdx ? +fpx(value.val - bottomTrim) : +fpx(value.val);\n const r = j === firstNonZeroIdx ? TOP_RADIUS : 0;\n\n const d = [\n `M ${xLeft} ${yTop + height}`, // bottom-left\n `L ${xLeft} ${yTop + r}`, // up left edge\n `Q ${xLeft} ${yTop} ${xLeft + r / 2} ${yTop}`, // top-left corner\n `L ${xLeft + width - r / 2} ${yTop}`, // across top\n `Q ${xLeft + width} ${yTop} ${xLeft + width} ${yTop + r}`, // top-right corner\n `L ${xLeft + width} ${yTop + height}`, // down right edge\n 'Z',\n ].join(' ');\n paths.push(\n <path\n key={keyVal(value.id, i)}\n d={d}\n fill={\n value.pattern === 'striped'\n ? `url(#stripe-pattern-${value.id})`\n : value.color\n }\n stroke={\n value.pattern === 'outline'\n ? value.outlineColor\n : (value.strokeColor ?? value.color)\n }\n strokeWidth={1}\n vectorEffect=\"non-scaling-stroke\"\n strokeLinejoin=\"round\"\n />\n );\n\n stackedBarHeight -= value.val;\n }\n } else if (isGroupedBarChart) {\n for (let j = 0; j < values.length; j++) {\n const groupedBarX = (j * barWidth) / values.length;\n const value = values[j];\n\n paths.push(\n <rect\n key={keyVal(value.id, i)}\n x={x + groupedBarX - barWidthHalf}\n y={fpy(value.val)}\n width={barWidth / values.length - 0.1}\n height={fpx(value.val)}\n fill={value.color}\n opacity={value.opacity}\n />\n );\n }\n } else {\n values.sort((a, b) => b.val - a.val);\n for (const value of values) {\n paths.push(\n <rect\n key={keyVal(value.id, i)}\n x={fpx(x - barWidthHalf)}\n y={fpy(value.val)}\n width={fpx(barWidth)}\n height={fpx(value.val)}\n fill={value.color}\n />\n );\n }\n }\n }\n\n return (\n <g>\n {patternDefs.length > 0 && <defs>{patternDefs}</defs>}\n {paths}\n </g>\n );\n }\n);\n\ninterface SvgBarsHoverProps {\n onHover(ind: number): void;\n onLeave(ind: number): void;\n}\n\nexport const SvgBarsHover: FC<SvgBarsHoverProps> = observer(({ onHover, onLeave }) => {\n const [store] = useDependencies(SvgStore);\n const { fpx, fpy, barWidth, length } = store;\n const barWidthHalf = barWidth / 2;\n const paths = [];\n\n for (let i = 0; i < length; i++) {\n const x = store.periodX(i);\n\n paths.push(\n <rect\n key={keyVal('_', i)}\n onMouseEnter={() => onHover(i)}\n onMouseLeave={() => onLeave(i)}\n x={fpx(x - barWidthHalf)}\n y={fpy(100)}\n width={fpx(barWidth)}\n height=\"100%\"\n fill=\"white\"\n fillOpacity=\"0\"\n />\n );\n }\n\n return <g>{paths}</g>;\n});\n"],"names":["observer","useDependencies","keyVal","SvgStore","SvgBars","metrics","isStackedBarChart","isGroupedBarChart","store","fpx","fpy","barWidth","length","barWidthHalf","paths","patternDefs","filter","m","opts","pattern","map","rotation","tileW","tileH","stripeWidth","Math","max","floor","tintOpacity","id","patternUnits","width","height","patternTransform","rect","fill","color","opacity","i","x","periodX","values","valuesOpts","val","periodY","strokeColor","outlineColor","value","spacingBetweenSegments","totalValue","reduce","sum","curr","totalYValue","firstNonZeroIdx","findIndex","v","lastNonZeroIdx","last","idx","yTop","scaleX","scaleY","push","g","transform","pointerEvents","text","y","textAnchor","dominantBaseline","fontSize","fontWeight","stroke","strokeWidth","paintOrder","fontFamily","round","stackedBarHeight","isFirstRendered","nonZeroCount","bottomTrim","j","TOP_RADIUS","xLeft","r","d","join","path","vectorEffect","strokeLinejoin","groupedBarX","sort","a","b","defs","SvgBarsHover","onHover","onLeave","onMouseEnter","onMouseLeave","fillOpacity"],"mappings":"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"}
@@ -15,6 +15,7 @@ const SvgLine = ({ color, points, dashed })=>/*#__PURE__*/ _jsx("path", {
15
15
  export const SvgLines = observer(({ metrics })=>{
16
16
  const [store] = useDependencies(SvgStore);
17
17
  const lines = useMemo(()=>metrics.map((m)=>{
18
+ var _ref;
18
19
  var _m_opts;
19
20
  const points = m.values.map((val, ind)=>[
20
21
  store.periodX(ind),
@@ -29,7 +30,6 @@ export const SvgLines = observer(({ metrics })=>{
29
30
  points[l][1] = (x1 * points[l][1] - x2 * points[l - 1][1]) / (x1 - x2);
30
31
  points[l][0] = 100;
31
32
  }
32
- var _m_opts_dashed;
33
33
  return {
34
34
  id: m.id,
35
35
  color: m.color,
@@ -37,7 +37,7 @@ export const SvgLines = observer(({ metrics })=>{
37
37
  store.fpx(x),
38
38
  store.fpy(y)
39
39
  ]),
40
- dashed: (_m_opts_dashed = (_m_opts = m.opts) === null || _m_opts === void 0 ? void 0 : _m_opts.dashed) !== null && _m_opts_dashed !== void 0 ? _m_opts_dashed : false
40
+ dashed: (_ref = (_m_opts = m.opts) === null || _m_opts === void 0 ? void 0 : _m_opts.dashed) !== null && _ref !== void 0 ? _ref : false
41
41
  };
42
42
  }), [
43
43
  store,