@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.
115 lines (114 loc) • 5.76 kB
JavaScript
import { jsx as l, jsxs as x } from "react/jsx-runtime";
import y from "react";
import * as m from "d3";
import { Icon as b, Popup as I } from "semantic-ui-react";
import { FormattedMessage as k } from "react-intl";
class O extends y.Component {
constructor(t) {
super(t), this.zoomRef = y.createRef(), this.lastInternalZoom = null, this.lastUserTransform = null, this.zoomed = this.zoomed.bind(this), this.zoomEnd = this.zoomEnd.bind(this), this.zoomIn = this.zoomIn.bind(this), this.zoomOut = this.zoomOut.bind(this), this.reset = this.reset.bind(this), this.fullView = this.fullView.bind(this), this.transition2fullView = this.transition2fullView.bind(this), this._fullView = this._fullView.bind(this), this.zoom = m.zoom().scaleExtent([0.1, 300]).on("zoom", this.zoomed).on("end", this.zoomEnd);
}
componentDidMount() {
const { zoomEnabled: t = !0 } = this.props, o = this.getSelection();
o && (this.fullView(), t && (this.props.editing || (o.on("dblclick.zoom", null), o.on("dblclick", (i) => {
i.preventDefault(), console.log("double click event"), o.transition().duration(250).call(this.zoom.scaleBy, 1.5);
}), o.on("wheel.zoom", null), o.on("wheel", (i) => {
console.log("wheel event", i.deltaY, i.deltaX, i.deltaZ), i.preventDefault();
const s = i.deltaY > 0 ? 1 / 1.5 : 1.5;
o.transition().duration(250).call(this.zoom.scaleBy, s);
}), o.call(this.zoom))));
}
componentDidUpdate(t) {
const o = this.getSelection(), { zoomEnabled: i, initialPosition: s, readyState: c, height: d, width: a, selectedPoint: n, projection: h } = this.props, r = JSON.stringify(t.initialPosition) !== JSON.stringify(s);
if (t.zoomEnabled !== i || r)
if (i && o) {
if (s && this.lastInternalZoom) {
const e = (V, S = 3) => Number(V.toFixed(S)), { x: f, y: p, k: u } = s, { x: z, y: g, k: w } = this.lastInternalZoom;
if (Math.abs(e(f) - e(z)) < 1 && Math.abs(e(p) - e(g)) < 1 && Math.abs(e(u) - e(w)) < 1e-3) {
this.lastInternalZoom = null;
return;
}
}
o.call(this.zoom).on(".zoom", this.zoom), this.transition2fullView();
} else o && o.on(".zoom", null);
!t.readyState && c && this.fullView(), (t.height !== d || t.width !== a) && this.fullView(), n != t.selectedPoint && n && this.zoomTo(h([n.y, n.x]));
}
zoomed(t) {
var i, s;
const o = this.getSelection();
o && (o.selectAll("g.zoomable").attr("transform", t.transform), (s = (i = this.props).onZoomed) == null || s.call(i, t.transform), this.props.editing && t.sourceEvent && (this.lastUserTransform = t.transform));
}
zoomEnd(t) {
var n, h;
const { identifier: o, editing: i, width: s, height: c, postMessageOrigin: d = "*" } = this.props, a = this.lastUserTransform || t.transform;
if (this.lastUserTransform = null, (h = (n = this.props).onZoomed) == null || h.call(n, a), i) {
const r = (g, w = 3) => Number(g.toFixed(w)), { x: e, y: f, k: p } = a, u = { x: r(e), y: r(f), k: r(p) };
this.lastInternalZoom = u;
const z = {
type: `d3_map_${o}`,
value: {
...u,
width: s,
height: c
}
};
window.parent.postMessage(z, d);
}
}
zoomIn() {
const t = this.getSelection();
if (t) {
const o = this.props.editing ? 0 : this.props.transitionDuration || 500;
t.transition().duration(o).call(this.zoom.scaleBy, 2);
}
}
zoomTo(t) {
const o = m.zoomIdentity.translate(this.props.width / 2, this.props.height / 2).scale(200).translate(-t[0], -t[1]), i = this.getSelection();
this.props.editing || this.props.transitionDuration, i.transition().duration(750).call(this.zoom.transform, o);
}
zoomOut() {
const t = this.getSelection();
if (t) {
const o = this.props.editing ? 0 : this.props.transitionDuration || 500;
t.transition().duration(o).call(this.zoom.scaleBy, 0.5);
}
}
reset() {
const t = this.getSelection();
t && (this.props.editing ? t.call(this.zoom.transform, m.zoomIdentity.translate(0, 0).scale(1)) : this.transition2fullView());
}
getSelection() {
var t;
return (t = this.props.svgRef) != null && t.current ? m.select(this.props.svgRef.current) : this.zoomRef.current ? m.select(this.zoomRef.current.parentNode.querySelector("svg")) : null;
}
_fullView(t = !0) {
const { initialPosition: o, width: i, height: s, transform: c } = this.props;
if (!o) return;
const { x: d = 100, y: a = 23, k: n = 1, width: h, height: r } = o;
if (!h || !r || !n) return;
const e = this.getSelection();
e && e.transition().duration(t ? 750 : 0).attr("transform", c).call(this.zoom.transform, m.zoomIdentity.translate(d, a).scale(n));
}
transition2fullView() {
this._fullView(!0);
}
fullView() {
this._fullView(!1);
}
render() {
const { editing: t, zoomEnabled: o = !0 } = this.props;
return /* @__PURE__ */ l("div", { ref: this.zoomRef, className: `zoom ${o ? "" : "disabled"}`, children: (t || o) && /* @__PURE__ */ x("div", { children: [
/* @__PURE__ */ l("div", { className: "button plus", onClick: this.zoomIn, children: /* @__PURE__ */ l(b, { name: "plus", size: "small" }) }),
/* @__PURE__ */ l("div", { className: "button minus", onClick: this.zoomOut, children: /* @__PURE__ */ l(b, { name: "minus", size: "small" }) }),
/* @__PURE__ */ l(
I,
{
content: /* @__PURE__ */ l(k, { id: "map.reset.tooltip", defaultMessage: "Reset zoom" }),
trigger: /* @__PURE__ */ l("div", { className: "button reset", onClick: this.reset, children: /* @__PURE__ */ l(b, { name: "repeat", size: "small" }) })
}
)
] }) });
}
}
export {
O as default
};