I am using d3js in a django web app. I have a static js script that contains a function to render a visualization given some data (passed in the context) and a selection (e.g. histogram(data,selection)). Why would d3 ignore the passed selection and directly append to the body?
This is a simplified version of my code.
Template:
{% load staticfiles %}
<script type="text/javascript" src="{% static 'd3.js' %}"></script>
<script src="{% static 'myd3vis.js' %}"></script>
<body>
<div class="vis"></div>
...
</body>
<script type="text/javascript">
mselection = d3.select(".visualization")
data = {{data|safe}}
histogram(data,selection)
</script>
In myd3vis.js file I define the histogram(data,selection) function, which contains something like this:
svg = console.append("svg").attr({"class":"visualization",
"width": 100,
"height":200})
...
When the template loads, the visualization svg is always appended to the body, instead of being appended to the <div class="vis"> element. Any idea why this would happen?
In most browsers’ JavaScript environments, console is a global object unrelated to the DOM – it provides debugging functions (e.g. console.log())… unless you’re clobbering it with a d3 DOM selection elsewhere, console.append() is unlikely to behave the way you seem to think it will.
Replace console with a bona-fide d3 selection, like:
var svg = d3.select('div.vis').attr(…); // et cetera
and inspect this object, to ensure your DOM logic is sound.
Related
How do you set dynamic content passed from view to template to use mathjax or Latex. To be more precise in the terminal if 2*sqrt(2) would be displayed as 2√2 by pprint function. But in the django template it outputs as 2*sqrt(2) and not 2√2?
Finally figured out in case anyone else runs into the same problem here's is the working solution. I used AsciiMath Input as the input format in mathjax that incorporates ASCIIMathML.
In the base.html add the following scripts:
<script>
MathJax = {
loader: {load: ['input/asciimath', 'output/chtml']}
}
</script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/startup.js"></script>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-chtml.js">
and remember to enclose the dynamic text by back-ticks”, i.e., `...` So in the django-admin you can simply enter sqrt(50) as ` sqrt(50) ` or ` x^2 ` and the dynamic content which is passed from view to the template, in the template you surround {{e1}} by back-ticks
` {{ e1 }} ` instead of
{{ e1 }}
where e1 is the dynamic content. So if e1 which was earlier displayed in plain text as 2*sqrt(2) will now be displyed as 2√2.
For more details: http://docs.mathjax.org/en/latest/input/asciimath.html#asciimath-support
I would like to load MathJax in my base template with:
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
<script type="text/javascript"
src="{% static "js/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML" %}">
</script>
However in the rendered template the URL is returned as:
/static/js/MathJax/MathJax.js%3Fconfig%3DTeX-AMS-MML_HTMLorMML
and MathJax doesn't work.
If I hard-code the URL as src="/static/js/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML" it works. How can I prevent Django/Mezzanine from escaping the ? and = characters? Is there an alternative approach?
[The reason I want to use a local MathJax is for development when I'm away from an internet connection; I use a CDN in production.]
I would try moving the config parameter outside the static reference and see if that helps:
<script type="text/javascript"
src="{% static "js/MathJax/MathJax.js" %}?config=TeX-AMS-MML_HTMLorMML">
</script>
I don't know Django or Mezzanine, but if the static is what is encoding the URL characters, moving them outside might prevent that.
I'm running into a problem. I need App.rootElement = "body", because views and components will be used all over the place. I do not want to put the entire page in a handlebars template, due to SEO and other concerns. The main application template will exist somewhere in the center of the page:
<h1>Header markup</h1>
<script type="text/x-handlebars">
<h2>Application Template</h2>
{{outlet}}
</script>
<h1>Footer markup</g1>
However, when the page is rendered, this template is appended to the end of the body, instead of staying where the template script has been placed. (see jsbin exmaple) Is there any way to tell Ember to render the application template where it is in the markup?
One hacky solution I've found is to manually move the containing element in didInsertElement, but that seems a little heavy handed and not something that would be considered a best practice. (see jsbin example)
The script tag doesn't have anything to do with placement, if you want it to live somewhere create a div tag, id it, and change the rootElement to that div tag.
<script type="text/x-handlebars">
<h2>Application Template</h2>
{{outlet}}
</script>
...
<h1>Header markup</h1>
<div id='foo'></div>
<h1>Footer markup</h1>
App.rootElement = '#foo';
/START description of why
I'm doing a 'load more' type of interaction: user gets at bottom of a page, I load more content.
As I'm using a plugin that formats content in a 'pinterest-style' (masonry), I need to take the output of a rest call, formatted using an ember view, and i'm doing something like:
<div id="list">
</div>
<div id="hidden" style="display:none">
{{#each item in App.itemsController}}
test {{item.id}}
<br />
{{/each}}
</div>
What I want to do is, load the content in the hidden div, and then pass its HTML generated content to the plugin to process in my formatted list view.
If I just copy the #hidden content, the Ember scripts get in, and on subsequent 'load more', content is inserted in the #list, in addition of going in the #hidden div.
That's because I copied the entire handlebars.
So I get rid of the container tag, the one I supposed was wrapping the controller content binding, but even when stripping it from the content I pass to #list, the #list still auto-updates when a 'load more' is called.
I know that's a dirty hackish thing, but in order to improve performance in the client I must take a similar route.
/END description of why
//ACTUAL QUESTION ;)
Given this background, the question is, stripping the container metamorph script tags (like the ones here below), and just take the content inside them, shouldn't get rid of the auto-updating content functionality?
<script id="metamorph-X-start" type="text/x-placeholder"></script>
//ALL THE CONTENT
<script id="metamorph-X-end" type="text/x-placeholder"></script>
Inside those, I just have the actual content generated, like:
<script id="metamorph-9-start" type="text/x-placeholder"></script>
test <script id="metamorph-59-start" type="text/x-placeholder"></script>2873<script id="metamorph-59-end" type="text/x-placeholder"></script>
<br>
<script id="metamorph-9-end" type="text/x-placeholder"></script>
<script id="metamorph-10-start" type="text/x-placeholder"></script>
test <script id="metamorph-60-start" type="text/x-placeholder"></script>2872<script id="metamorph-60-end" type="text/x-placeholder"></script>
<br>
<script id="metamorph-10-end" type="text/x-placeholder"></script>
The alternative is programmatically render the template inside a variable and process that, which is surely a better way of doing this, but I just wonder how the #each binding works internally as I thought the metamorph was doing that.
Have you looked into using a CollectionView and calling the plugin through the didInsertElement callback?
e.g.
MyList = Ember.CollectionView.extend({
itemViewClass: 'App.ListItem',
didInsertElement: function(){
view.$().jqueryPlugin({ ... })
}
})
I would like to know how to configure Mathjax in Django in a Q&A system where Questions and Answers will be based on LaTeX format.
I have tried to add:
<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
into the html template where the questions and answers will be displayed to no avail.
Thanks.
If the page's content is dynamically created, you will need to call MathJax after the content has been loaded. See the documentation for details. The main idea is that you have to include
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
in the javascript that is executed after the content is in place.
fOR Dynamic content here's is the working solution. I used AsciiMath Input as the input format in mathjax that incorporates ASCIIMathML.
In the base.html add the following scripts:
<script>
MathJax = {
loader: {load: ['input/asciimath', 'output/chtml']}
}
</script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/startup.js"></script>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-chtml.js">
and remember to enclose the dynamic text by back-ticks”, i.e., `...` So in the django-admin you can simply enter sqrt(50) as ` sqrt(50) ` or ` x^2 ` and the dynamic content which is passed from view to the template, in the template you surround {{e1}} by back-ticks
` {{ e1 }} `
instead of
{{ e1 }} where e1 is the dynamic content. So if e1 which was earlier displayed in plain text as 2*sqrt(2) will now be displyed as 2√2.
For more details: http://docs.mathjax.org/en/latest/input/asciimath.html#asciimath-support
see https://docs.mathjax.org/en/latest/web/configuration.html. For the demo indicated here to work you should also add ['\(', '\)'] to inlineMath:
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-svg.js">
</script>