How to use mathjax inside qtip on a cytoscape node

Tags: , , ,



How could I use the Mathjax library within qtip in a cytoscape node?

In the sample code below, the tooltip is displayed when clicking over the top of a node, but the Mathjax is not rendered.

How can this be fixed so that the equation is also shown in the tooltip? The solution in this answer by @peterkrautzberger could be an option, but I didn’t manage to adapt it to this case.

Edited: The answer by @dipenshah solves the original question. However, when extending the sample code allowing for dynamic Mathjax content it doesn’t seem to work. If instead of having a fixed text for the tooltips, the text is taken from the element txt in the definition of the node, then the Mathjax is not rendered. I have modified the code below to show it.

$(function(){
    var cy = window.cy = cytoscape({
        container: document.getElementById('cy'),

        ready: function(){
        },

        elements: {
            nodes: [
                { data: { id: '1', name: 'Node 1', txt: '$$\int f(x)dx=\frac{x^2+y}{2x} + C\,.$$' }, },
                { data: { id: '2', name: 'Node 2', txt: '$$\frac{\partial x^2}{dx}\,.$$' }, }
            ],
            edges: [
                { data: { source: '1', target: '2' } }
            ]
        }
    });

    cy.elements().nodes().qtip({
        content: function(){ return this.data('txt') },
        position: {
            my: 'top center',
            at: 'bottom center'
        },
        style: {
            classes: 'qtip-bootstrap',
            tip: {
                width: 16,
                height: 8
            }
        },
    events: {
      render: function() {
        MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
      }
    }
    });
});
<link rel="stylesheet" type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.css">

<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.js"></script>
<script src="https://unpkg.com/cytoscape-qtip@2.7.1/cytoscape-qtip.js"></script>
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<h3>Cytoscape qtip demo</h3>

<p>
$$int f(x)dx=frac{x^2+y}{2x} + C,.$$
</p>

<div id="cy" style="width:50%; height:50%; position:absolute;"></div>

Answer

Based on updated question: For dynamic content there is no guarantee that by the time MathJax starts processing dom element will be available in the same event callback, so here we can use setTimeout to queue processing after current Javascript calls have finished processing:

render: function(event, api) {
  var tooltip = api.elements.tooltip;
  tooltip.bind('tooltipshow', function(event, api) {
    setTimeout(() => MathJax.Hub.Queue(["Typeset", MathJax.Hub]));
  });
}

Let’s take a look:

$(function() {
  var cy = window.cy = cytoscape({
    container: document.getElementById('cy'),

    ready: function() {},

    elements: {
      nodes: [{
          data: {
            id: '1',
            name: 'Node 1',
            txt: '$$\int f(x)dx=\frac{x^2+y}{2x} + C\,.$$'
          },
        },
        {
          data: {
            id: '2',
            name: 'Node 2',
            txt: '$$\frac{\partial x^2}{dx}\,.$$'
          },
        }
      ],
      edges: [{
        data: {
          source: '1',
          target: '2'
        }
      }]
    }
  });

  cy.elements().nodes().qtip({
    content: function() {
      return this.data('txt');
    },
    position: {
      my: 'top center',
      at: 'bottom center'
    },
    style: {
      classes: 'qtip-bootstrap',
      tip: {
        width: 16,
        height: 8
      }
    },
    events: {
      render: function(event, api) {
        var tooltip = api.elements.tooltip;
        tooltip.bind('tooltipshow', function(event, api) {
          setTimeout(() => MathJax.Hub.Queue(["Typeset", MathJax.Hub]));
        });
      }
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/qtip2/3.0.3/jquery.qtip.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.css">

<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script src="https://unpkg.com/cytoscape-qtip@2.7.1/cytoscape-qtip.js"></script>
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML">
</script>

<h3>Cytoscape qtip demo</h3>

<p>
  $$int f(x)dx=frac{x^2+y}{2x} + C,.$$
</p>

<div id="cy" style="width:50%; height:50%; position:absolute;"></div>

Original answer:

You can use render callback on qtip, to let MathJax know about update:

events: {
  render: function() {
    MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
  }
}

checkout updated code:

$(function() {
  var cy = window.cy = cytoscape({
    container: document.getElementById('cy'),
    elements: {
      nodes: [{
          data: {
            id: '1',
            name: 'Node 1'
          },
        },
        {
          data: {
            id: '2',
            name: 'Node 2'
          },
        }
      ],
      edges: [{
        data: {
          source: '1',
          target: '2'
        }
      }]
    }
  });

  var qtip = cy.elements().nodes().qtip({
    content: '$$int f(x)dx=frac{x^2+y}{2x} + C,.$$',
    position: {
      my: 'top center',
      at: 'bottom center'
    },
    style: {
      classes: 'qtip-bootstrap',
      tip: {
        width: 16,
        height: 8
      }
    },
    events: {
      render: function() {
        MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
      }
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/qtip2/3.0.3/jquery.qtip.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.css">

<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script src="https://unpkg.com/cytoscape-qtip@2.7.1/cytoscape-qtip.js"></script>
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML">
</script>

<h3>Cytoscape qtip demo</h3>

<p>
  $$int f(x)dx=frac{x^2+y}{2x} + C,.$$
</p>

<div id="cy" style="width:50%; height:50%; position:absolute;"></div>


Source: stackoverflow