I'm creating some vega-lite plots for a blog post. I can change width and height to make the plots the right dimensions. However, the plot text is smaller than my blog text. So essentially, I want to make the vega-lite plots half of the pixels of my blog and then zoom in so they're magnified by twofold. What's the best solution here?
You might be able to use vega themes for this but the simplest (even if not very elegant solution) is to render to and SVG and then add a scale the whole plot with transform="scale(2)". Is that a viable option?
the simplest (even if not very elegant solution) is to render to and SVG and then add a scale the whole plot with transform="scale(2)"
So, that's equivalent to just exporting the visualization as a PNG or SVG that I embed in my blog? The downside is that I'm no longer using vega-lite to render the visualization in the browser, so I'll lose the "Open in Vega Editor" option and the direct connection to the underlying data?
That workaround will also deal with another issue -- making sure the visualization is always the same width as my blog content. Sorry I'm not very knowledgeable about web programming, so excuse the imprecise vocabulary!
You don't need to export an SVG. Vega can render to an SVG.
I think what you want to do is to set the vieBox. I hacked together this example where the chart is 1.5x as large as the original. Maybe you can adapt this to your needs. If this is not what you are looking for, can you send some mockups of what you want?
<!DOCTYPE html>
<head>
<title>Vega Lite Bar Chart</title>
<meta charset="utf-8">
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//vega.github.io/vega/vega.js"></script>
<script src="//vega.github.io/vega-lite/vega-lite.js"></script>
<script src="//vega.github.io/vega-editor/vendor/vega-embed.js" charset="utf-8"></script>
<style media="screen">
/* Add space between vega-embed links */
.vega-actions a {
margin-right: 5px;
}
</style>
</head>
<body>
<h1>Template for Embedding Vega-Lite Visualization</h1>
<div>See code at <a href="https://github.com/vega/vega-lite-demo">https://github.com/vega/vega-lite-demo</a></div>
<!-- Container for the visualization -->
<div id="vis"></div>
<script>
// Assign the specification to a local variable vlSpec.
var vlSpec = {
"data": {
"values": [
{"a": "C", "b": 2}, {"a": "C", "b": 7}, {"a": "C", "b": 4},
{"a": "D", "b": 1}, {"a": "D", "b": 2}, {"a": "D", "b": 6},
{"a": "E", "b": 8}, {"a": "E", "b": 4}, {"a": "E", "b": 7}
]
},
"mark": "bar",
"encoding": {
"y": {"field": "a", "type": "nominal"},
"x": {
"aggregate": "average", "field": "b", "type": "quantitative",
"axis": {
"title": "Average of b"
}
}
}
};
var embedSpec = {
mode: "vega-lite", // Instruct Vega-Embed to use the Vega-Lite compiler
spec: vlSpec,
renderer: 'svg'
};
// Embed the visualization in the container with id `vis`
vg.embed("#vis", embedSpec, function(error, result) {
// Callback receiving the View instance and parsed Vega spec
// result.view is the View, which resides under the '#vis' element
// begin HACK: scale svg
var svg = d3.select('#vis svg');
var scale = 1.5;
var w = svg.attr("width");
var h = svg.attr("height");
svg.attr("viewBox", `0 0 ${w} ${h}`);
svg.attr("width", w*scale);
svg.attr("height", h*scale);
// end HACK
});
</script>
</body>
</html>
@domoritz thanks a lot. Using your "hack", I was able to magnify the figure when using the svg renderer.
However, now I realize I may have been asking the wrong question. What I really want is the vega figure to resize to the width of the content div. As an example of what I want, here's a post on my blog. All the figures and media elements occupy the same width as the text. And if the text shrinks because the browser is resized, so do the figures.
Is this sort of sizing possible?
Yes! As soon as you set the viewBox, you can set the width to whatever you want, including relative sizing (e.g. 100%). Vega does not yet set the viewBox property by default. I'm not sure whether there would be negative side effects if we did that but @jheer might have thoughts on this.
@domoritz thanks! It's working with the following javascript!
var w = svg.attr("width");
var h = svg.attr("height");
svg.attr("viewBox", `0 0 ${w} ${h}`);
svg.attr("width", '100%');
svg.attr("height", '100%');
Terrific.
Great! I think it's a bit hacky so I don't think this is the "right" solution but probably the quickest solution that does not require vega changes.
For your blog, you should change the viewBox line to svg.attr("viewBox", "0 0 " + w + " " + h); because the template strings I used are not supported in all browsers yet :-/
I created a pr to add viewBox by default https://github.com/vega/vega-scenegraph/pull/30.
No support for template literals in Internet Explorer or Android! Ahh -- I've been using them everywhere lately. Boo.
Just posted the blog post with two vega-lite visualizations with 100% width.
Still haven't removed the template literals -- in a way I think it's a positive to encourage people to use modern browsers (and for browsers to become modern).
Awesome! Vega 3 will automatically add viewBox. See https://github.com/vega/vega-scenegraph/pull/30. Thanks for the use case @dhimmel!
Still haven't removed the template literals
I folded and removed them. Became too selfish, since I think people will end up blaming the blog rather than their browser.
Most helpful comment
I folded and removed them. Became too selfish, since I think people will end up blaming the blog rather than their browser.