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.

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