Skip to content

Instantly share code, notes, and snippets.

Created August 19, 2012 03:37
What would you like to do?
Reusable Component: MathJax label
<!DOCTYPE html>
<title>Line Chart</title>
<link href="MathJax.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src=""></script>
<script type="text/javascript" src=""></script>
<script type="text/javascript" src="mathjaxlabel.js"></script>
<script type="text/javascript">
var margin = {"top": 100, "right": 100, "bottom": 100, "left": 100},
height = 300,
width = 300,
title = ["\\(Title\\)","\\(sin(\\phi)\\)"],
ylabel = ["\\(Y Label\\)","\\(Random LaTex ^{4}_{2}He\\)"],
xlabel = ["\\(This is not getting positioned correctly\\)","\\(Should be at the bottom of the margin\\)"];
var gEnter ="body")
// X Label
var xlbl = mathJaxLabel().width(width).height(margin.bottom);
.attr("transform", "translate("+margin.left+","+( + 300) +")");
// Y Label
var ylbl = mathJaxLabel().width(height).height(margin.left);
.attr("transform", "translate(0,"+( + 300)+")rotate(-90)");
// Title
var ttl = mathJaxLabel().width(width).height(margin.bottom);
.attr("transform", "translate(100,0)");
rect {
.xlabel div.holder{
position: relative;
height: 100%;
width: 100%;
.xlabel div.lines{
position: absolute;
bottom: 0;
width: 100%;
function mathJaxLabel(){
//Adds a foreignObject to store mathJax Text, assumes data is a string formatted for mathJax
// Refer to this for mathJax rerendering voodoo: view-source:
var height,
function label(selection){
selection.each(function(data) {
var container =,
QUEUE = MathJax.Hub.queue;
var fo = container.selectAll(".label").data(function(d){return [d]}),
foEnter = fo.enter().append("foreignObject")
forUpdate = d3.transition(fo).attr("height",height).attr("width",width),
bUpdate = d3.transition(fo.selectAll("body")).style("height",height+"px").style("width",width+"px"),
foExit = d3.transition(fo.exit()).remove();
function toggleDisplay(selection){
selection.each(function() {
var el =,
state ="display")"display",function(){
return (state == "block")?"none":"block";})})};
function updateMath(item,i){
//Escape whitespace so that user doesn't have to
var newtext =".input").property("value").split(" ").join("\\ "),
math = MathJax.Hub.getAllJax(item.selectAll("div.div").node())[0],
data = container.datum();
data[0][i] = "\\("+newtext+"\\)";
//each line
var nl = container.selectAll("body div.lines").selectAll("div.newline").data(function(d){return d}),
nlEnter = nl.enter().append("xhtml:div")
nlExit = nl.exit().remove();
//mJax holder
var mjax = nlEnter.append("xhtml:div")
.html(function(d){return d.split(" ").join("\\ ")})
var inpt = nlEnter.append("xhtml:input")
.property("value",function(d){return d.slice(-(d.length -2),(d.length-2))});
//Display math elements once initialized.
QUEUE.Push(function () {
math = MathJax.Hub.getAllJax(container.selectAll("div.div")[0][0])[0];
var el =;
(".input").style("display") !== "none")?updateMath(el,i):el.selectAll(".div,.input").call(toggleDisplay)})
var el =,
id = i;
label.width = function(_) {
if (!arguments.length) return width;
width = _;
return label;
label.height = function(_) {
if (!arguments.length) return height;
height = _;
return label;
return label;
Copy link

Hey @chrisbrich,

First: Thanks for mathJaxLabel(). Do you mind if I use it for my (scientific) plotting?

I cross-posted the text below to the Google groups discussion but I thought I'd leave it here too in case someone comes across this here. The x-label positioning bug annoyed me! I thought it was working perfectly with your CSS hack, but then as soon as I zoomed in/out and resized the graph, the x-label was out of position.

To fix it, remove the .xlabel CSS styling and replace .attr("transform", "translate("+margin.left+","+( + 300) +")"); with .attr("transform", "translate("+margin.left+","+( + 300) +")rotate(0)"); in index.html.

That should fix it up. It appears without the rotate(0), none of the transform occurs.


Copy link

Cool stuff. Here is the link to see it in action:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment