3

I use to mxgraph-js. I want to show tooltip, so I coded as below. But tooltip doesn't show. What is the wrong.

graph.setTooltips(true);
graph.getTooltipForCell = function(cell)
{
    return 'this is a tooltip';
}

I tried to below code,

graph.setTooltips(true);
graph.getTooltip = function(state){
   var cell = state.cell;
   var model = this.getModel(),

   if(model.isEdge(cell)){
      var source = this.getLabel(model.getTerminal(cell,true));
      var target = this.getLabel(model.getTerminal(cell,false));
      return source + "->" + target;
   else return this.getLabel(cell);

But tooltip is not show.

dumpman
  • 131
  • 11

4 Answers4

3

I know it's been a while but I've seen this question around a lot and I just struggled with it myself so I'll try to answer it even if I'm certainly too late.

Arnaud's answer was actually the right answer, despite being a bit short.

Your first snippet of code was right. The problem lies in mxGraph and not your implementation.

The problem arises when your graph is contained in something else in your page, because mxGraph adds the tooltip to the body instead of the graph container.

To avoid that you can override init() function of mxTooltipHandler like this :

mxTooltipHandler.prototype.init = function() {
    if (document.body != null) {
      const container = document.getElementById("graphcontainer");
      this.div = document.createElement("div");
      this.div.className = "mxTooltip";
      this.div.style.visibility = "hidden";

      container.appendChild(this.div);

      mxEvent.addGestureListeners(
        this.div,
        mxUtils.bind(this, function(evt) {
          this.hideTooltip();
        })
      );
    }
  };

Here I used "graphcontainer" but use the id of your graph container.

This will allow the tooltip to show. But it will most likely be in the wrong place. To avaoid that I also overrode the reset function like this :

mxTooltipHandler.prototype.reset = function(
    me,
    restart,
    state
  ) {
    if (!this.ignoreTouchEvents || mxEvent.isMouseEvent(me.getEvent())) {
      this.resetTimer();
      state = state != null ? state : this.getStateForEvent(me);

      if (
        restart &&
        this.isEnabled() &&
        state != null &&
        (this.div == null || this.div.style.visibility == "hidden")
      ) {
        var node = me.getSource();
        if(!node.attributes.x){
          return
        }
        var x = parseInt(node.attributes.x.nodeValue);
        var y = parseInt(node.attributes.y.nodeValue);

        var stateSource =
          me.isSource(state.shape) || me.isSource(state.text);

        this.thread = window.setTimeout(
          mxUtils.bind(this, function() {
            if (
              !this.graph.isEditing() &&
              !this.graph.popupMenuHandler.isMenuShowing() &&
              !this.graph.isMouseDown
            ) {

              var tip = this.graph.getTooltip(state, node, x, y);
              this.show(tip, x, y);
              this.state = state;
              this.node = node;
              this.stateSource = stateSource;
            }
          }),
          this.delay
        );
      }
    }
  };

I'm not sure it's the best way to achieve this, but it worked for me.

Schnaffon
  • 101
  • 1
  • 10
1

On Angular add title to div and set it:

HTML:

<div #container title={{tooltip}} id="mxgraph-diagram-container"></div>

TS:

this.graph.getTooltipForCell = (cell) => {
    this.tooltip = cell.value;
    return cell.value;
}
Tiziano
  • 11
  • 1
0

I had the same problem in my project https://github.com/algenty/grafana-flowcharting

I have rewrite getTooltip funtion because by default it try to add child div to document instead parent div, you need too mxtooltip class https://github.com/algenty/grafana-flowcharting/blob/f15_general/src/Graph_over.js

BR Arnaud

Arnaud
  • 11
  • hey Arnaud! your answer looks good and might actually solve the problem. However, please edit it so that in addition to your brief explanation, you also take the OP's (original poster's) code and actually show him what mind of changes he should make to make it work. If you can't do that, please add a section of your own code (existing or just an example you create now) that DOES work, so he can see how you solved it. – Gibor Sep 08 '19 at 14:56
0

I've used answer from @arnud and with little fixes 1. It will show tooltips for edges 2. You have to add .maTooltip { position : absolute } in order to display tooltip

import { Graph } from './types';

declare var mxTooltipHandler, mxEvent, mxUtils;

export const initTooltips = (graph: Graph, graphElementId: string) => {

    graph.setTooltips(true);
    graph.getTooltipForCell = function(cell) {
        return 'this is a tooltip';
    };

    mxTooltipHandler.prototype.init = function() {
        if (document.body != null) {
            const container = document.getElementById(graphElementId);
            this.div = document.createElement('div');
            this.div.className = 'mxTooltip';
            this.div.position = 'absolute';
            this.div.style.visibility = 'hidden';

            container.appendChild(this.div);

            mxEvent.addGestureListeners(
                this.div,
                mxUtils.bind(this, function(evt) {
                    this.hideTooltip();
                })
            );
        }
    };

    mxTooltipHandler.prototype.reset = function(me, restart, state) {
        const evt = me.getEvent();
        if (!this.ignoreTouchEvents || mxEvent.isMouseEvent(me.getEvent())) {
            this.resetTimer();
            state = state != null ? state : this.getStateForEvent(me);

            if (
                restart &&
                this.isEnabled() &&
                state != null &&
                (this.div == null || this.div.style.visibility == 'hidden')
            ) {
                const node = me.getSource();

                const x = evt.offsetX;
                const y = evt.offsetY;

                const stateSource =
                    me.isSource(state.shape) || me.isSource(state.text);

                this.thread = window.setTimeout(
                    mxUtils.bind(this, function() {
                        if (
                            !this.graph.isEditing() &&
                            !this.graph.popupMenuHandler.isMenuShowing() &&
                            !this.graph.isMouseDown
                        ) {
                            let tip = this.graph.getTooltip(state, node, x, y);
                            this.show(tip, x, y);
                            this.state = state;
                            this.node = node;
                            this.stateSource = stateSource;
                        }
                    }),
                    this.delay
                );
            }
        }
    };
};
baio
  • 1,102
  • 2
  • 12
  • 20