preface

Q: What is bPMn.js? 🤔 ️

Bpmn. js is a BPMN2.0 rendering toolkit and Web modeler that allows you to draw flowcharts in the front end.

Q: Why did I write this series? 🤔 ️

Due to the business needs of the company, bPMN. js is used in the project. However, as the developer of BPMN. js is a foreign friend, there are few textbooks and no detailed documents on this aspect in China. So a lot of ways to use a lot of pits have to find their own. After mulling it over, I decided to write a series of textbooks on it to help more bPMn.js users or developers who want to find a good way to draw flowcharts. It is also a kind of consolidation of their own.

Because it is a series of articles, so the update may be more frequent, if you accidentally brush and not what you need also please understand 😊.

Don’t ask for praise 👍 don’t ask for heart ❤️. I only hope to have a little help for you.

The HTTP request article

In the previous chapter we introduced the basics of bPMn.js and how to use it in Vue. If you don’t know bPMn.js, please go to:

This chapter mainly explains how bPMn.js interacts with the background. By learning this chapter, you can learn:

Data is retrieved and rendered via HTTP requests

Send the latest edited BPMN to the background

After editing, save as a BPMN file or SVG file

Data is retrieved and rendered via HTTP requests

In the previous case, it was always an XML string that was written to death locally, so it’s definitely not going to be used this way.

What our team is doing now is:

  • The front end makes a request and gets onebpmnAddress of file
  • Once you get the address, use itaxiosRequest this address to getxmlThe string (named here asbpmnXmlStr)
  • useimportXMLMethod converts a string to a graph and renders it.

To simulate the above execution environment I followed up the project example from the previous chapter bPMn-vue-basic and created a file axios.vue in the Components folder and configured the route:

const routes = [
	...
	{
		path: '/axios'.component: (a)= > import('. /.. /components/axios')}]Copy the code

Also install AXIOS in the project for the front-end to send HTTP requests:

npm i axios --save-D
Copy the code

The loading effect is shown in the HTML code before the user gets the XML:

// axios.vue
<template>
  <div class="containers">
    <div class="loading" v-if="loading">
        Loading...
    </div>
    <template v-else>
        <div class="canvas" ref="canvas"></div>
        <div id="js-properties-panel" class="panel"></div>
    </template>
  </div>
</template>
Copy the code

Then import axios in js and define a getXmlUrl method to simulate getting the BPMN file address:

// axios.vue
<script>. import axiosfrom 'axios'
import { xmlStr } from '.. /mock/xmlStr' // Import a local XML string, to be used if no background data is retrieved

export default{... data () {return{... loading:true.xmlUrl: ' '.defaultXmlStr: xmlStr
		}
	},
	methods: {
  	async init () {
      this.loading = true
      this.xmlUrl = await this.getXmlUrl()
      console.log(this.xmlUrl)
      this.loading = false
      this.$nextTick((a)= > { // Wait for DOM updates before initializing the workflow
      	this.initBpmn()
    	})
    },
    getXmlUrl () { // This method simulates asking the background to obtain the BPMN file address
        return new Promise(resolve= > {
            setTimeout((a)= > {
                const url = 'https://hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/bpmnMock.bpmn' // Simulate a network request for an address
                resolve(url)
            }, 1000)
        })
    },
    initBpmn () {
      ... // Here is the code to initialize the workflow
      this.createNewDiagram()
    },
    async createNewDiagram () {
        const that = this
        let bpmnXmlStr = ' '
        if (this.xmlUrl === ' ') { // If there is no data in the background, use the default XML
            bpmnXmlStr = this.defaultXmlStr
            this.transformCanvas(bpmnXmlStr)
        } else {
            let res = await axios({
                method: 'get'.timeout: 120000.url: that.xmlUrl,
                headers: { 'Content-Type': 'multipart/form-data'}})console.log(res)
            bpmnXmlStr = res['data']
            this.transformCanvas(bpmnXmlStr)
        }
    },
    transformCanvas(bpmnXmlStr) {
      // Convert the string to a graph for display
      this.bpmnModeler.importXML(bpmnXmlStr, (err) => {
        if (err) {
          console.error(err)
        } else {
          this.success()
        }
        // Let the graph adapt to the screen
        var canvas = this.bpmnModeler.get('canvas')
        canvas.zoom('fit-viewport')
      })
    },
    success () {
        console.log('Created successfully! ')}}}</script>
Copy the code

You can directly use the path I simulated in the example to get the address:

Hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/bpmnMock.bp…

Case Git address: lindaidai-bpmn.js Test case axios.vue

Send the latest edited BPMN to the background

Above we explained how to get the data from the background and render it to the page, but that’s not enough.

You may need to store the latest BPMN after editing in the background.

This feature involves event binding in BPMn.js, where the front end needs to bind an event to the graph to detect changes in the graph and get the latest XML information.

Create a save.vue file and copy in the contents of axios.vue.

Add an addBpmnListener() binding event method to the Success () method:

// save.vue
<script>
   success () {
    	console.log('Created successfully! ')
    	this.addBpmnListener()
  	},
		// Add a binding event
    addBpmnListener () {
      const that = this
      // Bind the graph to an event that will be triggered when the graph changes
      this.bpmnModeler.on('commandStack.changed'.function () {
        that.saveDiagram(function(err, xml) {
          console.log(xml) // This is the latest XML information})})},// Download in BPMN format,done is a function passed in when called
    saveDiagram(done) {
      // Pass the incoming done to the saveXML function call of the BPMN prototype
      this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
        done(err, xml)
      })
    }
</script>

Copy the code

As shown in the figure:

img2

Case Git address: lindaidai-bpmn.js Test case save.vue

After editing, save as a BPMN file or SVG file

Here we listen for the commandStack.changed event to get the latest XML information in real time.

Once you have this information, you can choose to ask the backend to pass them the latest XML every time the graph changes;

Alternatively, you can save it to a variable, give it a save button on the page, and pass it to the background when the button is clicked.

Perhaps you don’t need to request to the background at all and want to download it locally as a BPMN or SVG file.

Add two save buttons to the save.vue case above:

img3

Then modify the HTML code:

// save.vue
<template>.<ul class="buttons">
    <li>
    	<a ref="saveDiagram" href="javascript:" title="Save as BPMN">Save as BPMN</a>
    </li>
    <li>
    	<a ref="saveSvg" href="javascript:" title="Save as SVG">Save as SVG</a>
    </li>
  </ul>
</template>
Copy the code

Add to the js code:

// save.vue
<script>. addBpmnListener () {const that = this
      // Get the A tag dom node
      const downloadLink = this.$refs.saveDiagram
      const downloadSvgLink = this.$refs.saveSvg
        // Bind the graph to an event that will be triggered when the graph changes
      this.bpmnModeler.on('commandStack.changed'.function () {
        that.saveSVG(function(err, svg) {
            that.setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg)
        })
        that.saveDiagram(function(err, xml) {
            that.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml)
        })
      })
  },
  // Download in SVG format,done is a function passed in when called
  saveSVG(done) {
      // Pass the incoming done to the saveSVG function call of the BPMN prototype
      this.bpmnModeler.saveSVG(done)
  },
  // Download in BPMN format,done is a function passed in when called
  saveDiagram(done) {
      // Pass the incoming done to the saveXML function call of the BPMN prototype
      this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
          done(err, xml)
      })
  },
  // This function is called when the graph changes, and the data is the graph's XML
  setEncoded(link, name, data) {
      // Convert the XML to a URI and download the required one
      const encodedData = encodeURIComponent(data)
      // Use the href tag to download the file. // Use the href tag to download the file
      console.log(link, name, data)
      let xmlFile = new File([data], 'test.bpmn')
      console.log(xmlFile)
      if (data) {
        link.className = 'active'
        link.href = 'data:application/bpmn20-xml; charset=UTF-8,' + encodedData
        link.download = name
      }
  }
</script>
Copy the code

If you want to save the vue, please give a Star🌟, thank you 😊

After the language

For the full catalogue of the series, please check here: “The most detailed BPMN.js textbook in the whole Web”.

Series related recommendations:

“The most detailed BPMN.JS textbook in the Whole Web – Basic Chapter”

The most detailed BPMN.JS textbook in the whole Web – Events

The most detailed BPMN.js textbook on the Whole web – Renderer

The most detailed BPMN.js textbook -contextPad

“The most detailed BPMN. js textbook in the whole web – Editing and Deleting nodes”