Rendering subprocess

Hello,

I tried to color the subprocess green during bpmn-js-example-custom-rendering, but somehow it doesn’t work. In the CustomRenderer I changed every occurrence from bpmn:Task to bpmn:Subprocess.

Am I missing something?

import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer';

import {
  append as svgAppend,
  attr as svgAttr,
  classes as svgClasses,
  create as svgCreate,
  remove as svgRemove
} from 'tiny-svg';

import {
  getRoundRectPath
} from 'bpmn-js/lib/draw/BpmnRenderUtil';

import { is } from 'bpmn-js/lib/util/ModelUtil';
import { isAny } from 'bpmn-js/lib/features/modeling/util/ModelingUtil';

const HIGH_PRIORITY = 1500,
      TASK_BORDER_RADIUS = 2;


export default class CustomRenderer extends BaseRenderer {
  constructor(eventBus, bpmnRenderer) {
    super(eventBus, HIGH_PRIORITY);

    this.bpmnRenderer = bpmnRenderer;
  }

  canRender(element) {

    // only render tasks and events (ignore labels)
    return isAny(element, [ 'bpmn:Subprocess', 'bpmn:Event' ]) && !element.labelTarget;
  }

  drawShape(parentNode, element) {
    const shape = this.bpmnRenderer.drawShape(parentNode, element);

    if (is(element, 'bpmn:Subprocess')) {
      const rect = drawRect(parentNode, 100, 80, TASK_BORDER_RADIUS, '#52B415');

      prependTo(rect, parentNode);

      svgRemove(shape);

      return shape;
    }

    const rect = drawRect(parentNode, 30, 20, TASK_BORDER_RADIUS, '#cc0000');

    svgAttr(rect, {
      transform: 'translate(-20, -10)'
    });

    return shape;
  }

  getShapePath(shape) {
    if (is(shape, 'bpmn:Subprocess')) {
      return getRoundRectPath(shape, TASK_BORDER_RADIUS);
    }

    return this.bpmnRenderer.getShapePath(shape);
  }
}

CustomRenderer.$inject = [ 'eventBus', 'bpmnRenderer' ];

// helpers //////////

// copied from https://github.com/bpmn-io/bpmn-js/blob/master/lib/draw/BpmnRenderer.js
function drawRect(parentNode, width, height, borderRadius, strokeColor) {
  const rect = svgCreate('rect');

  svgAttr(rect, {
    width: width,
    height: height,
    rx: borderRadius,
    ry: borderRadius,
    stroke: strokeColor || '#000',
    strokeWidth: 2,
    fill: '#fff'
  });

  svgAppend(parentNode, rect);

  return rect;
}

// copied from https://github.com/bpmn-io/diagram-js/blob/master/lib/core/GraphicsFactory.js
function prependTo(newNode, parentNode, siblingNode) {
  parentNode.insertBefore(newNode, siblingNode || parentNode.firstChild);
}

What exactly doesn’t work?

Also, have you noticed that there is an API for coloring elements:

modeling.setColor(myElement, {
  fill: 'red',
  stroke: 'blue'
});

Hello,

I uploaded my project and added your tip but subprocesses are still black bordered, although I used modeling.
https://github.com/TestUser-coder/bpmn-js-example-custom-rendering.git

I think there’s a misunderstanding.

:no_entry: Please do not do this:

drawShape(parentNode, element) {
    const shape = this.bpmnRenderer.drawShape(parentNode, element);

    modeling.setColor(shape, {
      fill: 'red',
      stroke: 'blue'
    });
    
  }

This is an anti-pattern which will get you into trouble. We don’t execute commands (which is what modeling.setColor will do) when rendering. When rendering we merely visualize our model (initially and whenever it has been changed). modeling.setColor is a way to change that model.

Do you want all of your sub-processes to always be rendered in a specific way or do you want to be able to choose the sub-processes that should be rendered in a specific way?

Hello,

I want both later. I want to render the events as in the example and color only selected subprocesses.
I mean with selected subprocesses something like the example with the suitablityscore. So that only the subprocesses with score = 100 are colored in such a way.

You can implement both of these features in the renderer.