Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering MathML on svg using d3.js

Tags:

svg

d3.js

mathml

I am trying to render MathML equations on svg using d3.js. Can anyone help me getting a quadratic equation on svg. I tried doing it using foreign object with no success.

like image 823
Ronak Bhandari Avatar asked Jan 08 '15 12:01

Ronak Bhandari


People also ask

How many points can D3 handle?

D3 charts are most often rendered using SVG, a retained mode graphics model, which is easy to use, but performance is limited. SVG charts can typically handle around 1,000 datapoints.

Does D3 use GPU?

Moreover, we can confirm that D3 transitions do not use any GPU power to slim the process.

Does d3js use canvas?

You could use D3. js entirely for its functional purpose – to transform data that you can then position onto your canvas as you see fit. You could also use D3. js with some dummy HTML nodes to capture lifecycle selections and then repainting the canvas when the data changes.

What is SVG in D3?

SVG stands for Scalable Vector Graphics. SVG is an XML-based vector graphics format. It provides options to draw different shapes such as Lines, Rectangles, Circles, Ellipses, etc. Hence, designing visualizations with SVG gives you more power and flexibility.


2 Answers

I spent quite some time trying to make it work in a JSFiddle with no success, but it works great on my PC. JSFiddle here. Do you mind trying the following and let me know if it works with you too?

Step 1. Load MathJax

<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

Step 2. Use this code to append a foreignObject

var svg = d3.select("body").append("svg").attr("width",400).attr("height",400)
var text = svg.append("foreignObject").attr("width",100).attr("height",100)
text.text("$$ x = \\sum_{i \\in A} i^{2} $$")
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);

However, if you still prefer MathML, then you can use the following:

text.html("<math display=\"block\"><mrow><mi>x</mi><mo>=</mo><mfrac><mrow><mo>−</mo><mi>b</mi><mo>±</mo><msqrt><mrow><msup><mi>b</mi><mn>2</mn></msup><mo>−</mo><mn>4</mn><mi>a</mi><mi>c</mi></mrow></msqrt></mrow><mrow><mn>2</mn><mi>a</mi></mrow></mfrac></mrow></math>")

I know I am adding more scripts for you to load, but my understanding is that MathML is not really much used any more.

I hope it helps.

EDIT Finally a JSFiddle here: link

Thanks

like image 192
Nikos Avatar answered Oct 24 '22 01:10

Nikos


You've two bugs

  • foreignObject must have width/height attributes
  • mathml elements must be created in the mathml namespace

Fixing these results in this...

d3.ns.prefix.mathml = "http://www.w3.org/1998/Math/MathML";

var foreignObject = d3.select("body")
    .append("svg")
var x = foreignObject.append("foreignObject")
    .attr("requiredExtensions", "http://www.w3.org/1999/xhtml")
    .attr("width", "100")
    .attr("height", "100")
var text = x.append("mathml:mo")
var row = x.append("mathml:mrow")
row.append("mathml:mi").text("a")
row.append("mathml:mo").text('\u2062')
var msup = row.append("msup")
msup.append("mathml:mi").text("x")
msup.append("mathml:mi").text("2")
row.append("mathml:mo").text("+")
row.append("mathml:mi").text("b")
row.append("mathml:mo").text('\u2062')
row.append("mathml:mi").text('x')
row.append("mathml:mo").text('+')
row.append("mathml:mi").text('c')

or as a fiddle

like image 3
Robert Longson Avatar answered Oct 24 '22 00:10

Robert Longson