diff --git a/js/src/Figure.js b/js/src/Figure.js index ab9bf9ac5c2..013c63f8ab0 100644 --- a/js/src/Figure.js +++ b/js/src/Figure.js @@ -4,6 +4,7 @@ var Plotly = require("plotly.js/dist/plotly"); var PlotlyIndex = require("plotly.js/src/lib/index"); var semver_range = "^" + require("../package.json").version; + // Model // ===== /** @@ -680,6 +681,37 @@ var FigureModel = widgets.DOMWidgetModel.extend({ // View // ==== +var default_renderer; + +function mathjax_init() { + if (window.MathJax) { + // MathJax loaded + MathJax.Hub.Config({ + SVG: {font: "STIX-Web"}, + }); + } +} + +function mathjax_pre() { + if (window.MathJax) { + // MathJax loaded + + // Save off original renderer so we can restore it after we're done + default_renderer = MathJax.Hub.config.menuSettings.renderer; + MathJax.Hub.Queue(["setRenderer", MathJax.Hub, "SVG"]); + + } +} + +function mathjax_post() { + if (window.MathJax) { + // MathJax loaded + + // Restore original renderer + MathJax.Hub.Queue(["setRenderer", MathJax.Hub, default_renderer]); + } +} + /** * A FigureView manages the visual presentation of a single Plotly.js * figure for a single notebook output cell. Each FigureView has a @@ -702,6 +734,8 @@ var FigureView = widgets.DOMWidgetView.extend({ var that = this; + mathjax_init(); + // Wire up message property callbacks // ---------------------------------- // Python -> JS event properties @@ -741,6 +775,8 @@ var FigureView = widgets.DOMWidgetView.extend({ var initialTraces = _.cloneDeep(this.model.get("_data")); var initialLayout = _.cloneDeep(this.model.get("_layout")); + mathjax_pre(); + Plotly.newPlot(that.el, initialTraces, initialLayout).then( function () { @@ -752,6 +788,8 @@ var FigureView = widgets.DOMWidgetView.extend({ // ### Send layout delta ### that._sendLayoutDelta(layout_edit_id); + mathjax_post(); + // Wire up plotly event callbacks that.el.on("plotly_restyle", function (update) { @@ -1257,6 +1295,7 @@ var FigureView = widgets.DOMWidgetView.extend({ msgData.restyle_traces); restyleData["_doNotReportToPy"] = true; + Plotly.restyle(this.el, restyleData, traceIndexes); // ### Send trace deltas ### @@ -1307,7 +1346,8 @@ var FigureView = widgets.DOMWidgetView.extend({ msgData.style_traces); style["_doNotReportToPy"] = true; - Plotly.update(this.el, style, layout, traceIndexes); + + Plotly.update(this.el, style, layout, traceIndexes); // ### Send trace deltas ### // We create an array of deltas corresponding to the updated diff --git a/plotly/offline/offline.py b/plotly/offline/offline.py index 1ba236596a9..c463102e00e 100644 --- a/plotly/offline/offline.py +++ b/plotly/offline/offline.py @@ -108,37 +108,48 @@ def init_notebook_mode(connected=False): global __PLOTLY_OFFLINE_INITIALIZED + mathjax_config = """ + MathJax.Hub.Config({ + SVG: {font: "STIX-Web"}, + displayAlign: "center"});""" + if connected: # Inject plotly.js into the output cell - script_inject = ( - '' - '' - ) + # + # Note we omit the extension .js in requirejs.config + # because require will include it. + script_inject = """ + +""".format(mathjax_config=mathjax_config) + else: # Inject plotly.js into the output cell - script_inject = ( - '' - '' - '').format(script=get_plotlyjs()) + script_inject = """ + +""".format(script=get_plotlyjs(), mathjax_config=mathjax_config) display_bundle = { 'text/html': script_inject, @@ -149,7 +160,7 @@ def init_notebook_mode(connected=False): def _plot_html(figure_or_data, config, validate, default_width, - default_height, global_requirejs): + default_height, global_requirejs, mathjax_notebook=False): figure = tools.return_figure_from_figure_or_data(figure_or_data, validate) @@ -232,30 +243,60 @@ def _plot_html(figure_or_data, config, validate, default_width, config['linkText'] = link_text jconfig = jconfig.replace('Export to plot.ly', link_text) + if mathjax_notebook: + # Construct JavaScript snippets to configure MathJax for Plotly.js, + # and then reconfigure it for the notebook once Plotly.js is finished. + mathjax_pre = """\ + MathJax.Hub.Queue( + ["setRenderer", MathJax.Hub, "SVG"]);""" + + mathjax_post = """\ + MathJax.Hub.Queue( + ["setRenderer", MathJax.Hub, "HTML-CSS"]);""" + else: + mathjax_pre = '' + mathjax_post = '' + if jframes: - script = ''' - Plotly.plot( + script = """ +{mathjax_pre} + + Plotly.newPlot( '{id}', {data}, {layout}, {config} - ).then(function () {add_frames}).then(function(){animate}) - '''.format( + ).then(function () {{ + return Plotly.addFrames('{id}', {frames}) + }} + ).then(function() {{ + Plotly.animate('{id}').then(function() {{ +{mathjax_post} + }})}}) + """.format( + mathjax_pre=mathjax_pre, id=plotdivid, data=jdata, layout=jlayout, config=jconfig, - add_frames="{" + "return Plotly.addFrames('{id}',{frames}".format( - id=plotdivid, frames=jframes - ) + ");}", - animate="{" + "Plotly.animate('{id}');".format(id=plotdivid) + "}" + frames=jframes, + mathjax_post=mathjax_post ) else: - script = 'Plotly.newPlot("{id}", {data}, {layout}, {config})'.format( + + script = """ +{mathjax_pre} + + Plotly.newPlot( + "{id}", {data}, {layout}, {config}).then(function() {{ +{mathjax_post} + }})""".format( + mathjax_pre=mathjax_pre, id=plotdivid, data=jdata, layout=jlayout, - config=jconfig) + config=jconfig, + mathjax_post=mathjax_post) optional_line1 = ('require(["plotly"], function(Plotly) {{ ' if global_requirejs else '') @@ -356,8 +397,8 @@ def iplot(figure_or_data, show_link=True, link_text='Export to plot.ly', if __PLOTLY_OFFLINE_INITIALIZED: plot_html, plotdivid, width, height = _plot_html( - figure_or_data, config, validate, '100%', 525, True - ) + figure_or_data, config, validate, '100%', 525, True, + mathjax_notebook=True) display_bundle['text/html'] = plot_html display_bundle['text/vnd.plotly.v1+html'] = plot_html @@ -485,8 +526,20 @@ def plot(figure_or_data, show_link=True, link_text='Export to plot.ly', '' ).format(id=plotdivid) + mathjax_path = ('https://cdnjs.cloudflare.com/ajax/libs/mathjax/' + '2.7.5/MathJax.js') if output_type == 'file': with open(filename, 'w') as f: + + include_mathjax = True + + if include_mathjax: + mathjax_script = ''.join([ + '', + ]) + if include_plotlyjs: plotly_js_script = ''.join([ '