javascriptnode.jsjointjs

JointJs: Define a custom shape with Node.Js


I am a bit confused by the fact, that in my application it doesn't seem to work to define custom shapes using JointJs in combination with NodeJs. I was trying the following code:

const joint = require('jointjs')

const rectWidth = 130
const rectHeight = 65

joint.shapes.standard.Rectangle.define('examples.CustomRectangle', {
  attrs: {
    body: {
      refWidth: '100%',
      refHeight: '100%',
      strokeWidth: 5,
      stroke: '#000000',
      strokeDasharray: rectWidth + ',' + rectHeight,
      fill: 'white'
    },
    label: {
      textVerticalAnchor: 'middle',
      textAnchor: 'middle',
      refX: '50%',
      refY: '50%',
      fontSize: 14,
      fill: '#333333'
    }
  }
})

console.log(joint)

export class ElementFactory {
  createDatastore (x, y) {
    return new joint.shapes.examples.CustomRectangle({
      position: { x: x - rectWidth / 2, y: y - rectHeight / 2 },
      size: { width: rectWidth, height: rectHeight },
      attrs: {
        text: { textWrap: { width: rectWidth * 0.95, height: 20, ellipsis: true, text: 'Datastore' } }
      }
    })
  }
}

Now my understanding is, that if I require the JointJs module at the beginning of the script, and define a custom shape under it, that it would appear in the module and if needed later (in the factory) I could still access it over the same variable. But instead I get the following error:

Uncaught TypeError: Cannot read property 'CustomRectangle' of undefined

I am also logging the module right after I have defined the custom shape, but it still doesn't show up.

Am I missing something about NodeJs or JointJs? Does anyone have an idea what the problem is? Any help would be appreciated.


Solution

  • I believe the issue is with how you're attaching it to joint.

    Try this:

    joint.shapes.examples.CustomRectangle = joint.shapes.standard.Rectangle.define('examples.CustomRectangle', {
      attrs: {
        body: {
          refWidth: '100%',
          refHeight: '100%',
          strokeWidth: 5,
          stroke: '#000000',
          strokeDasharray: rectWidth + ',' + rectHeight,
          fill: 'white'
        },
        label: {
          textVerticalAnchor: 'middle',
          textAnchor: 'middle',
          refX: '50%',
          refY: '50%',
          fontSize: 14,
          fill: '#333333'
        }
      }
    });
    
    

    Despite what the docs (https://resources.jointjs.com/tutorial/custom-elements) strongly imply, define() doesn't attach it to joint.