Skip to main content

Vue

If you want to integrate JointJS+ with Vue, you're in the right place! This tutorial will help you create a project, and after a few minutes, have a working JointJS+ Vue application.

The source code for this tutorial can be found on GitHub. Looking for a different version of your favourite framework? Be sure to checkout the different branches of the repository to see if you find what you need.

info

This tutorial adds JointJS+ via a joint-plus.tgz installable archive. Sign up to receive yours! If using the open-source JointJS library, you can still adapt the following integration steps to Vue and the @joint/core package. Just follow the JointJS code in our Quickstart guide instead.

Create a Vue project

In order to create our Vue project, we will follow the recommended setup in the Vue documentation.

npm create vue@latest

We will be prompted to choose some options about project configuration. Select the following:

  • Project Name: › joint-plus-tutorial-vue
  • Add TypeScript? › Yes
  • Add JSX Support? › No
  • Add Vue Router for Single Page Application development? › No
  • Add Pinia for state management? › No
  • Add Vitest for Unit Testing? › No
  • Add an End-to-End Testing Solution? › No
  • Add ESLint for code quality? › Yes
  • Add Prettier for code formatting? › Yes

After the setup is complete, we can change to the correct directory.

cd joint-plus-tutorial-vue

Add JointJS+ to the Vue project

We can add JointJS+ to the project by placing the installable archive joint-plus.tgz in the root directory of the Vue application, and installing @joint/plus via our preferred package manager. All project dependencies will be installed alongside @joint/plus too.

npm add joint-plus.tgz

Build the Vue application

Before we get started, let's clean up the existing project a little bit.

  • Open src/App.vue
    • Remove everything inside the script, template, and style tags
  • Delete the src/components directory
  • Delete the assets/base.css file
  • Open assets/main.css, and delete all contents

The current state of App.vue should be as follows:

<script setup lang="ts"></script>

<template></template>

<style scoped></style>

Let's add some scoped styles by placing the following CSS rules in within the style tags.

<style scoped>
.canvas {
width: 100%;
height: 100%;
}

.canvas:deep(.joint-paper) {
border: 1px solid #a0a0a0;
}
</style>

We'll also add some global styles in main.css.

@import '@joint/plus/joint-plus.css';

body {
height: 100vh;
box-sizing: border-box;
margin: 0;
}

#app {
height: 100%;
}

Now that the basic setup is completed, we are ready to create our JointJS+ Vue application. We will take advantage of 2 Vue features in our App.vue component. onMounted allows us to run code after the component is first rendered in the DOM, and ref allows us to interact with our component programmtically via a reference to a rendered element.

The relevant JointJS+ code is also imported.

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { dia, ui, shapes } from '@joint/plus';

const canvas = ref<Element | null>(null);

onMounted(() => {});
</script>

<template>
<div class="canvas" ref="canvas"></div>
</template>

<style scoped>
.canvas {
width: 100%;
height: 100%;
}

.canvas:deep(.joint-paper) {
border: 1px solid #a0a0a0;
}
</style>

After our ref declaration, we can add the Graph, Paper, and PaperScroller.

const graph = new dia.Graph({}, { cellNamespace: shapes });

const paper = new dia.Paper({
model: graph,
background: {
color: '#F8F9FA',
},
frozen: true,
async: true,
cellViewNamespace: shapes
});

const scroller = new ui.PaperScroller({
paper,
autoResizePaper: true,
cursor: 'grab'
});

Next, let's render our PaperScroller component, create a simple Rectangle shape, and add it to our Graph.

scroller.render();

const rect = new shapes.standard.Rectangle({
position: { x: 100, y: 100 },
size: { width: 100, height: 50 },
attrs: {
label: {
text: 'Hello World'
}
}
});

graph.addCell(rect);

Inside the onMounted lifecycle function, let's append the PaperScroller to our ref that we created earlier. Afterwards, we can position the Paper in the center of the PaperScroller viewport, and unfreeze the Paper.

onMounted(() => {
canvas.value?.appendChild(scroller.el);
scroller.center();
paper.unfreeze();
});

That's all it takes to create a simple JointJS+ Vue application. The final application code is as follows:

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { dia, ui, shapes } from '@joint/plus';

const canvas = ref<Element | null>(null);

const graph = new dia.Graph({}, {
cellNamespace: shapes
});

const paper = new dia.Paper({
model: graph,
background: {
color: '#F8F9FA'
},
frozen: true,
async: true,
cellViewNamespace: shapes
});

const scroller = new ui.PaperScroller({
paper,
autoResizePaper: true,
cursor: 'grab'
});

scroller.render();

const rect = new shapes.standard.Rectangle({
position: { x: 100, y: 100 },
size: { width: 100, height: 50 },
attrs: {
label: {
text: 'Hello World'
}
}
});

graph.addCell(rect);

onMounted(() => {
canvas.value?.appendChild(scroller.el);
scroller.center();
paper.unfreeze();
});
</script>

<template>
<div class="canvas" ref="canvas"></div>
</template>

<style scoped>
.canvas {
width: 100%;
height: 100%;
}

.canvas:deep(.joint-paper) {
border: 1px solid #a0a0a0;
}
</style>

To serve our JointJS+ Vue application, we can use npm run dev. Lastly, let's visit the url suggested by our terminal in the browser, and we should see our JointJS+ Vue application!

See it in action

Here is the example of a Vue application with integrated JointJS+:

Frequently asked questions

Do you have demo X available in Vue?

We have a few demos written specifically in Vue, but not all of them. However, the modular nature of JointJS makes it possible to adapt any JointJS example to Vue.

Learn more...

Vue examples in your trial package:

In the JointJS+ trial package, you can find Vue versions of our Chatbot and KitchenSink applications:

  • Chatbot (online demo) - source code can be found in the unzipped JointJS+ package in the folder apps/Chatbot/VueTs.

  • KitchenSink (online demo) - source code can be found in the unzipped JointJS+ package in the folder apps/KitchenSink/VueTs. An equivalent version written in JavaScript can be found in the unzipped JointJS+ package in the folder apps/KitchenSink/VueJs.

Vue examples in our Vue tutorial GitHub repository:

We also provide our Diagram Index and Tabs demos in Vue. The source code can be found on GitHub at the links below:

tip

Make sure to check out the other branches of the repository for additional Vue content.

Other Vue content:

We also have a Vue tutorial, which covers the basics of the integration - see above.