Highlight multiple cells using mxCellHighlight
Asked Answered
O

2

5

I would like to highlight a sequence of cells in a draw.io diagram in chromeless mode. The objective is to illustrate a path which includes vertices and edges:

enter image description here

Using the helper class mxCellHighlight, I am basically trying the following:

var highlight = new mxCellHighlight(graph, '#ff0000', 2);
highlight.highlight(graph.view.getState(cell1)));
highlight.highlight(graph.view.getState(cell2)));
...

This does not work, only one cell gets highlighted at a time. I am aware the resetHandler hides the highlighting marker when the current root of a cell changes, but unfortunately I fail to override it properly to prevent this effect.

Any help is highly appreciated, thanks.

Orvieto answered 17/12, 2020 at 10:57 Comment(0)
C
6

mxCellHighlight can highlight only one cell. You can simply check out its source code, it's quite small (related lines)

So, I could think of the following options:

Create multiple highlights, like this:

var h1 = new mxCellHighlight(graph, '#ff0000', 2);
h1.highlight(graph.view.getState(cell1)));
var h2 = new mxCellHighlight(graph, '#ff0000', 2);
h2.highlight(graph.view.getState(cell2)));

You can save them in array to reset later, if needed. Utterly ineffective, but simple. Or you could modify class to support multiple shapes. But this would be probably more complicated, basically it seems to be as good as writing it from scratch.

Alternatively, you could try selecting shapes, and change the selection style to look like "highlight" by changing some constants. This can work if you don't care about selection. Check out the list of the constants you can redefine here. Basically, I mean something like this:

mxConstants.HANDLE_SIZE = 0;
mxConstants.VERTEX_SELECTION_COLOR = '#00ff0080';
mxConstants.EDGE_SELECTION_COLOR = '#00ff0080';
mxConstants.EDGE_SELECTION_STROKEWIDTH = 2;
mxConstants.VERTEX_SELECTION_STROKEWIDTH = 2;
mxConstants.VERTEX_SELECTION_DASHED = false;
mxConstants.EDGE_SELECTION_DASHED = false;

graph.getSelectionModel().setCells([cell1, cell2]);

Alternatively, you can do no cheating and go modify the cell renderer (mxSvgCanvas2D.prototype.rect I guess in your case), that, depending on your shape, will render the highlight. This is probably a bit complicated way, but this way you'll be able to control your shape with style ("highlighted") for example, so you can just set that value in code for the style and then read from the renderer, and add svg filter for example (with real "glow" effect, if you want it).

Collusion answered 27/12, 2020 at 23:56 Comment(0)
R
1

As explained by @Nikolay, mxCellHighlight is to highlight a single cell: it adds an additional shape to the one you want to highlight and manages listeners (mouse enter/leave for you). You can also check if mxCellTracker and mxCellMarker can fit your need.

Hightlighting can be seen as changing the style of the cells, so you could change the style of the cells directly on the model. Assuming you know the cells you want to highlight i.e. you have an array of cells, you can do the following to update the cell opacity with https://github.com/jgraph/mxgraph/blob/v4.2.2/javascript/src/js/util/mxUtils.js#L3430

const cells = []; // the cells you want to highlight

graph.getModel().beginUpdate(); // required if you want to apply the highlight to all cells in a single transaction
  try {
    mxUtils.setCellStyles(graph.getModel(), cells, 'opacity', 20);
  } finally {
    // Updates the display
    graph.getModel().endUpdate();
  }

Notice that mxUtils.setCellStyles manages an inner transaction and only let to change a single style key/value. So you may have to call mxUtils.setCellStyles several times or replicate the logic of setting style keys/values as in https://github.com/jgraph/mxgraph/blob/v4.2.2/javascript/src/js/util/mxUtils.js#L3453 or create a dedicate style and directly applies it to the cell with model.setStyle(cells[i], style). mxUtils provides several functions to update style from string or array to help you on that topic.

To remove the applied style, you probably would have to keep the non hightlighted style value to reapply it afterwards.

I have used this technic to highlight path as shown in the following screencasts (the path i.e the cells to hightligh is computed on mouse enter and managed by a graph mouse listener https://github.com/jgraph/mxgraph/blob/v4.2.2/javascript/src/js/view/mxGraph.js#L12628)

Code available in https://github.com/tbouffard/mxgraph-js-playground/pull/1 (uggly, it was a POC)

Screencast content

  • 1st highlight a cell (in red) and apply an overlay to it, then remove it
  • 2nd activate path detection: cells opacitity changed on cells of the detected path

highlight path elements

Retrogressive answered 28/12, 2020 at 14:35 Comment(2)
Unfortunately, it is not possible to split the bounty, so I assigned it to @Collusion whose simple approach was a bit more suited to what I was looking for. Anyway, I appreciate your detailed answer, @redfish4ktc!Orvieto
ok, no problem, at least, it may help others in the future.Retrogressive

© 2022 - 2024 — McMap. All rights reserved.