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.

185 lines (184 loc) 8.03 kB
import { jsx as L } from "react/jsx-runtime"; import "react"; import q from "./BaseLayer.js"; import G from "../data/DataProvider.js"; import H from "../data/DataConsumer.js"; import * as P from "d3"; import { injectIntl as X } from "react-intl"; import K from "papaparse"; import Q from "./BreaksStyles.js"; class Z extends q { constructor() { super(), this.createDataLayer = this.createDataLayer.bind(this); } createDataLayer(r) { const { format: s, path: a, tooltip: k, markFillColor: n, markBorderColor: g, markSizeScale: F, //circle size featureJoinAttribute: d, apiJoinAttribute: A, projection: w, breaks: C, markSizeScale2: b, //arrow size measures: u, zoom: v, offsetPixels: l = 10, waitForFilters: N } = this.props, E = u[0], x = new Q({ breaks: C, defaultFillColor: n, defaultBorderColor: g, defaultSize: b }); s.style === "compacted" || s.style, s.style, s.currency, parseInt(s.minimumFractionDigits), parseInt(s.maximumFractionDigits); const _ = r.features.filter((t) => t.properties._value != null); this.g = P.select(this.gRef.current), this.g.attr("class", "base-layer zoomable"), this.props.transform && this.g.attr("transform", this.props.transform), this.g.selectAll(".flow-line").remove(), this.g.selectAll(".start-point").remove(), this.g.selectAll(".end-point").remove(), this.g.select("defs").selectAll("*").remove(); const J = this.props.transform ? this.props.transform.k : 1, S = []; _.forEach((t) => { S.push(t), t.properties.destinations.sort((p, e) => p[E] - e[E]).forEach((p) => { const e = p[E]; r.features.filter((o) => o.properties[d] == p.value).forEach((o) => { o.properties.meta = p; const c = t.properties[d], i = t.properties[d] + "--" + o.properties[d], f = a.centroid(t), h = a.centroid(o), O = h[0] - f[0], T = h[1] - f[1], I = Math.sqrt(O * O + T * T), V = O / I, M = T / I, R = [ h[0] - V * l, h[1] - M * l ], U = w.invert(R), W = { type: "LineString", coordinates: [ w.invert(f), // Start in geo coords U // New endpoint before d2 ] }, m = this.g.append("g"); this.g.select("defs").append("marker").attr("id", "arrow" + i).attr("markerUnits", "strokeWidth").attr("markerWidth", "6").attr("markerHeight", "6").attr("viewBox", "0 0 24 24").attr("refX", "6").attr("refY", "6").attr("orient", "auto").append("path").attr("d", "M2,2 L10,6 L2,10 L6,6 L2,2").attr("d", "M2,2 L10,6 L2,10 L6,6 L2,2").attr("style", (D) => "fill: " + x.getColor(e) + ";"), m.append("path").attr("d", a(W)).attr("id", i).attr("class", "flow-line").style("fill", "none").style("cursor", "pointer").style("stroke-dasharray", "0").style("stroke", (D) => x.getColor(e)).style("stroke-width", (D) => x.getSize(e)).attr("marker-end", "url(#arrow" + i + ")").on("mouseenter", (D, tt) => { if (m.selectAll("marker").transition().duration("200").style("opacity", 0), m.selectAll(".start-point").transition().duration("200").style("opacity", 0), m.selectAll(".flow-line").transition().duration("200").style("opacity", 0), P.select(D.target).transition().duration("200").style("opacity", 1), m.selectAll("#arrow" + i).transition().duration("200").style("opacity", 1), m.selectAll(".start-point.circle_" + c).transition().duration("200").style("opacity", 1), e) { const B = {}, j = {}; Object.keys(t.properties).forEach((y) => { B["origin_" + y] = t.properties[y]; }), Object.keys(o.properties).forEach((y) => { j["target_" + y] = o.properties[y]; }), Object.keys(o.properties.meta).forEach((y) => { j["target_" + y] = o.properties.meta[y]; }); const Y = { ...B, ...j, meta: { [A]: t.properties.meta ? t.properties.meta.value : "", ...t.properties.meta, value: e } }; this.showToolTip(k, Y, x.getColor(o.properties._value)); } }).on("mouseout", (D) => { this.hiddenToolTip(), P.selectAll(".flow-line").transition().duration("100").style("opacity", 1), m.selectAll(".start-point").transition().duration("100").style("opacity", 1), m.selectAll("marker").transition().duration("100").style("opacity", 1); }), m.append("text").append("textPath").attr("xlink:href", i).style("text-anchor", "middle").attr("startOffset", "50%").attr("fill", "#fff").text("Yay, my text is on a wavy path"); }); }); }), S.forEach((t) => { this.g.append("circle").attr("fill", n).attr("stroke", g).attr("class", "start-point circle_" + t.properties[d]).attr("stroke-width", 2).style("vector-effect", "non-scaling-stroke").attr("cx", a.centroid(t)[0]).attr("cy", a.centroid(t)[1]).attr("r", () => F * 1 / J).on("mouseenter", (p) => { this.showToolTip("{name_en}", t.properties, ""); }).on("mouseout", (p) => { this.hiddenToolTip(); }); }); } create() { const { app: r, name: s, file: a, path: k, csv: n, zoom: g, labelFilter: F = [], labelField: d, labelFontSize: A, labelColor: w, fillColor: C, borderColor: b, featureJoinAttribute: u, editing: v, data: l, breaks: N, markFillColor: E, markSizeScale: x, measures: _, flowValuesFrom: J } = this.props; a != "none" && this.loadJSON(a).then((S) => { const t = S.features.map((e) => { const o = e.properties[u]; if (r != "csv" && l && l.children) { const c = l.children.filter((i) => i.value.indexOf(o) > -1); if (c.length > 0) { const i = c[0][_[0]]; e.properties.meta = c[0], e.properties._value = i, e.properties.destinations = c[0].children; } } else if (r == "csv") { const c = K.parse(n, { header: !0, dynamicTyping: !0 }), i = e.properties[u]; c.data.filter((h) => h.origin == i); const f = c.data.filter((h) => h.origin == i)[0]; f != null && (alert("CSV Not implemented Yet, please do it if you have time"), e.properties.meta = f, e.properties._value = f.value, e.properties.destinations = f.destination); } return e; }), p = { ...S, features: t }; this.createDataLayer(p); }); } componentDidUpdate(r, s, a) { const { projection: k, editing: n, data: g } = this.props; (n || JSON.stringify(r.data) !== JSON.stringify(g)) && this.create(), r.visible != this.props.visible && this.g.style("display", this.props.visible ? "" : "none"); } componentDidMount() { this.create(), this.props.zoom.current.fullView(); } render() { const { id: r } = this.props; return /* @__PURE__ */ L("g", { id: "data-" + r, className: "data " + r, ref: this.gRef, children: /* @__PURE__ */ L("defs", {}) }); } } const $ = (z) => { const { id: r, unique: s, filters: a, csv: k, app: n, group: g = "default", flowOrigin: F, editing: d, flowDestination: A, dvzProxyDatasetId: w, waitForFilters: C } = z, b = { dvzProxyDatasetId: w }, u = a || {}; return u && u.forEach && u.forEach((v) => { v.value != null && v.value.filter((l) => l != null && l.toString().trim() != "").length > 0 && (b[v.param] = v.value); }), /* @__PURE__ */ L( G, { editing: d, params: b, waitForFilters: C, app: n, csv: decodeURIComponent(k), group: g, ignoreErrors: !0, isSvg: !0, store: [n, s, r], source: F + "/" + A, children: /* @__PURE__ */ L(H, { children: /* @__PURE__ */ L(Z, { ...z }) }) } ); }, pt = X($); export { pt as default };