@skillpet/circuit
Version:
Circuit diagram library — render electrical schematics from JSON, with interactive SVG, themes, and Vue/React components
55 lines (54 loc) • 1.97 kB
JavaScript
/// <reference lib="dom" />
import { defineComponent, ref, h, onMounted, onUnmounted, watch, } from "vue";
import { mountFromJson, renderFromJson, } from "../index.js";
export const CircuitDiagram = defineComponent({
name: "CircuitDiagram",
props: {
circuit: { type: Object, required: true },
options: { type: Object, default: () => ({}) },
interactive: { type: Boolean, default: false },
},
emits: [
"element-click",
"element-hover",
"element-leave",
"element-select",
"canvas-click",
"ready",
],
setup(props, { emit }) {
const containerRef = ref();
let ctrl = null;
function render() {
const el = containerRef.value;
if (!el)
return;
if (ctrl) {
ctrl.destroy();
ctrl = null;
}
if (props.interactive) {
ctrl = mountFromJson(el, props.circuit, {
...props.options,
interactive: true,
});
ctrl.on("element:click", (info) => emit("element-click", info));
ctrl.on("element:hover", (info) => emit("element-hover", info));
ctrl.on("element:leave", (info) => emit("element-leave", info));
ctrl.on("element:select", (info) => emit("element-select", info));
ctrl.on("canvas:click", (pt) => emit("canvas-click", pt));
emit("ready", ctrl);
}
else {
el.innerHTML = renderFromJson(props.circuit, props.options);
}
}
onMounted(render);
watch(() => [props.circuit, props.options, props.interactive], render, { deep: true });
onUnmounted(() => {
if (ctrl)
ctrl.destroy();
});
return () => h("div", { ref: containerRef, class: "circuit-container" });
},
});