react-plotly.js
Version:
A plotly.js react component from Plotly
272 lines (267 loc) • 9.95 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/react-plotly.js
var react_plotly_exports = {};
__export(react_plotly_exports, {
default: () => react_plotly_default
});
module.exports = __toCommonJS(react_plotly_exports);
// src/factory.js
var import_react = __toESM(require("react"));
// src/events.js
var events = [
{ name: "AfterExport" },
{ name: "AfterPlot" },
{ name: "Animated", triggersUpdate: true },
{ name: "Animating" },
{ name: "AnimatingFrame" },
{ name: "AnimationInterrupted" },
{ name: "AutoSize" },
{ name: "BeforeExport" },
{ name: "BeforeHover" },
{ name: "BeforePlot" },
{ name: "ButtonClicked" },
{ name: "Click" },
{ name: "ClickAnnotation" },
{ name: "Deselect" },
{ name: "DoubleClick", triggersUpdate: true },
{ name: "Framework" },
{ name: "Hover" },
{ name: "IcicleClick" },
{ name: "LegendClick" },
{ name: "LegendDoubleClick" },
{ name: "LegendTitleClick" },
{ name: "LegendTitleDoubleClick" },
{ name: "Relayout", triggersUpdate: true },
{ name: "Relayouting", triggersUpdate: true },
{ name: "Restyle", triggersUpdate: true },
{ name: "Redraw", triggersUpdate: true },
{ name: "Selected" },
{ name: "Selecting" },
{ name: "SliderChange" },
{ name: "SliderEnd" },
{ name: "SliderStart" },
{ name: "SunburstClick" },
{ name: "Transitioned" },
{ name: "Transitioning" },
{ name: "TransitionInterrupted" },
{ name: "TreemapClick" },
{ name: "Unhover" },
{ name: "WebGlContextLost" }
];
function getPlotlyEventName(eventName) {
return "plotly_" + eventName.toLowerCase();
}
function getPropName(eventName) {
return "on" + eventName;
}
var eventNames = events.map((event) => event.name);
var updateEvents = events.filter((event) => event.triggersUpdate).map((event) => getPlotlyEventName(event.name));
// src/factory.js
var isBrowser = typeof window !== "undefined";
var DEFAULT_DATA = Object.freeze([]);
var DEFAULT_STYLE = Object.freeze({ position: "relative", display: "inline-block" });
function plotComponentFactory(Plotly2) {
return (0, import_react.forwardRef)(function PlotlyComponent({
data = DEFAULT_DATA,
layout,
config,
frames,
revision,
onInitialized,
onUpdate,
onPurge,
onError,
debug = false,
style = DEFAULT_STYLE,
className,
useResizeHandler = false,
divId,
...eventProps
}, forwardedRef) {
const elRef = (0, import_react.useRef)(null);
const promiseRef = (0, import_react.useRef)(Promise.resolve());
const handlersRef = (0, import_react.useRef)({});
const resizeHandlerRef = (0, import_react.useRef)(null);
const unmountingRef = (0, import_react.useRef)(false);
const prevRef = (0, import_react.useRef)(null);
const onUpdateRef = (0, import_react.useRef)(onUpdate);
onUpdateRef.current = onUpdate;
const onPurgeRef = (0, import_react.useRef)(onPurge);
onPurgeRef.current = onPurge;
const handleUpdate = (0, import_react.useRef)(() => {
const cb = onUpdateRef.current;
if (typeof cb !== "function" || !elRef.current) {
return;
}
const el = elRef.current;
const frames2 = el._transitionData ? el._transitionData._frames : null;
cb({ data: el.data, layout: el.layout, frames: frames2 }, el);
}).current;
const setRef = (0, import_react.useCallback)(
(el) => {
elRef.current = el;
if (typeof forwardedRef === "function") {
forwardedRef(el);
} else if (forwardedRef) {
forwardedRef.current = el;
}
if (debug && isBrowser && el) {
window.gd = el;
}
},
[forwardedRef, debug]
);
(0, import_react.useEffect)(() => {
unmountingRef.current = false;
if (prevRef.current === null) {
prevRef.current = { data, layout, config, frames, revision };
runPlotlyReact(true, onInitialized, true);
return;
}
const prev = prevRef.current;
const numPrev = prev.frames && prev.frames.length ? prev.frames.length : 0;
const numNext = frames && frames.length ? frames.length : 0;
const figureChanged = !(prev.layout === layout && prev.data === data && prev.config === config && numPrev === numNext);
const revisionWasDefined = prev.revision !== void 0;
const revisionChanged = prev.revision !== revision;
prevRef.current = { data, layout, config, frames, revision };
if (!figureChanged && (!revisionWasDefined || !revisionChanged)) {
return;
}
runPlotlyReact(false, onUpdate, false);
});
(0, import_react.useEffect)(() => {
const el = elRef.current;
return () => {
unmountingRef.current = true;
if (el) {
if (typeof onPurgeRef.current === "function") {
const frames2 = el._transitionData ? el._transitionData._frames : null;
onPurgeRef.current({ data: el.data, layout: el.layout, frames: frames2 }, el);
}
if (el.removeListener) {
updateEvents.forEach((evt) => el.removeListener(evt, handleUpdate));
}
Plotly2.purge(el);
}
if (resizeHandlerRef.current && isBrowser) {
window.removeEventListener("resize", resizeHandlerRef.current);
resizeHandlerRef.current = null;
}
prevRef.current = null;
promiseRef.current = Promise.resolve();
handlersRef.current = {};
};
}, []);
function runPlotlyReact(shouldInvokeResize, figureCallback, shouldAttachUpdateEvents) {
promiseRef.current = promiseRef.current.then(() => {
if (unmountingRef.current) {
return void 0;
}
if (!elRef.current) {
throw new Error("Missing element reference");
}
return Plotly2.react(elRef.current, { data, layout, config, frames });
}).then(() => {
if (unmountingRef.current) {
return;
}
syncWindowResize(shouldInvokeResize);
syncEventHandlers();
invokeFigureCallback(figureCallback);
if (shouldAttachUpdateEvents) {
attachUpdateEvents();
}
}).catch((err) => {
if (typeof onError === "function") {
onError(err);
}
});
}
function invokeFigureCallback(callback) {
if (typeof callback !== "function" || !elRef.current) {
return;
}
const el = elRef.current;
const f = el._transitionData ? el._transitionData._frames : null;
callback({ data: el.data, layout: el.layout, frames: f }, el);
}
function attachUpdateEvents() {
if (!elRef.current || !elRef.current.removeListener) {
return;
}
updateEvents.forEach((evt) => elRef.current.on(evt, handleUpdate));
}
function syncWindowResize(invoke) {
if (!isBrowser) {
return;
}
if (useResizeHandler && !resizeHandlerRef.current) {
resizeHandlerRef.current = () => Plotly2.Plots.resize(elRef.current);
window.addEventListener("resize", resizeHandlerRef.current);
if (invoke) {
resizeHandlerRef.current();
}
} else if (!useResizeHandler && resizeHandlerRef.current) {
window.removeEventListener("resize", resizeHandlerRef.current);
resizeHandlerRef.current = null;
}
}
function syncEventHandlers() {
eventNames.forEach((eventName) => {
const prop = eventProps[getPropName(eventName)];
const handler = handlersRef.current[eventName];
const hasHandler = Boolean(handler);
if (prop && !hasHandler) {
addEventHandler(eventName, prop);
} else if (!prop && hasHandler) {
removeEventHandler(eventName);
} else if (prop && hasHandler && prop !== handler) {
removeEventHandler(eventName);
addEventHandler(eventName, prop);
}
});
}
function addEventHandler(eventName, prop) {
handlersRef.current[eventName] = prop;
elRef.current.on(getPlotlyEventName(eventName), prop);
}
function removeEventHandler(eventName) {
elRef.current.removeListener(getPlotlyEventName(eventName), handlersRef.current[eventName]);
delete handlersRef.current[eventName];
}
return /* @__PURE__ */ import_react.default.createElement("div", { id: divId, style, ref: setRef, className });
});
}
// src/react-plotly.js
var import_plotly = __toESM(require("plotly.js/dist/plotly"));
var PlotComponent = plotComponentFactory(import_plotly.default);
var react_plotly_default = PlotComponent;
//# sourceMappingURL=index.cjs.map