React and JointJS - custom element - Uncaught Error: dia.ElementView: markup required

94 views Asked by At

I am playing around with JointJS and React. I am using this code (with some minor modifications)

I created 2 projects: (1) without and (2) with react. In both cases I am able to render the graph with elements inside. In the project that does not use react the 'collapse' works fine. In the project that uses react the 'collapse' works to some extent: I can hide the subgraph but I cannot show it again. I am getting the following error in the console: Uncaught Error: dia.ElementView: markup required

Below the code that I used in the 'react' project.

Declaration of 'GroupView' and adding the namespaces to the graph and paper didn't help.

import * as joint from "jointjs";

function GraphPage() {
  useEffect(() => {
    customElement();
  }, []);
  return <div id="paper"></div>;
}

function customElement() {
  joint.shapes.example = {};
  joint.shapes.example.Group = joint.dia.Element.define(
    "example.Group",
    {
      size: {
        width: 100,
        height: 40,
      },
      attrs: {
        body: {
          refWidth: "100%",
          refHeight: "100%",
          fill: "white",
          stroke: "black",
          strokeWidth: 2,
        },
        tool: {
          r: 10,
          cx: 20,
          cy: 20,
          fill: "white",
          stroke: "blue",
          strokeWidth: 2,
          cursor: "pointer",
          event: "element:collapse",
        },
      },
    },
    {
      markup: [
        {
          tagName: "rect",
          selector: "body",
        },
        {
          tagName: "circle",
          selector: "tool",
        },
      ],
    }
  );
  joint.shapes.example.GroupView = joint.dia.ElementView;

  var namespace = joint.shapes;
  var graph = new joint.dia.Graph({}, { cellNamespace: namespace });
  var paper = new joint.dia.Paper({
    el: document.getElementById("paper"),
    model: graph,
    cellViewNamespace: namespace,
    defaultConnectionPoint: { name: "boundary" },
    defaultAnchor: { name: "center" },
  });

  // Setup
  var e1 = new joint.shapes.example.Group();
  e1.position(100, 100);
  var a1 = new joint.shapes.standard.Rectangle();
  var a2 = new joint.shapes.standard.Rectangle();
  a1.size(50, 50);
  a2.size(70, 30);
  var l1 = new joint.shapes.standard.Link();
  l1.source(a1).target(a2);
  graph.addCells([e1, a1, a2, l1]);
  e1.embed(a1);
  e1.embed(a2);
  a1.position(20, 10, { parentRelative: true });
  a2.position(90, 30, { parentRelative: true });
  e1.fitEmbeds({ padding: { top: 40, left: 10, right: 10, bottom: 10 } });

  var e2 = new joint.shapes.example.Group();
  e2.position(500, 200);
  var a3 = new joint.shapes.standard.Rectangle();
  var a4 = new joint.shapes.standard.Rectangle();
  a3.size(50, 50);
  a4.size(70, 30);
  var l2 = new joint.shapes.standard.Link();
  l2.source(a3).target(a4);
  graph.addCells([e2, a3, a4, l2]);
  e2.embed(a3);
  e2.embed(a4);
  a3.position(20, 10, { parentRelative: true });
  a4.position(90, -20, { parentRelative: true });
  e2.fitEmbeds({ padding: { top: 40, left: 10, right: 10, bottom: 10 } });
  toggleCollapse(e2);

  var l = new joint.shapes.standard.Link();
  l.source(e1).target(e2);
  l.addTo(graph);

  // Collapse / Expand
  function toggleCollapse(group) {
    var graph = group.graph;
    if (!graph) return;
    var embeds;
    if (group.get("collapsed")) {
      // EXPAND
      var subgraph = group.get("subgraph");
      // deserialize subgraph
      var tmpGraph = new joint.dia.Graph();
      tmpGraph.addCells(subgraph);
      embeds = tmpGraph.getCells();
      tmpGraph.removeCells(embeds);
      // set relative position to parent
      embeds.forEach(function (embed) {
        if (embed.isLink()) return;
        var diff = embed.position().offset(group.position());
        embed.position(diff.x, diff.y);
      });
      graph.addCells(embeds);
      embeds.forEach(function (embed) {
        if (embed.isElement()) {
          group.embed(embed);
        } else {
          embed.reparent();
        }
      });
      group.set("collapsed", false);
      group.fitEmbeds({
        padding: { top: 40, left: 10, right: 10, bottom: 10 },
      });
      group.attr("tool/stroke", "blue");
    } else {
      // COLLAPSE
      embeds = graph.getSubgraph(group.getEmbeddedCells());
      embeds.sort(function (a) {
        return a.isLink() ? 1 : -1;
      });
      graph.removeCells(embeds);
      // get relative position to parent
      embeds.forEach(function (embed) {
        if (embed.isLink()) return;
        var diff = embed.position().difference(group.position());
        embed.position(diff.x, diff.y);
      });
      // serialize subgraph
      group.set(
        "subgraph",
        embeds.map(function (embed) {
          return embed.toJSON();
        })
      );
      group.resize(100, 100);
      group.set("collapsed", true);
      group.size(100, 40);
      group.attr("tool/stroke", "red");
    }
  }

  // event handler for task group button
  paper.on("element:collapse", function (elementView, evt) {
    evt.stopPropagation();
    toggleCollapse(elementView.model);
  });

}
0

There are 0 answers