首页 > 解决方案 > 如何使用 Typescript 在 React 应用程序内的 mxGraph 中包含 mxFloorplan.js?

问题描述

所以我正在尝试创建一个简单的反应应用程序来呈现我从文件加载的 mxGraph。我可以加载模型,但某些形状无法正确渲染。问题是它们是一个特定的形状,是floorplan 包的一部分,我找不到在我的代码中包含这些形状的方法。

ps.:我是使用 mxGraph 的新手。

我尝试过的事情

  1. 我尝试的第一件事是将mxFloorplan.js文件下载到我的应用程序中,然后将其导入,如下所示:
// App.tsx
import './models/mxFloorplan'

const mx = factory({
  mxBasePath: './models'
})

let graph: mxGraph
...

因为关于扩展 mxShape 的文档显示我应该注册一个新形状:mxCellRenderer.registerShape('customShape', CustomShape);而 mxFloorplan.js 文件就是这样做的。然后我简单地将其添加到文件的开头:

// mxFloorplan.js
import Graph, {
    mxShape,
    mxUtils,
    mxCellRenderer,
    mxPoint
} from 'mxgraph'
...

但后来我得到这个错误: 错误 mxCellRenderer 未定义

  1. 然后我认为我需要将 mxCellRenderer 链接到我的图形实例?所以我尝试将其中一个形状定义移动到 App.jsx 中进行测试:
// App.jsx
const mx = factory({
  mxBasePath: './models'
})

let graph: mxGraph

function mxFloorplanWall(bounds: any, fill: any, stroke: any, strokewidth: any)
{
    mx.mxShape.call(this); <-- Error: "Expected 2 args, but got one"
    this.bounds = bounds;
    this.fill = fill;
    this.stroke = stroke;
    this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
* Extends mxShape.
*/
mx.mxUtils.extend(mxFloorplanWall, mxShape); <-- Error: "Property 'extend' does not exist on type mxUtils

// ... more code

mx.mxCellRenderer.registerShape(mxFloorplanWall.prototype.cst.WALL, mxFloorplanWall); <-- Error: mxFloorplanWall type not compatible with expected.

真的不知道如何解决这些问题。在我的研究中,我只找到对 的引用 mxCellRenderer.registerShape('name', CustomShape),所以对其余部分不太确定。

它看起来如何

这是图表的样子(请忽略箭头和标签): 来自draw.io的图表

这是我实际渲染的内容(“黑匣子”有shape=shape=mxgraph.floorplan.wallU): 用 React 渲染的图表

标签: reactjsmxgraph

解决方案


https://jgraph.github.io/mxgraph/docs/js-api/files/shape/mxShape-js.html中所述,您必须将构造函数传递给mxCellRenderer.registerShape

function CustomShape() { }

CustomShape.prototype = new mxShape();
CustomShape.prototype.constructor = CustomShape;

// To register a custom shape in an existing graph instance,
// one must register the shape under a new name in the graph’s cell renderer
// as follows:
mxCellRenderer.registerShape('customShape', CustomShape);
}

我猜您的问题来自错误的 drawio 代码端口(使用非常旧的 Javscript 语法)并且与 React 完全无关。我目前还不清楚您到底实施了什么。这里有一些提示。

如果您使用 TypeScript,则mxCellRenderer.registerShape签名由 mxgraph 类型https://github.com/typed-mxgraph/typed-mxgraph/blob/v0.0.5-0/view/mxCellRenderer.d.ts#L83强制执行。将 mxFloorplanWall 代码移植到 Typescript 时,您应该有一个如下所示的构造函数(请避免任何!)

export class mxFloorplanWall extends mxShape { // or extends mx.mxShape depending how you manage mxgraph imports

  public constructor(bounds: mxRectangle, fill: string, stroke: string, strokewidth: number) {
    super(bounds, fill, stroke, strokewidth);
  }
...
}

调用 super 直接设置超类中的参数,避免错误

// mx.mxUtils.extend(mxFloorplanWall, mxShape); <-- Error: "Property 'extend' does not exist on type mxUtils
// avoid mx.mxShape.call(this); <-- Error: "Expected 2 args, but got one"

如果您使用 Javascript,则更喜欢使用 ES6 类语法来声明 mxFloorplanWall 类。


推荐阅读