process-analytics / bpmn-visualization-js

A TypeScript library for visualizing process execution data on BPMN diagrams
https://process-analytics.github.io/bpmn-visualization-js/
Apache License 2.0
224 stars 30 forks source link

[FEAT] Configure programatically the style of a Shape/Edge #1030

Closed csouchet closed 1 year ago

csouchet commented 3 years ago

Is your feature request related to a problem? Please describe.

We want to customize a Shape/Edge giving the CSS content programmatically, and not with the CSS class (already managed by #942).

Describe the solution you'd like

To do that, we can do something like done on the G6 Shape.

POC

2539

Decisions

For a first iteration, we decided to have this method as API signature:

updateStyle(bpmnElementIds: string | string[], style: ShapeStyleUpdate | EdgeStyleUpdate): void;

This method will be available in the BpmnElementsRegistry class. We currently store all the methods related to the manipulation of the elements there. So let's continue to be consistent. We will probably change all the API locations in the future, so there is no need to add a dedicated API object at this time.

Property signatures

Notes:

type ShapeStyleUpdate = {
  fill?: Fill;
  font?: Font;
  opacity?: Opacity;
  stroke?: Stroke;
};
type EdgeStyleUpdate = {
  font?: Font;
  opacity?: Opacity;
  stroke?: Stroke;
};
type Font = {
  color?: string;
  opacity?: Opacity;

  /**
   *  The type of the value is int (in px).
   */
  size?: number;

  family?: string;

  /**
   *  Default: false
   */
  isBold?: boolean;
  /**
   *  Default: false
   */
  isItalic?: boolean;
  /**
   *  Default: false
   */
  isUnderline?: boolean;
  /**
   *  Default: false
   */
  isStrikeThrough?: boolean;
};
type Fill = {
  /**
   * Possible values are all HTML color names or HEX codes, as well as special keywords such as ‘swimlane‘,
   * ‘inherit’ to use the color code of a related cell.
   */
  color: string | 'swimlane';

  // implemented later
  gradient?: Gradient;

  opacity?: Opacity;
};
type Stroke = {
  /**
   * Possible values are all HTML color names or HEX codes, as well as special keywords such as ‘swimlane‘,
   * ‘inherit’ to use the color code of a related cell or ‘none’ for no color.
   */
  color: string | 'swimlane' | 'none';

  /**
   The type of the value is numeric and the possible range is any non-negative value larger or equal to 1.
   The value defines the stroke width in pixels.
   Note: To hide a stroke use strokeColor 'none'.
   */
  width?: number;

  opacity?: Opacity;
};
#### General tasks
- [x] Put the `rounded` of the activities in `StyleConfigurator`, and not `BaseActivityShape`. During the POC, we detected that when updating the styles of an activity, the rounded border are removed. However, the rounded border is kept when configuring "rounded" in the style definition. #2556
- [x] Create a `Opacity` type: see https://github.com/process-analytics/bpmn-visualization-js/pull/2539/files#diff-c477a4e33404498b4aafe8e14f58e809eeb8025d8cadfef0c229743800bea870. This will guide user to set a value in a range from 0 to 100.

Properties

Common
Shape
Edge

See BpmnConnector:
c.setFillColor(mxgraph.mxUtils.getValue(this.style, BpmnStyleIdentifier.EDGE_START_FILL_COLOR, this.stroke));

Tests to implement

As for the API managing the CSS class and the Overlays, we will privilege integration tests over visualization tests. In integration tests, we check that the mxGraph model is updated correctly when setting the style. We can easily check all properties and corner cases. In visual tests, we check that the style is actually updated. We will limit them to a few use cases: this is enough to ensure that we correctly call all the required mxGraph functions. Have as few visualization tests as possible as they are slow to run and harder to maintain that integration tests.

#### Visual tests to create
- [x]  _stroke_ style update (edge and shape)
- [x]  _fill_ style update (shape)
- [x] Several properties at the same time
- [x] Opacity & Color on Font. Use labels.04.fonts.bpmn
- [x] Add theme e2e test with labels.04.fonts.bpmn
- [x] Opacity & Color on Fill

New features that will follow

Non exhaustive list. Here is some features that are already considered:

csouchet commented 1 year ago

Prerequisite:

tbouffard commented 1 year ago

mxGraph examples that dynamically change the style of elements, once one or several elements are selected

https://user-images.githubusercontent.com/27200110/212734282-5d01b9a4-a873-4c44-af09-60cbd201bb46.mp4

tbouffard commented 1 year ago

Feedback from a first implementation in bpmn-visualization-pm4py

See https://github.com/process-analytics/bpmn-visualization-pm4py/issues/3 and https://github.com/process-analytics/bpmn-visualization-pm4py/issues/15 When using model.setStyle, the activities are not rounded anymore. Is it because the rounded property is hard coded in the shape source code and not configured with a style property?

Feedback from the implementation of the CSS classnames

We are setting the property direcly in the state.style and not on the style of the cell in the model, because otherwise it wasn't applied. This is mentioned in https://github.com/process-analytics/bpmn-visualization-js/issues/942#issuecomment-768345971. Here are some details of the way we iterate to find a working implementation. The following seemed not working: