@mx-cartographer/experiences 9.4.37 → 9.4.39
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/CHANGELOG.md +8 -0
- package/dist/common/components/ListItemRow.d.ts +1 -1
- package/dist/common/components/ListItemRow.es.js.map +1 -1
- package/dist/common/components/charts/LineChart.d.ts +2 -0
- package/dist/common/components/charts/LineChart.es.js +120 -109
- package/dist/common/components/charts/LineChart.es.js.map +1 -1
- package/dist/core/stores/TrendsStore.d.ts +2 -0
- package/dist/core/stores/TrendsStore.es.js +24 -15
- package/dist/core/stores/TrendsStore.es.js.map +1 -1
- package/dist/trends/TrendsWidget.es.js +131 -128
- package/dist/trends/TrendsWidget.es.js.map +1 -1
- package/dist/trends/components/CategoriesListItem.es.js +34 -29
- package/dist/trends/components/CategoriesListItem.es.js.map +1 -1
- package/dist/trends/components/TrendsChartTotals.es.js +45 -37
- package/dist/trends/components/TrendsChartTotals.es.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [9.4.39] - 09-23-2026
|
|
2
|
+
|
|
3
|
+
- **FIXED** - Trends category rows no longer show a nonzero total with "0 transactions" and no chevron. (MEW-4021)
|
|
4
|
+
|
|
5
|
+
## [9.4.38] - 09-22-2026
|
|
6
|
+
|
|
7
|
+
- **FIXED** - `LineChart` x-axis now shows every tick label instead of dropping overlapping ones, so month labels no longer disappear on small views. On the Trends 1 Year (12-month) view on small screens, labels render as single letters so all twelve fit; the full month is preserved as the accessible name so screen readers and tooltips are unchanged (MEW-4096)
|
|
8
|
+
|
|
1
9
|
## [9.4.37] - 09-22-2026
|
|
2
10
|
|
|
3
11
|
- **FIXED** - Trends Categories "View more"/"View less" toggle now scrolls back into the viewport after the list expands, so keyboard users keep the focused control in view instead of losing track of focus below the fold (MEW-3587)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListItemRow.es.js","names":[],"sources":["../../../src/common/components/ListItemRow.tsx"],"sourcesContent":["import React from 'react'\n\nimport ListItem from '@mui/material/ListItem'\nimport ListItemButton from '@mui/material/ListItemButton'\nimport ListItemIcon from '@mui/material/ListItemIcon'\nimport ListItemText from '@mui/material/ListItemText'\nimport Stack from '@mui/material/Stack'\n\nimport { Text } from '@mxenabled/mxui'\n\ninterface ListItemRowProps {\n onClick?: () => void\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n title?: string\n subtitle?:
|
|
1
|
+
{"version":3,"file":"ListItemRow.es.js","names":[],"sources":["../../../src/common/components/ListItemRow.tsx"],"sourcesContent":["import React from 'react'\n\nimport ListItem from '@mui/material/ListItem'\nimport ListItemButton from '@mui/material/ListItemButton'\nimport ListItemIcon from '@mui/material/ListItemIcon'\nimport ListItemText from '@mui/material/ListItemText'\nimport Stack from '@mui/material/Stack'\n\nimport { Text } from '@mxenabled/mxui'\n\ninterface ListItemRowProps {\n onClick?: () => void\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n title?: string\n subtitle?: React.ReactNode\n rightContent?: React.ReactNode\n titleBold?: boolean\n rightContentBold?: boolean\n}\n\nexport const ListItemRow: React.FC<ListItemRowProps> = ({\n onClick,\n leftIcon,\n rightIcon,\n title,\n subtitle,\n rightContent,\n titleBold = true,\n rightContentBold = true,\n}) => {\n const content = (\n <React.Fragment>\n {leftIcon && <ListItemIcon sx={{ ml: 0 }}>{leftIcon}</ListItemIcon>}\n <ListItemText>\n <Stack\n sx={{\n alignItems: 'center',\n flexDirection: 'row',\n marginLeft: 12,\n }}\n >\n <Stack sx={{ flex: 1, minWidth: 0 }}>\n <Text bold={titleBold} variant=\"body1\">\n {title}\n </Text>\n {subtitle && <Text variant=\"caption\">{subtitle}</Text>}\n </Stack>\n <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 1 }}>\n {rightContent && (\n <Text bold={rightContentBold} display=\"flex\" variant=\"body1\">\n {rightContent}\n </Text>\n )}\n {rightIcon && <ListItemIcon>{rightIcon}</ListItemIcon>}\n </Stack>\n </Stack>\n </ListItemText>\n </React.Fragment>\n )\n\n return (\n <ListItem>\n {onClick ? (\n <ListItemButton\n onClick={onClick}\n sx={{\n py: 14,\n }}\n >\n {content}\n </ListItemButton>\n ) : (\n <Stack\n sx={{\n py: 14,\n px: 24,\n width: '100%',\n flexDirection: 'row',\n alignItems: 'center',\n }}\n >\n {content}\n </Stack>\n )}\n </ListItem>\n )\n}\n"],"mappings":";;;;;;;;AAqBA,IAAa,IAAA,CAA2C,EACtD,SAAA,GACA,UAAA,GACA,WAAA,GACA,OAAA,GACA,UAAA,GACA,cAAA,GACA,WAAA,IAAY,IACZ,kBAAA,IAAmB,GAAA,MACf;AACJ,QAAM,IACJ,gBAAA,EAAC,EAAM,UAAP,EAAA,UAAA,CACG,KAAY,gBAAA,EAAC,GAAD;AAAA,IAAc,IAAI,EAAE,IAAI,EAAE;AAAA,IAAI,UAAA;AAAA,EAAuB,CAAA,GAClE,gBAAA,EAAC,GAAD,EAAA,UACE,gBAAA,EAAC,GAAD;AAAA,IACE,IAAI;AAAA,MACF,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,YAAY;AAAA,IACd;AAAA,IALF,UAAA,CAOE,gBAAA,EAAC,GAAD;AAAA,MAAO,IAAI;AAAA,QAAE,MAAM;AAAA,QAAG,UAAU;AAAA,MAAE;AAAA,MAAlC,UAAA,CACE,gBAAA,EAAC,GAAD;AAAA,QAAM,MAAM;AAAA,QAAW,SAAQ;AAAA,QAC5B,UAAA;AAAA,MACG,CAAA,GACL,KAAY,gBAAA,EAAC,GAAD;AAAA,QAAM,SAAQ;AAAA,QAAW,UAAA;AAAA,MAAe,CAAA,CAChD;AAAA,IACP,CAAA,GAAA,gBAAA,EAAC,GAAD;AAAA,MAAO,IAAI;AAAA,QAAE,eAAe;AAAA,QAAO,YAAY;AAAA,QAAU,KAAK;AAAA,MAAE;AAAA,MAAhE,UAAA,CACG,KACC,gBAAA,EAAC,GAAD;AAAA,QAAM,MAAM;AAAA,QAAkB,SAAQ;AAAA,QAAO,SAAQ;AAAA,QAClD,UAAA;AAAA,MACG,CAAA,GAEP,KAAa,gBAAA,EAAC,GAAD,EAAA,UAAe,EAAwB,CAAA,CAChD;AAAA,IACF,CAAA,CAAA;AAAA,EACK,CAAA,EAAA,CAAA,CACA,EAAA,CAAA;AAGlB,SACE,gBAAA,EAAC,GAAD,EAAA,UACG,IACC,gBAAA,EAAC,GAAD;AAAA,IACW,SAAA;AAAA,IACT,IAAI,EACF,IAAI,GACN;AAAA,IAEC,UAAA;AAAA,EACa,CAAA,IAEhB,gBAAA,EAAC,GAAD;AAAA,IACE,IAAI;AAAA,MACF,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,eAAe;AAAA,MACf,YAAY;AAAA,IACd;AAAA,IAEC,UAAA;AAAA,EACI,CAAA,EAED,CAAA;AAEd"}
|
|
@@ -1,50 +1,59 @@
|
|
|
1
|
-
import { formatCurrency as
|
|
2
|
-
import { stripChartSlotProps as
|
|
3
|
-
import { getMarkerShape as
|
|
4
|
-
import
|
|
5
|
-
import { CustomLine as
|
|
6
|
-
import { CustomMark as
|
|
7
|
-
import { CustomTooltip as
|
|
1
|
+
import { formatCurrency as R, generateEqualIntervals as I } from "../../../core/utils/NumberFormatting.es.js";
|
|
2
|
+
import { stripChartSlotProps as pt } from "./chartSlotProps.es.js";
|
|
3
|
+
import { getMarkerShape as ct } from "./linechart/utils/markerShapes.es.js";
|
|
4
|
+
import ht from "./linechart/CustomLegend.es.js";
|
|
5
|
+
import { CustomLine as yt } from "./linechart/CustomLine.es.js";
|
|
6
|
+
import { CustomMark as ut } from "./linechart/CustomMark.es.js";
|
|
7
|
+
import { CustomTooltip as dt } from "./linechart/CustomTooltip.es.js";
|
|
8
8
|
import "react";
|
|
9
9
|
import { jsx as e, jsxs as d } from "react/jsx-runtime";
|
|
10
|
-
import { useTheme as
|
|
11
|
-
import
|
|
12
|
-
import { BarPlot as
|
|
13
|
-
import { ChartContainer as
|
|
14
|
-
import { ChartsAxisHighlight as
|
|
10
|
+
import { useTheme as xt } from "@mui/material/styles";
|
|
11
|
+
import gt from "@mui/material/Box";
|
|
12
|
+
import { BarPlot as kt } from "@mui/x-charts/BarChart";
|
|
13
|
+
import { ChartContainer as bt } from "@mui/x-charts/ChartContainer";
|
|
14
|
+
import { ChartsAxisHighlight as Lt } from "@mui/x-charts/ChartsAxisHighlight";
|
|
15
|
+
import { ChartsText as S } from "@mui/x-charts/ChartsText";
|
|
15
16
|
import { ChartsReferenceLine as Mt } from "@mui/x-charts/ChartsReferenceLine";
|
|
16
|
-
import { ChartsTooltipContainer as
|
|
17
|
-
import { ChartsXAxis as
|
|
18
|
-
import { ChartsYAxis as
|
|
19
|
-
import { AreaPlot as
|
|
20
|
-
var
|
|
21
|
-
const a =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
import { ChartsTooltipContainer as Tt } from "@mui/x-charts/ChartsTooltip";
|
|
18
|
+
import { ChartsXAxis as Ct } from "@mui/x-charts/ChartsXAxis";
|
|
19
|
+
import { ChartsYAxis as vt } from "@mui/x-charts/ChartsYAxis";
|
|
20
|
+
import { AreaPlot as At, LinePlot as Pt, MarkPlot as Rt } from "@mui/x-charts/LineChart";
|
|
21
|
+
var It = (r) => {
|
|
22
|
+
const a = typeof r.text == "string" ? r.text : "", c = Array.from(a.trim())[0] ?? "";
|
|
23
|
+
return c ? /* @__PURE__ */ e(S, {
|
|
24
|
+
...r,
|
|
25
|
+
"aria-label": a,
|
|
26
|
+
role: "img",
|
|
27
|
+
text: c
|
|
28
|
+
}) : /* @__PURE__ */ e(S, { ...r });
|
|
29
|
+
}, St = { axisTickLabel: It }, Zt = ({ areaColor: r, axisColor: a, baseline: c = "max", chartFor: x, chartXaxisSx: w, chartYaxisSx: O, colors: b, curveType: _ = "linear", customLegendVariant: D, customLegendSx: G, customLegendBoxSx: N, customTooltipLabels: W, datasets: h, height: X, isCurrency: $, isGraphClippingXAxis: j = !1, labels: L, labelBackgroundColor: M, labelFontColor: E, labelFontSize: q, margin: z, markHandlers: H, markStyles: Y, minRange: B, maxRange: J, narrowXAxisLabels: T = !1, showAllXAxisLabels: K = !1, onItemClick: g, peerAverage: C, showArea: v = !1, showAverage: A = !1, showAxisHighlight: Q = !1, showBars: k = !1, showLegend: U = !1, showMark: V = !0, showMarkLabel: Z = !1, showTooltip: F = !1, showXAxis: tt = !1, showXAxisTicks: et = !1, showYAxis: rt = !1, showYAxisTicks: at = !1, title: it, useCustomMark: ot = !1, valueFormatterString: s, width: nt, xAxisScaleType: st }) => {
|
|
30
|
+
const i = xt(), lt = h.flat().map((t) => t.x), o = h.flat().map((t) => t.y), P = C || (o.length ? Math.round(o.reduce((t, l) => l + t, 0) / o.length) : 0), m = o.length ? Math.floor(Math.min(...o) / 100) * 100 : 0, f = o.length ? Math.ceil(Math.max(...o) / 100) * 100 : 0, y = h.map((t, l) => ({
|
|
31
|
+
type: k ? "bar" : "line",
|
|
32
|
+
curve: _,
|
|
33
|
+
color: k ? i.palette.chart?.chart6 : b[l] ?? i.palette.primary.main,
|
|
34
|
+
data: t.map((n) => n.y),
|
|
35
|
+
area: v,
|
|
36
|
+
baseline: c,
|
|
28
37
|
showMark: !0,
|
|
29
|
-
shape:
|
|
30
|
-
valueFormatter: (
|
|
31
|
-
})),
|
|
38
|
+
shape: ct(l),
|
|
39
|
+
valueFormatter: (n) => s ? R(n || 0, s) : String(n)
|
|
40
|
+
})), mt = {
|
|
32
41
|
top: 60,
|
|
33
42
|
right: 35,
|
|
34
43
|
bottom: 25,
|
|
35
44
|
left: -10,
|
|
36
|
-
...
|
|
45
|
+
...z
|
|
37
46
|
};
|
|
38
|
-
let p =
|
|
39
|
-
if (
|
|
40
|
-
const t =
|
|
41
|
-
p =
|
|
47
|
+
let p = B ?? m, u = J ?? f;
|
|
48
|
+
if (x === "networthChart") {
|
|
49
|
+
const t = f - m, l = t < f * 0.05 ? 0.25 : 0.2, n = Math.max(t * l, f * 0.015);
|
|
50
|
+
p = m - n < 0 ? m : m - n, u = f + n;
|
|
42
51
|
}
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
45
|
-
if (
|
|
52
|
+
const ft = () => {
|
|
53
|
+
if (x === "creditOverTime") return I(p, 850, 5);
|
|
54
|
+
if (x === "networthChart") return I(p, u, 5);
|
|
46
55
|
};
|
|
47
|
-
return /* @__PURE__ */ d(
|
|
56
|
+
return /* @__PURE__ */ d(gt, {
|
|
48
57
|
sx: {
|
|
49
58
|
position: "relative",
|
|
50
59
|
touchAction: "pan-y",
|
|
@@ -54,49 +63,50 @@ var Bt = ({ areaColor: f, axisColor: n, baseline: R = "max", chartFor: u, chartX
|
|
|
54
63
|
},
|
|
55
64
|
"& .recharts-wrapper": { touchAction: "pan-y" }
|
|
56
65
|
},
|
|
57
|
-
children: [/* @__PURE__ */ d(
|
|
58
|
-
height:
|
|
59
|
-
margin:
|
|
60
|
-
series:
|
|
66
|
+
children: [/* @__PURE__ */ d(bt, {
|
|
67
|
+
height: X,
|
|
68
|
+
margin: mt,
|
|
69
|
+
series: y,
|
|
61
70
|
sx: {
|
|
62
71
|
"& .MuiBarLabel-root": {
|
|
63
72
|
fontSize: 10,
|
|
64
73
|
fontWeight: 600
|
|
65
74
|
},
|
|
66
75
|
"& .MuiAreaElement-root": { opacity: 0.15 },
|
|
67
|
-
"& .MuiChartsAxis-tickLabel > tspan": { fontFamily:
|
|
68
|
-
"& .MuiLineChart-markLabel": { fontFamily:
|
|
76
|
+
"& .MuiChartsAxis-tickLabel > tspan": { fontFamily: i.typography.body2.fontFamily },
|
|
77
|
+
"& .MuiLineChart-markLabel": { fontFamily: i.typography.body2.fontFamily }
|
|
69
78
|
},
|
|
70
|
-
width:
|
|
79
|
+
width: nt,
|
|
71
80
|
xAxis: [{
|
|
72
|
-
data:
|
|
73
|
-
scaleType:
|
|
81
|
+
data: lt,
|
|
82
|
+
scaleType: st || (k ? "band" : "point"),
|
|
83
|
+
...(K || T) && { tickLabelInterval: () => !0 }
|
|
74
84
|
}],
|
|
75
85
|
yAxis: [{
|
|
76
|
-
tickInterval:
|
|
77
|
-
min:
|
|
78
|
-
max:
|
|
79
|
-
colorMap:
|
|
86
|
+
tickInterval: ft(),
|
|
87
|
+
min: j ? -22 : p,
|
|
88
|
+
max: u || 100,
|
|
89
|
+
colorMap: v && y.length < 2 ? {
|
|
80
90
|
type: "continuous",
|
|
81
91
|
min: p,
|
|
82
|
-
max:
|
|
83
|
-
color: [
|
|
92
|
+
max: u,
|
|
93
|
+
color: [i.palette.background.paper, b[0] ?? i.palette.primary.main]
|
|
84
94
|
} : void 0,
|
|
85
|
-
valueFormatter: (t) =>
|
|
95
|
+
valueFormatter: (t) => s ? R(t, s) : String(t),
|
|
86
96
|
width: 62
|
|
87
97
|
}],
|
|
88
98
|
children: [
|
|
89
|
-
|
|
99
|
+
A && /* @__PURE__ */ e(Mt, {
|
|
90
100
|
lineStyle: {
|
|
91
|
-
stroke:
|
|
101
|
+
stroke: M ? i.palette.neutral.main : i.palette.neutral.dark,
|
|
92
102
|
strokeDasharray: "10, 8",
|
|
93
103
|
strokeWidth: 2
|
|
94
104
|
},
|
|
95
|
-
y:
|
|
105
|
+
y: P
|
|
96
106
|
}),
|
|
97
|
-
/* @__PURE__ */ e(
|
|
98
|
-
onItemClick:
|
|
99
|
-
...
|
|
107
|
+
/* @__PURE__ */ e(At, {
|
|
108
|
+
onItemClick: g,
|
|
109
|
+
...r && { slots: { area: (t) => /* @__PURE__ */ d("g", { children: [/* @__PURE__ */ e("defs", { children: /* @__PURE__ */ d("linearGradient", {
|
|
100
110
|
id: "customGradient",
|
|
101
111
|
x1: "0",
|
|
102
112
|
x2: "0",
|
|
@@ -104,92 +114,93 @@ var Bt = ({ areaColor: f, axisColor: n, baseline: R = "max", chartFor: u, chartX
|
|
|
104
114
|
y2: "1",
|
|
105
115
|
children: [/* @__PURE__ */ e("stop", {
|
|
106
116
|
offset: "0%",
|
|
107
|
-
stopColor:
|
|
117
|
+
stopColor: r
|
|
108
118
|
}), /* @__PURE__ */ e("stop", {
|
|
109
119
|
offset: "100%",
|
|
110
|
-
stopColor:
|
|
120
|
+
stopColor: r,
|
|
111
121
|
stopOpacity: 0.02
|
|
112
122
|
})]
|
|
113
123
|
}) }), /* @__PURE__ */ e("path", {
|
|
114
|
-
...
|
|
124
|
+
...pt(t),
|
|
115
125
|
fill: "url(#customGradient)"
|
|
116
126
|
})] }) } }
|
|
117
127
|
}),
|
|
118
|
-
/* @__PURE__ */ e(
|
|
119
|
-
onItemClick:
|
|
120
|
-
slots: { line: (t) => /* @__PURE__ */ e(
|
|
128
|
+
/* @__PURE__ */ e(Pt, {
|
|
129
|
+
onItemClick: g,
|
|
130
|
+
slots: { line: (t) => /* @__PURE__ */ e(yt, {
|
|
121
131
|
...t,
|
|
122
|
-
lineColor:
|
|
132
|
+
lineColor: r ?? t.ownerState.color ?? i.palette.primary.main
|
|
123
133
|
}) }
|
|
124
134
|
}),
|
|
125
|
-
/* @__PURE__ */ e(
|
|
126
|
-
onItemClick:
|
|
127
|
-
slots:
|
|
128
|
-
handlers:
|
|
129
|
-
labelBackgroundColor:
|
|
130
|
-
labelFontColor:
|
|
131
|
-
labelFontSize:
|
|
132
|
-
showLabel:
|
|
133
|
-
showMark:
|
|
134
|
-
style:
|
|
135
|
-
valueFormatterString:
|
|
136
|
-
yData:
|
|
135
|
+
/* @__PURE__ */ e(Rt, {
|
|
136
|
+
onItemClick: g,
|
|
137
|
+
slots: ot ? { mark: (t) => /* @__PURE__ */ e(ut, {
|
|
138
|
+
handlers: H,
|
|
139
|
+
labelBackgroundColor: M,
|
|
140
|
+
labelFontColor: E,
|
|
141
|
+
labelFontSize: q,
|
|
142
|
+
showLabel: Z,
|
|
143
|
+
showMark: V || t.dataIndex === h[0].length - 1,
|
|
144
|
+
style: Y?.(t.dataIndex) ?? {},
|
|
145
|
+
valueFormatterString: s,
|
|
146
|
+
yData: o,
|
|
137
147
|
...t
|
|
138
148
|
}) } : void 0
|
|
139
149
|
}),
|
|
140
|
-
/* @__PURE__ */ e(
|
|
150
|
+
/* @__PURE__ */ e(kt, {
|
|
141
151
|
barLabel: (t) => Number(t.value) > 0 ? `$${t.value}` : null,
|
|
142
152
|
borderRadius: 10
|
|
143
153
|
}),
|
|
144
|
-
/* @__PURE__ */ e(
|
|
145
|
-
disableLine: !
|
|
146
|
-
disableTicks: !
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
154
|
+
/* @__PURE__ */ e(Ct, {
|
|
155
|
+
disableLine: !tt,
|
|
156
|
+
disableTicks: !et,
|
|
157
|
+
slots: T ? St : void 0,
|
|
158
|
+
slotProps: a ? {
|
|
159
|
+
axisLine: { style: { stroke: a } },
|
|
160
|
+
axisTick: { style: { stroke: a } }
|
|
150
161
|
} : {},
|
|
151
162
|
sx: { ...w }
|
|
152
163
|
}),
|
|
153
|
-
/* @__PURE__ */ e(
|
|
154
|
-
disableLine: !
|
|
155
|
-
disableTicks: !
|
|
156
|
-
slotProps:
|
|
157
|
-
axisLine: { style: { stroke:
|
|
158
|
-
axisTick: { style: { stroke:
|
|
164
|
+
/* @__PURE__ */ e(vt, {
|
|
165
|
+
disableLine: !rt,
|
|
166
|
+
disableTicks: !at,
|
|
167
|
+
slotProps: a ? {
|
|
168
|
+
axisLine: { style: { stroke: a } },
|
|
169
|
+
axisTick: { style: { stroke: a } }
|
|
159
170
|
} : {},
|
|
160
|
-
sx: { ...
|
|
171
|
+
sx: { ...O }
|
|
161
172
|
}),
|
|
162
|
-
|
|
163
|
-
|
|
173
|
+
Q && /* @__PURE__ */ e(Lt, { x: "line" }),
|
|
174
|
+
F && /* @__PURE__ */ e(Tt, {
|
|
164
175
|
trigger: "axis",
|
|
165
|
-
children: /* @__PURE__ */ e(
|
|
166
|
-
customLabels:
|
|
167
|
-
isCurrency:
|
|
168
|
-
labels:
|
|
169
|
-
series:
|
|
170
|
-
valueFormatterString:
|
|
176
|
+
children: /* @__PURE__ */ e(dt, {
|
|
177
|
+
customLabels: W,
|
|
178
|
+
isCurrency: $,
|
|
179
|
+
labels: L,
|
|
180
|
+
series: y,
|
|
181
|
+
valueFormatterString: s
|
|
171
182
|
})
|
|
172
183
|
})
|
|
173
184
|
]
|
|
174
|
-
}),
|
|
175
|
-
average:
|
|
176
|
-
customLegendBoxSx:
|
|
177
|
-
customLegendVariant:
|
|
178
|
-
labels:
|
|
179
|
-
series:
|
|
185
|
+
}), U && /* @__PURE__ */ e(ht, {
|
|
186
|
+
average: A ? P : void 0,
|
|
187
|
+
customLegendBoxSx: N,
|
|
188
|
+
customLegendVariant: D,
|
|
189
|
+
labels: L,
|
|
190
|
+
series: y,
|
|
180
191
|
style: {
|
|
181
192
|
position: "absolute",
|
|
182
193
|
top: 16,
|
|
183
194
|
left: 16,
|
|
184
|
-
|
|
195
|
+
...G
|
|
185
196
|
},
|
|
186
|
-
title:
|
|
187
|
-
valueFormatterString:
|
|
197
|
+
title: it,
|
|
198
|
+
valueFormatterString: s
|
|
188
199
|
})]
|
|
189
200
|
});
|
|
190
201
|
};
|
|
191
202
|
export {
|
|
192
|
-
|
|
203
|
+
Zt as LineChart
|
|
193
204
|
};
|
|
194
205
|
|
|
195
206
|
//# sourceMappingURL=LineChart.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LineChart.es.js","names":[],"sources":["../../../../src/common/components/charts/LineChart.tsx"],"sourcesContent":["import React from 'react'\n\nimport Box from '@mui/material/Box'\nimport type { SxProps } from '@mui/material/styles'\nimport { useTheme } from '@mui/material/styles'\n\nimport type { AllSeriesType } from '@mui/x-charts'\nimport { BarPlot } from '@mui/x-charts/BarChart'\nimport { ChartContainer as ResponsiveChartContainer } from '@mui/x-charts/ChartContainer'\nimport { ChartsAxisHighlight } from '@mui/x-charts/ChartsAxisHighlight'\nimport { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'\nimport { ChartsTooltipContainer } from '@mui/x-charts/ChartsTooltip'\nimport { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'\nimport { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'\nimport { AreaPlot, LinePlot, MarkPlot } from '@mui/x-charts/LineChart'\n\nimport { stripChartSlotProps } from './chartSlotProps'\nimport CustomLegend from './linechart/CustomLegend'\nimport { getMarkerShape } from './linechart/utils/markerShapes'\nimport { CustomLine } from './linechart/CustomLine'\nimport { CustomMark, MarkHandlers } from './linechart/CustomMark'\nimport { CustomTooltip } from './linechart/CustomTooltip'\nimport { formatCurrency } from '../../../core/utils/NumberFormatting'\nimport { generateEqualIntervals } from '../../../core/utils/NumberFormatting'\n\nexport type LineChartDataset = { x: string; y: number }[]\nexport type LineChartLabel = string | { label: string; amount: number }\nexport type TooltipLabel = LineChartLabel & { header?: string }\n\ntype LineChartCurve =\n | 'catmullRom'\n | 'linear'\n | 'monotoneX'\n | 'monotoneY'\n | 'natural'\n | 'step'\n | 'stepBefore'\n | 'stepAfter'\n | 'bump'\n | 'bumpX'\n | 'bumpY'\n\ninterface LineChartProps {\n areaColor?: string\n axisColor?: string\n baseline?: string\n chartFor?: string\n chartXaxisSx?: SxProps\n chartYaxisSx?: SxProps\n // Because theme chart colors are typed string|undefined\n colors: (string | undefined)[]\n curveType?: LineChartCurve\n customLegendVariant?: string\n customLegendSx?: SxProps\n customLegendBoxSx?: SxProps\n customTooltipLabels?: TooltipLabel[][]\n datasets: LineChartDataset[]\n height?: number\n isCurrency?: boolean\n isGraphClippingXAxis?: boolean\n labels: LineChartLabel[]\n labelBackgroundColor?: string\n labelFontColor?: string\n labelFontSize?: number\n margin?: { top?: number; right?: number; bottom?: number; left?: number }\n markHandlers?: MarkHandlers\n markStyles?: (markIndex: number) => React.CSSProperties & {\n markLabelStyles?: React.CSSProperties\n }\n minRange?: number\n maxRange?: number\n onItemClick?: () => void\n peerAverage?: number\n showArea?: boolean\n showAverage?: boolean\n showAxisHighlight?: boolean\n showBars?: boolean\n showLegend?: boolean\n showMark?: boolean\n showMarkLabel?: boolean\n showTooltip?: boolean\n showXAxis?: boolean\n showXAxisTicks?: boolean\n showYAxis?: boolean\n showYAxisTicks?: boolean\n tickIntervals?: any[] | 'auto' | ((value: any, index: number) => boolean) | undefined\n title?: string\n useCustomMark?: boolean\n valueFormatterString?: string\n width?: number\n xAxisScaleType?: 'band' | 'point'\n}\n\n// TODO: Remove negative values and use a proper layout to support X-Charts v8\n\nexport const LineChart: React.FC<LineChartProps> = ({\n areaColor,\n axisColor,\n baseline = 'max',\n chartFor,\n chartXaxisSx,\n chartYaxisSx,\n colors,\n curveType = 'linear',\n customLegendVariant,\n customLegendSx,\n customLegendBoxSx,\n customTooltipLabels,\n datasets,\n height,\n isCurrency,\n isGraphClippingXAxis = false,\n labels,\n labelBackgroundColor,\n labelFontColor,\n labelFontSize,\n margin,\n markHandlers,\n markStyles,\n minRange,\n maxRange,\n onItemClick,\n peerAverage,\n showArea = false,\n showAverage = false,\n showAxisHighlight = false,\n showBars = false,\n showLegend = false,\n showMark = true,\n showMarkLabel = false,\n showTooltip = false,\n showXAxis = false,\n showXAxisTicks = false,\n showYAxis = false,\n showYAxisTicks = false,\n title,\n useCustomMark = false,\n valueFormatterString,\n width,\n xAxisScaleType,\n}) => {\n const theme = useTheme()\n\n // Data for the X axis\n const xData = datasets.flat().map((item) => item.x)\n const yData = datasets.flat().map((item) => item.y)\n\n // Guard the empty-data case: with no points, reduce()/Math.min()/Math.max()\n // produce NaN/±Infinity which flow into the y-axis and make x-charts warn\n // \"the value NaN does not exist in the data of y axis\". Default to 0 so an\n // empty/loading chart renders a valid (flat) axis instead.\n const average = peerAverage\n ? peerAverage\n : yData.length\n ? Math.round(yData.reduce((value, total) => total + value, 0) / yData.length)\n : 0\n\n // Used for the min and max Y axis values\n const yMin = yData.length ? Math.floor(Math.min(...yData) / 100) * 100 : 0\n const yMax = yData.length ? Math.ceil(Math.max(...yData) / 100) * 100 : 0\n\n const series = datasets.map((data, index) => {\n return {\n type: showBars ? 'bar' : 'line',\n curve: curveType,\n color: showBars ? theme.palette.chart?.chart6 : (colors[index] ?? theme.palette.primary.main),\n data: data.map((item) => item.y),\n area: showArea,\n baseline: baseline,\n showMark: true,\n shape: getMarkerShape(index),\n valueFormatter: (value: number) =>\n valueFormatterString ? formatCurrency(value || 0, valueFormatterString) : String(value),\n }\n })\n\n const defaultMargin = {\n top: 60,\n right: 35,\n bottom: 25,\n left: -10,\n }\n\n // Merge default margin with any provided custom margin\n const chartMargin = {\n ...defaultMargin,\n ...margin,\n }\n\n let rangeMin = minRange ?? yMin\n let rangeMax = maxRange ?? yMax\n if (chartFor === 'networthChart') {\n const valueRange = yMax - yMin\n\n const paddingRatio = valueRange < yMax * 0.05 ? 0.25 : 0.2\n const padding = Math.max(valueRange * paddingRatio, yMax * 0.015)\n rangeMin = yMin - padding < 0 ? yMin : yMin - padding\n rangeMax = yMax + padding\n }\n\n const getTickInterval = () => {\n if (chartFor === 'creditOverTime') {\n return generateEqualIntervals(rangeMin, 850, 5)\n } else if (chartFor === 'networthChart') {\n return generateEqualIntervals(rangeMin, rangeMax, 5)\n }\n return undefined\n }\n return (\n <Box\n sx={{\n position: 'relative',\n touchAction: 'pan-y', // Allow vertical scrolling\n '& svg': {\n touchAction: 'pan-y', // Allow vertical scrolling on SVG\n userSelect: 'none', // Prevent text selection\n },\n '& .recharts-wrapper': {\n touchAction: 'pan-y', // For Recharts library specifically\n },\n }}\n >\n <ResponsiveChartContainer\n height={height}\n margin={chartMargin}\n series={series as AllSeriesType[]}\n sx={{\n '& .MuiBarLabel-root': {\n fontSize: 10,\n fontWeight: 600,\n },\n '& .MuiAreaElement-root': {\n opacity: 0.15,\n },\n '& .MuiChartsAxis-tickLabel > tspan': {\n fontFamily: theme.typography.body2.fontFamily,\n },\n '& .MuiLineChart-markLabel': {\n fontFamily: theme.typography.body2.fontFamily,\n },\n }}\n width={width}\n xAxis={[{ data: xData, scaleType: xAxisScaleType || (showBars ? 'band' : 'point') }]}\n yAxis={[\n {\n tickInterval: getTickInterval(),\n min: isGraphClippingXAxis ? -22 : rangeMin,\n max: rangeMax || 100,\n colorMap:\n showArea && series.length < 2\n ? {\n type: 'continuous',\n min: rangeMin,\n max: rangeMax,\n color: [\n theme.palette.background.paper,\n colors[0] ?? theme.palette.primary.main,\n ],\n }\n : undefined,\n valueFormatter: (value: number) =>\n valueFormatterString ? formatCurrency(value, valueFormatterString) : String(value),\n width: 62,\n },\n ]}\n >\n {/** Provides the average line - positioned first to be behind other elements **/}\n {showAverage && (\n <ChartsReferenceLine\n lineStyle={{\n stroke: labelBackgroundColor\n ? theme.palette.neutral.main\n : theme.palette.neutral.dark,\n strokeDasharray: '10, 8',\n strokeWidth: 2,\n }}\n y={average}\n />\n )}\n\n {/** Area plot provides gradiant below the line **/}\n {/* Note: Must be above the LinePlot for some style rules to work */}\n <AreaPlot\n onItemClick={onItemClick}\n {...(areaColor && {\n slots: {\n area: (props) => {\n return (\n <g>\n <defs>\n <linearGradient id=\"customGradient\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={areaColor} />\n <stop offset=\"100%\" stopColor={areaColor} stopOpacity={0.02} />\n </linearGradient>\n </defs>\n <path {...stripChartSlotProps(props)} fill={`url(#customGradient)`} />\n </g>\n )\n },\n },\n })}\n />\n\n {/** Line plot provides the data line **/}\n <LinePlot\n onItemClick={onItemClick}\n slots={{\n line: (props) => (\n <CustomLine\n {...props}\n lineColor={areaColor ?? props.ownerState.color ?? theme.palette.primary.main}\n />\n ),\n }}\n />\n\n {/** Mark plot provides the circles **/}\n <MarkPlot\n onItemClick={onItemClick}\n slots={\n useCustomMark\n ? {\n mark: (props) => {\n return (\n <CustomMark\n handlers={markHandlers}\n labelBackgroundColor={labelBackgroundColor}\n labelFontColor={labelFontColor}\n labelFontSize={labelFontSize}\n showLabel={showMarkLabel}\n showMark={showMark || props.dataIndex === datasets[0].length - 1}\n style={markStyles?.(props.dataIndex) ?? {}}\n valueFormatterString={valueFormatterString}\n yData={yData}\n {...props}\n />\n )\n },\n }\n : undefined\n }\n />\n\n <BarPlot\n barLabel={(item) => (Number(item.value) > 0 ? `$${item.value}` : null)}\n borderRadius={10}\n />\n\n {/** Provides the X axis line and values **/}\n <ChartsXAxis\n disableLine={!showXAxis}\n disableTicks={!showXAxisTicks}\n slotProps={\n axisColor\n ? {\n axisLine: {\n style: {\n stroke: axisColor,\n },\n },\n axisTick: {\n style: {\n stroke: axisColor,\n },\n },\n }\n : {}\n }\n sx={{ ...chartXaxisSx }}\n />\n\n {/** Provides the Y axis values **/}\n <ChartsYAxis\n disableLine={!showYAxis}\n disableTicks={!showYAxisTicks}\n slotProps={\n axisColor\n ? {\n axisLine: {\n style: {\n stroke: axisColor,\n },\n },\n axisTick: {\n style: {\n stroke: axisColor,\n },\n },\n }\n : {}\n }\n sx={{ ...chartYaxisSx }}\n />\n\n {/* Add vertical crosshair on hover */}\n {showAxisHighlight && <ChartsAxisHighlight x=\"line\" />}\n\n {showTooltip && (\n <ChartsTooltipContainer trigger=\"axis\">\n <CustomTooltip\n customLabels={customTooltipLabels}\n isCurrency={isCurrency}\n labels={labels}\n series={series}\n valueFormatterString={valueFormatterString}\n />\n </ChartsTooltipContainer>\n )}\n </ResponsiveChartContainer>\n\n {showLegend && (\n <CustomLegend\n average={showAverage ? average : undefined}\n customLegendBoxSx={customLegendBoxSx}\n customLegendVariant={customLegendVariant}\n labels={labels}\n series={series}\n style={{\n position: 'absolute',\n top: 16,\n left: 16,\n ...customLegendSx,\n }}\n title={title}\n valueFormatterString={valueFormatterString}\n />\n )}\n </Box>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LineChart.es.js","names":[],"sources":["../../../../src/common/components/charts/LineChart.tsx"],"sourcesContent":["import React from 'react'\n\nimport Box from '@mui/material/Box'\nimport type { SxProps } from '@mui/material/styles'\nimport { useTheme } from '@mui/material/styles'\n\nimport type { AllSeriesType } from '@mui/x-charts'\nimport { BarPlot } from '@mui/x-charts/BarChart'\nimport { ChartContainer as ResponsiveChartContainer } from '@mui/x-charts/ChartContainer'\nimport { ChartsAxisHighlight } from '@mui/x-charts/ChartsAxisHighlight'\nimport { ChartsText, type ChartsTextProps } from '@mui/x-charts/ChartsText'\nimport { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'\nimport { ChartsTooltipContainer } from '@mui/x-charts/ChartsTooltip'\nimport { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'\nimport { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'\nimport { AreaPlot, LinePlot, MarkPlot } from '@mui/x-charts/LineChart'\n\nimport { stripChartSlotProps } from './chartSlotProps'\nimport CustomLegend from './linechart/CustomLegend'\nimport { getMarkerShape } from './linechart/utils/markerShapes'\nimport { CustomLine } from './linechart/CustomLine'\nimport { CustomMark, MarkHandlers } from './linechart/CustomMark'\nimport { CustomTooltip } from './linechart/CustomTooltip'\nimport { formatCurrency } from '../../../core/utils/NumberFormatting'\nimport { generateEqualIntervals } from '../../../core/utils/NumberFormatting'\n\nexport type LineChartDataset = { x: string; y: number }[]\nexport type LineChartLabel = string | { label: string; amount: number }\nexport type TooltipLabel = LineChartLabel & { header?: string }\n\n// X-axis tick that shows only the first letter of the label (e.g. \"J\" for\n// \"Jan\") so all labels fit in small/narrow views. role=\"img\" + aria-label give\n// the tick a reliable accessible name (aria-label alone on a bare SVG <text> is\n// inconsistently announced), so screen readers still get the full label.\nconst NarrowXAxisTickLabel = (props: ChartsTextProps) => {\n const fullLabel = typeof props.text === 'string' ? props.text : ''\n // Array.from keeps surrogate pairs / combining marks intact (non-Latin locales).\n const singleLetter = Array.from(fullLabel.trim())[0] ?? ''\n if (!singleLetter) return <ChartsText {...props} />\n return <ChartsText {...props} aria-label={fullLabel} role=\"img\" text={singleLetter} />\n}\n\nconst NARROW_X_AXIS_SLOTS = { axisTickLabel: NarrowXAxisTickLabel }\n\ntype LineChartCurve =\n | 'catmullRom'\n | 'linear'\n | 'monotoneX'\n | 'monotoneY'\n | 'natural'\n | 'step'\n | 'stepBefore'\n | 'stepAfter'\n | 'bump'\n | 'bumpX'\n | 'bumpY'\n\ninterface LineChartProps {\n areaColor?: string\n axisColor?: string\n baseline?: string\n chartFor?: string\n chartXaxisSx?: SxProps\n chartYaxisSx?: SxProps\n // Because theme chart colors are typed string|undefined\n colors: (string | undefined)[]\n curveType?: LineChartCurve\n customLegendVariant?: string\n customLegendSx?: SxProps\n customLegendBoxSx?: SxProps\n customTooltipLabels?: TooltipLabel[][]\n datasets: LineChartDataset[]\n height?: number\n isCurrency?: boolean\n isGraphClippingXAxis?: boolean\n labels: LineChartLabel[]\n labelBackgroundColor?: string\n labelFontColor?: string\n labelFontSize?: number\n margin?: { top?: number; right?: number; bottom?: number; left?: number }\n markHandlers?: MarkHandlers\n markStyles?: (markIndex: number) => React.CSSProperties & {\n markLabelStyles?: React.CSSProperties\n }\n minRange?: number\n maxRange?: number\n // When true, x-axis labels render as a single letter (with the full label kept\n // as the accessible name), so months don't overlap and get dropped in\n // small/narrow views. Implies showAllXAxisLabels.\n narrowXAxisLabels?: boolean\n onItemClick?: () => void\n // When true, every x-axis tick label is shown instead of letting x-charts drop\n // overlapping ones. Opt-in so it doesn't affect other charts that rely on the\n // default thinning.\n showAllXAxisLabels?: boolean\n peerAverage?: number\n showArea?: boolean\n showAverage?: boolean\n showAxisHighlight?: boolean\n showBars?: boolean\n showLegend?: boolean\n showMark?: boolean\n showMarkLabel?: boolean\n showTooltip?: boolean\n showXAxis?: boolean\n showXAxisTicks?: boolean\n showYAxis?: boolean\n showYAxisTicks?: boolean\n tickIntervals?: any[] | 'auto' | ((value: any, index: number) => boolean) | undefined\n title?: string\n useCustomMark?: boolean\n valueFormatterString?: string\n width?: number\n xAxisScaleType?: 'band' | 'point'\n}\n\n// TODO: Remove negative values and use a proper layout to support X-Charts v8\n\nexport const LineChart: React.FC<LineChartProps> = ({\n areaColor,\n axisColor,\n baseline = 'max',\n chartFor,\n chartXaxisSx,\n chartYaxisSx,\n colors,\n curveType = 'linear',\n customLegendVariant,\n customLegendSx,\n customLegendBoxSx,\n customTooltipLabels,\n datasets,\n height,\n isCurrency,\n isGraphClippingXAxis = false,\n labels,\n labelBackgroundColor,\n labelFontColor,\n labelFontSize,\n margin,\n markHandlers,\n markStyles,\n minRange,\n maxRange,\n narrowXAxisLabels = false,\n showAllXAxisLabels = false,\n onItemClick,\n peerAverage,\n showArea = false,\n showAverage = false,\n showAxisHighlight = false,\n showBars = false,\n showLegend = false,\n showMark = true,\n showMarkLabel = false,\n showTooltip = false,\n showXAxis = false,\n showXAxisTicks = false,\n showYAxis = false,\n showYAxisTicks = false,\n title,\n useCustomMark = false,\n valueFormatterString,\n width,\n xAxisScaleType,\n}) => {\n const theme = useTheme()\n\n // Data for the X axis\n const xData = datasets.flat().map((item) => item.x)\n const yData = datasets.flat().map((item) => item.y)\n\n // Guard the empty-data case: with no points, reduce()/Math.min()/Math.max()\n // produce NaN/±Infinity which flow into the y-axis and make x-charts warn\n // \"the value NaN does not exist in the data of y axis\". Default to 0 so an\n // empty/loading chart renders a valid (flat) axis instead.\n const average = peerAverage\n ? peerAverage\n : yData.length\n ? Math.round(yData.reduce((value, total) => total + value, 0) / yData.length)\n : 0\n\n // Used for the min and max Y axis values\n const yMin = yData.length ? Math.floor(Math.min(...yData) / 100) * 100 : 0\n const yMax = yData.length ? Math.ceil(Math.max(...yData) / 100) * 100 : 0\n\n const series = datasets.map((data, index) => {\n return {\n type: showBars ? 'bar' : 'line',\n curve: curveType,\n color: showBars ? theme.palette.chart?.chart6 : (colors[index] ?? theme.palette.primary.main),\n data: data.map((item) => item.y),\n area: showArea,\n baseline: baseline,\n showMark: true,\n shape: getMarkerShape(index),\n valueFormatter: (value: number) =>\n valueFormatterString ? formatCurrency(value || 0, valueFormatterString) : String(value),\n }\n })\n\n const defaultMargin = {\n top: 60,\n right: 35,\n bottom: 25,\n left: -10,\n }\n\n // Merge default margin with any provided custom margin\n const chartMargin = {\n ...defaultMargin,\n ...margin,\n }\n\n let rangeMin = minRange ?? yMin\n let rangeMax = maxRange ?? yMax\n if (chartFor === 'networthChart') {\n const valueRange = yMax - yMin\n\n const paddingRatio = valueRange < yMax * 0.05 ? 0.25 : 0.2\n const padding = Math.max(valueRange * paddingRatio, yMax * 0.015)\n rangeMin = yMin - padding < 0 ? yMin : yMin - padding\n rangeMax = yMax + padding\n }\n\n const getTickInterval = () => {\n if (chartFor === 'creditOverTime') {\n return generateEqualIntervals(rangeMin, 850, 5)\n } else if (chartFor === 'networthChart') {\n return generateEqualIntervals(rangeMin, rangeMax, 5)\n }\n return undefined\n }\n return (\n <Box\n sx={{\n position: 'relative',\n touchAction: 'pan-y', // Allow vertical scrolling\n '& svg': {\n touchAction: 'pan-y', // Allow vertical scrolling on SVG\n userSelect: 'none', // Prevent text selection\n },\n '& .recharts-wrapper': {\n touchAction: 'pan-y', // For Recharts library specifically\n },\n }}\n >\n <ResponsiveChartContainer\n height={height}\n margin={chartMargin}\n series={series as AllSeriesType[]}\n sx={{\n '& .MuiBarLabel-root': {\n fontSize: 10,\n fontWeight: 600,\n },\n '& .MuiAreaElement-root': {\n opacity: 0.15,\n },\n '& .MuiChartsAxis-tickLabel > tspan': {\n fontFamily: theme.typography.body2.fontFamily,\n },\n '& .MuiLineChart-markLabel': {\n fontFamily: theme.typography.body2.fontFamily,\n },\n }}\n width={width}\n xAxis={[\n {\n data: xData,\n scaleType: xAxisScaleType || (showBars ? 'band' : 'point'),\n // Show every tick instead of letting x-charts drop overlapping ones.\n ...((showAllXAxisLabels || narrowXAxisLabels) && { tickLabelInterval: () => true }),\n },\n ]}\n yAxis={[\n {\n tickInterval: getTickInterval(),\n min: isGraphClippingXAxis ? -22 : rangeMin,\n max: rangeMax || 100,\n colorMap:\n showArea && series.length < 2\n ? {\n type: 'continuous',\n min: rangeMin,\n max: rangeMax,\n color: [\n theme.palette.background.paper,\n colors[0] ?? theme.palette.primary.main,\n ],\n }\n : undefined,\n valueFormatter: (value: number) =>\n valueFormatterString ? formatCurrency(value, valueFormatterString) : String(value),\n width: 62,\n },\n ]}\n >\n {/** Provides the average line - positioned first to be behind other elements **/}\n {showAverage && (\n <ChartsReferenceLine\n lineStyle={{\n stroke: labelBackgroundColor\n ? theme.palette.neutral.main\n : theme.palette.neutral.dark,\n strokeDasharray: '10, 8',\n strokeWidth: 2,\n }}\n y={average}\n />\n )}\n\n {/** Area plot provides gradiant below the line **/}\n {/* Note: Must be above the LinePlot for some style rules to work */}\n <AreaPlot\n onItemClick={onItemClick}\n {...(areaColor && {\n slots: {\n area: (props) => {\n return (\n <g>\n <defs>\n <linearGradient id=\"customGradient\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={areaColor} />\n <stop offset=\"100%\" stopColor={areaColor} stopOpacity={0.02} />\n </linearGradient>\n </defs>\n <path {...stripChartSlotProps(props)} fill={`url(#customGradient)`} />\n </g>\n )\n },\n },\n })}\n />\n\n {/** Line plot provides the data line **/}\n <LinePlot\n onItemClick={onItemClick}\n slots={{\n line: (props) => (\n <CustomLine\n {...props}\n lineColor={areaColor ?? props.ownerState.color ?? theme.palette.primary.main}\n />\n ),\n }}\n />\n\n {/** Mark plot provides the circles **/}\n <MarkPlot\n onItemClick={onItemClick}\n slots={\n useCustomMark\n ? {\n mark: (props) => {\n return (\n <CustomMark\n handlers={markHandlers}\n labelBackgroundColor={labelBackgroundColor}\n labelFontColor={labelFontColor}\n labelFontSize={labelFontSize}\n showLabel={showMarkLabel}\n showMark={showMark || props.dataIndex === datasets[0].length - 1}\n style={markStyles?.(props.dataIndex) ?? {}}\n valueFormatterString={valueFormatterString}\n yData={yData}\n {...props}\n />\n )\n },\n }\n : undefined\n }\n />\n\n <BarPlot\n barLabel={(item) => (Number(item.value) > 0 ? `$${item.value}` : null)}\n borderRadius={10}\n />\n\n {/** Provides the X axis line and values **/}\n <ChartsXAxis\n disableLine={!showXAxis}\n disableTicks={!showXAxisTicks}\n slots={narrowXAxisLabels ? NARROW_X_AXIS_SLOTS : undefined}\n slotProps={\n axisColor\n ? {\n axisLine: {\n style: {\n stroke: axisColor,\n },\n },\n axisTick: {\n style: {\n stroke: axisColor,\n },\n },\n }\n : {}\n }\n sx={{ ...chartXaxisSx }}\n />\n\n {/** Provides the Y axis values **/}\n <ChartsYAxis\n disableLine={!showYAxis}\n disableTicks={!showYAxisTicks}\n slotProps={\n axisColor\n ? {\n axisLine: {\n style: {\n stroke: axisColor,\n },\n },\n axisTick: {\n style: {\n stroke: axisColor,\n },\n },\n }\n : {}\n }\n sx={{ ...chartYaxisSx }}\n />\n\n {/* Add vertical crosshair on hover */}\n {showAxisHighlight && <ChartsAxisHighlight x=\"line\" />}\n\n {showTooltip && (\n <ChartsTooltipContainer trigger=\"axis\">\n <CustomTooltip\n customLabels={customTooltipLabels}\n isCurrency={isCurrency}\n labels={labels}\n series={series}\n valueFormatterString={valueFormatterString}\n />\n </ChartsTooltipContainer>\n )}\n </ResponsiveChartContainer>\n\n {showLegend && (\n <CustomLegend\n average={showAverage ? average : undefined}\n customLegendBoxSx={customLegendBoxSx}\n customLegendVariant={customLegendVariant}\n labels={labels}\n series={series}\n style={{\n position: 'absolute',\n top: 16,\n left: 16,\n ...customLegendSx,\n }}\n title={title}\n valueFormatterString={valueFormatterString}\n />\n )}\n </Box>\n )\n}\n"],"mappings":"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"}
|
|
@@ -10,6 +10,8 @@ export declare class TrendsStore {
|
|
|
10
10
|
setSelectedDateRange: (dateRange: DateRange) => void;
|
|
11
11
|
setVisibleListLength: (length: number) => void;
|
|
12
12
|
get sortedDetailedCategoriesWithTransactions(): DetailedCategoryWithTransactions[];
|
|
13
|
+
get isTransactionStoreIdle(): boolean;
|
|
14
|
+
get isSelectedRangeLoaded(): boolean;
|
|
13
15
|
get selectedDateRangeMonthCount(): number;
|
|
14
16
|
get selectedDateRangeMonthRange(): string;
|
|
15
17
|
get visibleCategories(): DetailedCategoryWithTransactions[];
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { DATE_FORMATS_INTL as
|
|
2
|
-
import { buildCategoryDetailsChartData as i, filterAndSortCategoriesWithTransactions as
|
|
3
|
-
import { endOfMonth as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
1
|
+
import { DATE_FORMATS_INTL as a, formatDate as s } from "../constants/DateFormats.es.js";
|
|
2
|
+
import { buildCategoryDetailsChartData as i, filterAndSortCategoriesWithTransactions as o } from "../utils/TrendsUtil.es.js";
|
|
3
|
+
import { endOfMonth as r } from "date-fns/endOfMonth";
|
|
4
|
+
import { isBefore as n } from "date-fns/isBefore";
|
|
5
|
+
import { subMonths as l } from "date-fns/subMonths";
|
|
6
|
+
import { differenceInCalendarMonths as d } from "date-fns/differenceInCalendarMonths";
|
|
7
|
+
import { makeAutoObservable as g } from "mobx";
|
|
8
|
+
import { addSeconds as c } from "date-fns/addSeconds";
|
|
9
|
+
var R = class {
|
|
9
10
|
globalStore;
|
|
10
11
|
selectedCategoryData = null;
|
|
11
12
|
selectedDateRange;
|
|
12
13
|
visibleListLength = 5;
|
|
13
14
|
constructor(e) {
|
|
14
15
|
this.globalStore = e, this.selectedDateRange = {
|
|
15
|
-
start:
|
|
16
|
-
end:
|
|
17
|
-
},
|
|
16
|
+
start: c(r(l(/* @__PURE__ */ new Date(), 6)), 1),
|
|
17
|
+
end: r(/* @__PURE__ */ new Date())
|
|
18
|
+
}, g(this);
|
|
18
19
|
}
|
|
19
20
|
setSelectedCategoryData = (e) => {
|
|
20
21
|
this.selectedCategoryData = e;
|
|
@@ -26,13 +27,21 @@ var u = class {
|
|
|
26
27
|
this.visibleListLength = e;
|
|
27
28
|
};
|
|
28
29
|
get sortedDetailedCategoriesWithTransactions() {
|
|
29
|
-
return
|
|
30
|
+
return o(this.globalStore.categoryStore.detailedCategoriesWithTransactions);
|
|
31
|
+
}
|
|
32
|
+
get isTransactionStoreIdle() {
|
|
33
|
+
const { isTransactionDataLoaded: e, transactionsLoading: t } = this.globalStore.transactionStore;
|
|
34
|
+
return e && !t;
|
|
35
|
+
}
|
|
36
|
+
get isSelectedRangeLoaded() {
|
|
37
|
+
const { isTransactionDataLoaded: e, cachedStartDate: t } = this.globalStore.transactionStore;
|
|
38
|
+
return e && !n(this.selectedDateRange.start, t);
|
|
30
39
|
}
|
|
31
40
|
get selectedDateRangeMonthCount() {
|
|
32
|
-
return
|
|
41
|
+
return d(this.selectedDateRange.end, this.selectedDateRange.start) + 1;
|
|
33
42
|
}
|
|
34
43
|
get selectedDateRangeMonthRange() {
|
|
35
|
-
return `${
|
|
44
|
+
return `${s(this.selectedDateRange.start, a.MONTH_LONG)} - ${s(this.selectedDateRange.end, a.MONTH_LONG)}`;
|
|
36
45
|
}
|
|
37
46
|
get visibleCategories() {
|
|
38
47
|
return this.sortedDetailedCategoriesWithTransactions.slice(0, this.visibleListLength);
|
|
@@ -45,7 +54,7 @@ var u = class {
|
|
|
45
54
|
}
|
|
46
55
|
};
|
|
47
56
|
export {
|
|
48
|
-
|
|
57
|
+
R as TrendsStore
|
|
49
58
|
};
|
|
50
59
|
|
|
51
60
|
//# sourceMappingURL=TrendsStore.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrendsStore.es.js","names":[],"sources":["../../../src/core/stores/TrendsStore.ts"],"sourcesContent":["import { makeAutoObservable } from 'mobx'\nimport { addSeconds } from 'date-fns/addSeconds'\nimport { differenceInCalendarMonths } from 'date-fns/differenceInCalendarMonths'\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { subMonths } from 'date-fns/subMonths'\n\nimport type { DateRange, DetailedCategoryWithTransactions } from '../types'\nimport { DATE_FORMATS_INTL, formatDate } from '../constants'\nimport {\n buildCategoryDetailsChartData,\n filterAndSortCategoriesWithTransactions,\n} from '../utils/TrendsUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class TrendsStore {\n globalStore: GlobalStore\n selectedCategoryData: DetailedCategoryWithTransactions | null = null\n selectedDateRange: DateRange\n visibleListLength: number = 5\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.selectedDateRange = {\n start: addSeconds(endOfMonth(subMonths(new Date(), 6)), 1),\n end: endOfMonth(new Date()),\n }\n makeAutoObservable(this)\n }\n\n setSelectedCategoryData = (data: DetailedCategoryWithTransactions | null) => {\n this.selectedCategoryData = data\n }\n\n setSelectedDateRange = (dateRange: DateRange) => {\n this.selectedDateRange = dateRange\n }\n\n setVisibleListLength = (length: number) => {\n this.visibleListLength = length\n }\n\n get sortedDetailedCategoriesWithTransactions(): DetailedCategoryWithTransactions[] {\n return filterAndSortCategoriesWithTransactions(\n this.globalStore.categoryStore.detailedCategoriesWithTransactions,\n )\n }\n\n get selectedDateRangeMonthCount(): number {\n return differenceInCalendarMonths(this.selectedDateRange.end, this.selectedDateRange.start) + 1\n }\n\n get selectedDateRangeMonthRange(): string {\n const startMonth = formatDate(this.selectedDateRange.start, DATE_FORMATS_INTL.MONTH_LONG)\n const endMonth = formatDate(this.selectedDateRange.end, DATE_FORMATS_INTL.MONTH_LONG)\n return `${startMonth} - ${endMonth}`\n }\n\n get visibleCategories(): DetailedCategoryWithTransactions[] {\n return this.sortedDetailedCategoriesWithTransactions.slice(0, this.visibleListLength)\n }\n\n get collapsedCategories(): DetailedCategoryWithTransactions[] {\n return this.sortedDetailedCategoriesWithTransactions.slice(this.visibleListLength)\n }\n\n get categoryDetailsChartData() {\n return buildCategoryDetailsChartData(\n this.selectedCategoryData,\n this.selectedDateRangeMonthCount,\n )\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"TrendsStore.es.js","names":[],"sources":["../../../src/core/stores/TrendsStore.ts"],"sourcesContent":["import { makeAutoObservable } from 'mobx'\nimport { addSeconds } from 'date-fns/addSeconds'\nimport { differenceInCalendarMonths } from 'date-fns/differenceInCalendarMonths'\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { isBefore } from 'date-fns/isBefore'\nimport { subMonths } from 'date-fns/subMonths'\n\nimport type { DateRange, DetailedCategoryWithTransactions } from '../types'\nimport { DATE_FORMATS_INTL, formatDate } from '../constants'\nimport {\n buildCategoryDetailsChartData,\n filterAndSortCategoriesWithTransactions,\n} from '../utils/TrendsUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class TrendsStore {\n globalStore: GlobalStore\n selectedCategoryData: DetailedCategoryWithTransactions | null = null\n selectedDateRange: DateRange\n visibleListLength: number = 5\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.selectedDateRange = {\n start: addSeconds(endOfMonth(subMonths(new Date(), 6)), 1),\n end: endOfMonth(new Date()),\n }\n makeAutoObservable(this)\n }\n\n setSelectedCategoryData = (data: DetailedCategoryWithTransactions | null) => {\n this.selectedCategoryData = data\n }\n\n setSelectedDateRange = (dateRange: DateRange) => {\n this.selectedDateRange = dateRange\n }\n\n setVisibleListLength = (length: number) => {\n this.visibleListLength = length\n }\n\n get sortedDetailedCategoriesWithTransactions(): DetailedCategoryWithTransactions[] {\n return filterAndSortCategoriesWithTransactions(\n this.globalStore.categoryStore.detailedCategoriesWithTransactions,\n )\n }\n\n get isTransactionStoreIdle(): boolean {\n const { isTransactionDataLoaded, transactionsLoading } = this.globalStore.transactionStore\n return isTransactionDataLoaded && !transactionsLoading\n }\n\n get isSelectedRangeLoaded(): boolean {\n const { isTransactionDataLoaded, cachedStartDate } = this.globalStore.transactionStore\n return isTransactionDataLoaded && !isBefore(this.selectedDateRange.start, cachedStartDate)\n }\n\n get selectedDateRangeMonthCount(): number {\n return differenceInCalendarMonths(this.selectedDateRange.end, this.selectedDateRange.start) + 1\n }\n\n get selectedDateRangeMonthRange(): string {\n const startMonth = formatDate(this.selectedDateRange.start, DATE_FORMATS_INTL.MONTH_LONG)\n const endMonth = formatDate(this.selectedDateRange.end, DATE_FORMATS_INTL.MONTH_LONG)\n return `${startMonth} - ${endMonth}`\n }\n\n get visibleCategories(): DetailedCategoryWithTransactions[] {\n return this.sortedDetailedCategoriesWithTransactions.slice(0, this.visibleListLength)\n }\n\n get collapsedCategories(): DetailedCategoryWithTransactions[] {\n return this.sortedDetailedCategoriesWithTransactions.slice(this.visibleListLength)\n }\n\n get categoryDetailsChartData() {\n return buildCategoryDetailsChartData(\n this.selectedCategoryData,\n this.selectedDateRangeMonthCount,\n )\n }\n}\n"],"mappings":";;;;;;;;AAgBA,IAAa,IAAb,MAAyB;AAAA,EACvB;AAAA,EACA,uBAAgE;AAAA,EAChE;AAAA,EACA,oBAA4B;AAAA,EAE5B,YAAY,GAA0B;AACpC,SAAK,cAAc,GACnB,KAAK,oBAAoB;AAAA,MACvB,OAAO,EAAW,EAAW,EAAU,oBAAI,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC;AAAA,MACzD,KAAK,EAAW,oBAAI,KAAK,CAAC;AAAA,IAC5B,GACA,EAAmB,IAAI;AAAA,EACzB;AAAA,EAEA,0BAAA,CAA2B,MAAkD;AAC3E,SAAK,uBAAuB;AAAA,EAC9B;AAAA,EAEA,uBAAA,CAAwB,MAAyB;AAC/C,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEA,uBAAA,CAAwB,MAAmB;AACzC,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEA,IAAI,2CAA+E;AACjF,WAAO,EACL,KAAK,YAAY,cAAc,kCACjC;AAAA,EACF;AAAA,EAEA,IAAI,yBAAkC;AACpC,UAAM,EAAE,yBAAA,GAAyB,qBAAA,EAAA,IAAwB,KAAK,YAAY;AAC1E,WAAO,KAA2B,CAAC;AAAA,EACrC;AAAA,EAEA,IAAI,wBAAiC;AACnC,UAAM,EAAE,yBAAA,GAAyB,iBAAA,EAAA,IAAoB,KAAK,YAAY;AACtE,WAAO,KAA2B,CAAC,EAAS,KAAK,kBAAkB,OAAO,CAAe;AAAA,EAC3F;AAAA,EAEA,IAAI,8BAAsC;AACxC,WAAO,EAA2B,KAAK,kBAAkB,KAAK,KAAK,kBAAkB,KAAK,IAAI;AAAA,EAChG;AAAA,EAEA,IAAI,8BAAsC;AAGxC,WAAO,GAFY,EAAW,KAAK,kBAAkB,OAAO,EAAkB,UAEpE,CAAA,MADO,EAAW,KAAK,kBAAkB,KAAK,EAAkB,UAChD,CAAA;AAAA,EAC5B;AAAA,EAEA,IAAI,oBAAwD;AAC1D,WAAO,KAAK,yCAAyC,MAAM,GAAG,KAAK,iBAAiB;AAAA,EACtF;AAAA,EAEA,IAAI,sBAA0D;AAC5D,WAAO,KAAK,yCAAyC,MAAM,KAAK,iBAAiB;AAAA,EACnF;AAAA,EAEA,IAAI,2BAA2B;AAC7B,WAAO,EACL,KAAK,sBACL,KAAK,2BACP;AAAA,EACF;AACF"}
|