UNPKG

@devgateway/dvz-ui-react

Version:

A modular, embeddable React component library for data visualization and UI, built with TypeScript. Provides reusable components for charts, maps, dashboards, and more, with built-in support for internationalization and Redux integration.

421 lines (420 loc) 13.6 kB
import { jsxs as v, jsx as a, Fragment as J } from "react/jsx-runtime"; import { useState as k, useEffect as rt, Fragment as nt } from "react"; import { injectIntl as st } from "react-intl"; import { ResponsiveLine as lt } from "@nivo/line"; import it from "./Tooltip.js"; import { area as ct, line as ot } from "d3-shape"; import { useTheme as dt } from "@nivo/theming"; import mt from "../../layout/FlexWrapDetector.js"; import P from "../../utils/deviceType.js"; const ht = "#66676d", K = "#f0f0f1", ft = ["mobile", "tablet", "midTablet"].includes(P()), pe = P() === "mobile", xe = ["tablet", "midTablet"].includes(P()), ut = (d, x) => { const N = document.createElement("canvas").getContext("2d"); return N.font = x, N.measureText(d).width; }, pt = ({ editing: d, previewMode: x, app: V, legends: N, tooltip: $, tooltipEnabled: ye, options: m, intl: I, groupMode: Z, reverse: xt, marginLeft: be, lineLabelPosition: ge, marginTop: q, marginRight: ve, marginBottom: Q, format: E, colors: yt, offsetY: Ne, height: Ee, showLegends: X, legendPosition: p, tickRotation: y, offsetText: w, tickColor: B, legendLabel: C, xLabelColor: O, colorGenerator: ee, legendCheckBack: A, legendLabelBack: Oe, legendLabelColor: te, highlightXAxisLine: Te, showTickLine: S, showRightAxis: De, valueScale: bt, enableArea: Me, areaShadingCriteria: ae, areaLowerBound: re, areaUpperBound: ne, showPoints: ke, maxValue: $e, fixedMinValue: H, fixedMaxValue: R, offsetBottom: Ie, yAxisTickValues: Le, enableGridY: Fe, enableGridX: We, overrideTickColor: U, offsetRight: ze, selectedMeasures: _e, tooltipEnableMarkdown: je, minMaxClamp: we, reverseLegend: Be, customAxisFormat: L, mobileCustomization: Ae, lineCurve: Se, customLabels: G }) => { var he, fe, ue; const s = JSON.parse(decodeURIComponent(Ae)), se = ft && ((s == null ? void 0 : s.showCustomization) ?? !1), F = se && x !== "Desktop", W = !d && se, [le, He] = k(50), [Re, Ue] = k(q), [gt, ie] = k(0), [Ge, Ye] = k(Q), [T, Je] = k([]), z = m.data.map((e) => ({ id: e.id, label: G && G[e.id] ? G[e.id] : e.label || e.id, color: ee.getColor(e.id, e) })), ce = () => (Be && z.reverse(), /* @__PURE__ */ a(J, { children: X && z.map((e, t) => /* @__PURE__ */ v("div", { className: "legend item", onClick: () => Ve(e.id), children: [ /* @__PURE__ */ a( "input", { className: "ignore", type: "checkbox", checked: T.length === 0 || !T.includes(e.id), readOnly: !0, style: { backgroundColor: A === !0 ? e.color : "none", color: te } } ), /* @__PURE__ */ a( "span", { className: A === !0 ? "checkmark-with-bg" : "checkmark", style: { backgroundColor: A === !0 ? e.color : "transparent" } } ), /* @__PURE__ */ a( "label", { style: { backgroundColor: Oe === !0 ? e.color : "transparent", color: te }, children: e.label } ) ] }, t)) })); rt(() => { (() => { const r = 5 * Math.max(z.length - 5, 0); He(r); })(); }, [z]); const Ke = { bottom: `-${le}px` }, Pe = { bottom: `-${le}px`, gap: "0px", top: "0px" }, _ = (e) => T.length ? e.filter((t) => T.indexOf(t.id) === -1) : e, Ve = (e) => { const t = T.slice(); if (t.indexOf(e) > -1) { const r = t.indexOf(e); t.splice(r, 1); } else t.push(e); Je(t); }, Ze = (e) => { const t = Object.assign({}, e), r = dt(); (F || W) && de.includes(String(t.value)) && (t.value = ""); let l = [], n = ""; if (F || W) { const c = String(t.value).split(" "); let o = 25; d && x === "Mobile" || pe && !d ? o = (s == null ? void 0 : s.mobileMaxTickLength) ?? 25 : d && x === "Tablet" || xe && !d ? o = (s == null ? void 0 : s.tabletMaxTickLength) ?? 25 : window.matchMedia("(min-width: 768px) and (max-width: 1250px)").matches && !d && (o = 15), c.forEach((b) => { n.length + String(b).length <= o ? n += (n ? " " : "") + b : (l.push(n), n = b); }), n && l.push(n); } else l = [t.value]; let i = 12; return d && x === "Mobile" || pe && !d ? i = (s == null ? void 0 : s.mobileYAxisLineHeight) ?? 12 : (d && x === "Tablet" || xe && !d) && (i = (s == null ? void 0 : s.tabletYAxisLineHeight) ?? 12), ut(t.value, "12px Roboto") + 15, y > 0 && y < 180 ? /* @__PURE__ */ v("g", { transform: `translate(${e.x},${e.y + 30})`, children: [ S && /* @__PURE__ */ a( "line", { stroke: U ? B : K, strokeWidth: 1.5, y1: -32, y2: -12 } ), /* @__PURE__ */ a("g", { transform: `translate(0, ${e.y + w})`, children: l.map((c, o) => /* @__PURE__ */ a( "text", { transform: `rotate(${y})`, textAnchor: "start", y: typeof e.value == "number" ? 0 : o * i, dominantBaseline: "middle", style: { ...r.axis.ticks.text, fill: O === "null" ? "black" : O, fontSize: "12px", fontFamily: "sans-serif" }, children: c }, c )) }) ] }) : y > 180 && y < 360 ? /* @__PURE__ */ v("g", { transform: `translate(${e.x},${e.y + 30})`, children: [ S && /* @__PURE__ */ a( "line", { stroke: U ? B : K, strokeWidth: 1.5, y1: -32, y2: -12 } ), /* @__PURE__ */ a("g", { transform: `translate(0, ${e.y + w})`, children: /* @__PURE__ */ a( "text", { transform: `rotate(${y})`, textAnchor: "end", dominantBaseline: "middle", style: { ...r.axis.ticks.text, fill: O, fontSize: "12px" }, children: t.value } ) }) ] }) : /* @__PURE__ */ v("g", { transform: `translate(${e.x},${e.y + 30})`, children: [ S && /* @__PURE__ */ a( "line", { stroke: U ? B : K, strokeWidth: 1.5, y1: -32, y2: -12 } ), /* @__PURE__ */ a("g", { transform: `translate(0, ${e.y + w})`, children: l.map((c, o) => /* @__PURE__ */ a( "text", { transform: `rotate(${y})`, textAnchor: "middle", y: typeof e.value == "number" ? 0 : o * i, dominantBaseline: "middle", style: { ...r.axis.ticks.text, fill: O === "null" ? "black" : O, fontSize: "12px", fontFamily: "sans-serif" }, children: c }, c )) }) ] }); }, qe = ({ series: e, xScale: t, yScale: r, innerHeight: l }) => { const n = e && e.length > 0 ? e[0].color : "#3daff7", i = []; e[0] && e[0].data.forEach((u) => { V == "csv" ? m.keys.forEach((g) => { i.push({ measure: g, min: u.data.variables[g] }); }) : _e.forEach((g) => { i.push({ measure: g, min: u.data.variables[g] }); }); }); const c = i.sort((u, g) => u.min - g.min), o = ae == "CUSTOM_BETWEEN_TWO_LINES" && re ? re : c[0].measure, b = ae == "CUSTOM_BETWEEN_TWO_LINES" && ne ? ne : c[c.length - 1].measure, at = ct().x((u) => t(u.data.x)).y0((u) => r(u.data.variables[o])).y1((u) => r(u.data.variables[b])); return /* @__PURE__ */ a(J, { children: e && e[0] && /* @__PURE__ */ a( "path", { d: at(e[0].data), fill: n, fillOpacity: 0.4 } ) }); }, Qe = ({ series: e, xScale: t, yScale: r, innerHeight: l, innerWidth: n }) => { const i = [0, n], c = ot().x((o, b) => b === 0 ? -10 : o).y((o) => r(0)); return /* @__PURE__ */ a(nt, { children: /* @__PURE__ */ a( "path", { d: c(i), fill: "none", stroke: ht, style: { pointerEvents: "none", strokeDasharray: "4 4" } } ) }); }, D = ["grid", "axes", "lines", "legends"]; Me && D.push(qe), ke && (D.push("points"), D.push("mesh")), Te && D.push(Qe); let M = []; _(m.data).forEach((e) => { e.data && (M = [...M, ...e.data.map((t) => t.y)]); }); const Xe = () => { if (Z === "stacked") { const e = []; _(m.data).forEach((l) => { e.push(...l.data); }); const r = []; e.forEach((l) => { r.indexOf(l.x) == -1 && r.push(l.x); }), f = Math.max( ...r.map((l) => e.filter((n) => n.x == l).map((n) => n.y).reduce((n, i) => Math.max(n + i, n + 0))) ), h = Math.min( ...r.map((l) => e.filter((n) => n.x == l).map((n) => n.y).reduce((n, i) => Math.min(n - i, i - n))) ); } else M.length > 0 && (f = Math.max(...M), h = Math.min(...M)); return f = f < 0 ? f * 0.9 : f * 1.1, h = h > 0 ? h * 0.9 : h * 1.1, { min: h, max: f }; }; let h = "auto", f = "auto"; const j = Xe(); $e == "fixed" ? (h = H != null && H != "" ? H : j.min, f = R != null && R != "" ? R : j.max) : (h = j.min, f = j.max); const oe = () => /* @__PURE__ */ a(J, { children: X && C && /* @__PURE__ */ a("div", { className: "legend item", children: /* @__PURE__ */ a("label", { className: "legend-title", children: C }) }) }), Ce = { top: Re, right: ve, bottom: Ge, left: be }; let Y = parseInt(Le); const et = m.data && ((fe = (he = m.data) == null ? void 0 : he.filter((e) => { var t; return ((t = e == null ? void 0 : e.data) == null ? void 0 : t.length) > 0; })) == null ? void 0 : fe.length), de = []; if (F || W) { Y = Number.parseInt(s.yAxisTickValues); const e = new Map(Object.entries(((ue = s == null ? void 0 : s.labels) == null ? void 0 : ue.xAxis) ?? {})); for (const [t, r] of e) r || de.push(t); } const me = _(m.data), tt = ["grid", "axes", "legends"]; if (m != null && m.data && et > 0) { let e = _(m.data); return /* @__PURE__ */ v("div", { style: { height: Ee }, children: [ /* @__PURE__ */ a( lt, { curve: Se, data: me, margin: Ce, xScale: { type: "point" }, yScale: { type: "linear", min: h, max: f, stacked: Z == "stacked", reverse: !1, clamp: we }, layers: me.length === 0 ? tt : D, axisTop: null, axisRight: De ? { tickSize: 5, tickValues: Y, tickPadding: 5, tickRotation: 0, legend: N.right, legendPosition: "middle", legendOffset: parseInt(ze), format: (t) => { const r = L || E; return I.formatNumber( r.style === "percent" ? t / 100 : t, { ...r } ); } } : null, enableGridY: Fe, enableGridX: We, enablePointLabel: ge === "top", pointLabel: (t) => I.formatNumber( E.style === "percent" ? t.yFormatted / 100 : t.yFormatted, E ), lineWidth: 3, colors: (t) => ee.getColor(t.id, t), axisBottom: (F || W) && (s == null ? void 0 : s.xAxisDisabled) === !0 ? null : { renderTick: Ze, legend: N.bottom, legendPosition: "middle", legendOffset: Number.parseInt(Ie) }, axisLeft: { tickSize: 5, tickValues: Y, tickPadding: 5, tickRotation: 0, legend: N.left, legendPosition: "middle", legendOffset: Number.parseInt(Ne), format: (t) => { const r = L || E; return I.formatNumber( r.style === "percent" ? t / 100 : t, { ...r } ); } }, tooltip: (t) => ye && $ && $.trim().length > 0 ? /* @__PURE__ */ a( it, { intl: I, format: E, d: t, tooltip: $, tooltipEnableMarkdown: je } ) : null, pointSize: 10, pointBorderWidth: 2, pointBorderColor: { from: "serieColor" }, useMesh: e.length > 0 && e[0].data.length > 0 }, /* @__PURE__ */ new Date() ), (p === "top" || p === "bottom") && /* @__PURE__ */ a( "div", { className: `legends container has-standard-12-font-size ${p}`, children: /* @__PURE__ */ v("div", { className: "legend-sections", children: [ /* @__PURE__ */ a("div", { className: "title-section", children: oe() }), /* @__PURE__ */ a( mt, { onWrapChange: (t) => { p === "top" ? (Ue(q + t / 2 * 40), ie(t)) : (Ye(Q + t / 2 * 25), ie(t)); }, className: "legends container has-standard-12-font-size items-section", children: ce() } ) ] }) } ), (p === "right" || p === "left") && /* @__PURE__ */ v( "div", { className: `legends container has-standard-12-font-size ${p}`, style: p === "right" ? Ke : Pe, children: [ oe(), ce() ] } ) ] }); } return /* @__PURE__ */ a("div", {}); }, It = st(pt); export { It as default };