Saving D3.js (circles and lines) as an image - d3.js

I'm trying to modify this d3js graph example https://bl.ocks.org/nitaku/7512487 to generate and download as an image. I can get it to work with just the nodes, but can't seem to get the lines (edges) between the nodes to save.
Pasting the following into the console on the example above will generate the image of the nodes:
function svg2img(){
var svg = document.querySelector('svg');
var xml = new XMLSerializer().serializeToString(svg);
var svg64 = btoa(xml); //for utf8: btoa(unescape(encodeURIComponent(xml)))
var b64start = 'data:image/svg+xml;base64,';
var image64 = b64start + svg64;
return image64;
};svg2img()
For some wider context, it's used within a Python Flask app - I allow the user to create a graph network, then require it to be downloaded.
Many thanks!

When you export an SVG to an image like that, you lose all styles that are not inline. After all, it doesn't have access to the CSS files any more, when it's encoded as base64. You are not the first to have encountered this problem, but if you want do do it yourself, you'd need to first traverse the SVG nodes, then get their styles using window.getComputedLayout(node), and then export it. Or you can change the D3 code to apply all styles directly onto the nodes using .attr() or .style().
If you're fine using outside tools, there are many just on github alone, like this one, this one, and this one. You can install them or just use their code as inspiration.

Related

Any way to let a user draw an image in google colab and get the resulting image data?

I can see that there are ways of uploading files to google colab for processing, but it would be really good if there was a way for a user to draw a simple image to test out visual recognition of some systems, i.e MNIST numbers, giving the users a 28x28 grid to draw a number and see what the model predicts it to be.
So there are plenty of examples of how to do this sort of thing on codepen and some premade js libs for being able to just create simple pixel editors components on a canvas, but has anyone found an approach which lets you get something like this on a colab document, lets the user input the data then fetch the data from the drawn image?
I make a gist for doing just that.
https://gist.github.com/korakot/8409b3feec20f159d8a50b0a811d3bca
The main part is this sending data from JS
var data = new Promise(resolve=>{
button.onclick = ()=>{
resolve(canvas.toDataURL('image/png'))
}
})
And this receiving data in Python.
def draw(filename='drawing.png', w=400, h=200, line_width=1):
display(HTML(canvas_html % (w, h, line_width)))
data = eval_js("data")
binary = b64decode(data.split(',')[1])
with open(filename, 'wb') as f:
f.write(binary)
return len(binary)

Save D3 chart as image

I created lots of D3 chart in the application .
But right now my requirement is to save D3 chart in any format like png/gif or pdf.
I searched a lot and every one say we can use canvas for that.
Can anyone give any example or link for that...
Conceptually I am clear about that like
Use the canvg JavaScript library to render the SVG image using Canvas: https://github.com/gabelerner/canvg
Capture a data URI encoded as a JPG (or PNG) from the Canvas, according to these instructions: Capture HTML Canvas as gif/jpg/png/pdf?
What I want actually if any one have implemented, then could you please share the code.
After searching many resources and trying many things, I found SaveSvgAsPng
on GitHub.
It's very easy to implement and to use with resources available on README page on the same link.
Steps
Add Javascript library to your project.
Write a function with saveSvgAsPng call, include other options as required.
Example usage
saveSvgAsPng(document.getElementsByTagName("svg")[0], "plot.png");
Example function using d3.js
// I have button in html with id="download"
d3.select("#download")
.on('click', function(){
// Get the d3js SVG element and save using saveSvgAsPng.js
saveSvgAsPng(document.getElementsByTagName("svg")[0], "plot.png", {scale: 2, backgroundColor: "#FFFFFF"});
})
For this example, my plots are small for a web page so increased size to double for download and rather than transparent background as default I changed to white.
SaveSvgAsPng worked for me too. But if you want it to work in IE, you need to include "canvg" and pass it as parameter as below:
function saveAsImage(name, id) {
var svg = $('#'+id).find('svg')[0];
saveSvgAsPng(svg, name + '.png', { canvg: canvg, backgroundColor: 'white'});
}
"backgroundColor" parameter is also useful when your graphs need to be saved with a background.

Node get image properties (height, width)

I'm looking for a means to get the height and width of images from a given path locally. I know about imagemagick and graphicmagick but I'd prefer a method that doesn't involve installing extra software to the OS. If I can keep it to node modules that would be fantastic.
Does anyone have any ideas that may help me?
Worst case scenario, I'll use IM and GM but like it said would prefer to avoid this path.
You can use JIMP(JavaScript Image Manipulation Program). An image processing library for Node written entirely in JavaScript, with zero external or native dependencies. It has so many other image manipulation options available if you want.
var Jimp = require('jimp');
var image = new Jimp("./path/to/image.jpg", function (err, image) {
var w = image.bitmap.width; // width of the image
var h = image.bitmap.height; // height of the image
});
Hope this will help.
You can use a pure JS node module https://www.npmjs.org/package/image-size .. doesn't require installing anything extra
var sizeOf = require('image-size');
var dimensions = sizeOf('images/funny-cats.png');
console.log(dimensions.width, dimensions.height);

Import and parse SVG file in D3.js

I have SVG files created elsewhere (using MS Visio) which I would like to use as background for a visualization, where some positioning is driven by the placement of items in the SVG graphic. Ideally, I would be able to manipulate the imported SVG data directly, and then use it to create elements in the calling document using D3.
Is there a simple way to import an existing SVG document into a data structure using D3, similarly to the way that JSON can be imported? I've tried d3.xml, but don't seem to get a useful data structure. Importing the graphic with an IMG tag doesn't populate the DOM with SVG elements as far as I can see.
One small complication: it must also work in IE9! (ImportNode doesn't work)
Thanks for the ideas. I found out what to do in the end. It is possible to import the SVG file using a d3.xml call. The parsing is done, but the complication is how to understand the DOM structure which is produced. IE9 seems to have a problem with placing the imported node, but I don't need that behaviour as I only want to use aspects of the incoming SVG, and will be regenerating SVG using D3

How to Automatically Create ImageMaps of Grey Maps from Wikipedia?

I have a project using various members of Wikipedia's grey maps: http://en.wikipedia.org/wiki/Wikipedia:Blank_maps. I fill them in with colors depending on which countries, states or provinces a user selects by clicking on the shape or by checking a checkbox.
I would like to write a script that creates imagemaps automatically of each country, state or province by somehow getting the X and Y pixel location of the borders of a country, state or province albeit without the names of these entities, which I will fill in later. I have already done the World map by hand and found a open source US map image map demo. I would now like to create my maps more rapidly.
I use PHP and GD to floodfill the shapes, so I guess I could use one central pixel location of the shapes as well. Any suggestions? This script is a possibility but is still somewhat manual: http://abhinavsingh.com/blog/2009/03/using-image-maps-in-javascript-a-demo-application/. Also Mapedit, http://www.boutell.com/mapedit/, has a magic wand feature that works pretty well, but again I have a feeling this can be done automatically.
An almost perfect solution to this issue is by using SVG images and this translator of the svg code to imagmap area tags: http://www.electricfairground.com/polygonator/. The result is an appropriate image map, although the svg image may need to be resized, and the countries or provinces all seem to be offset and occasionally jumbled up. So this require opening a page generated with the SVG image or exported PNG copy of the SVG file, in a wysiwig editor that allows you to move imagemap elements.
I'm trying to figure out what the pattern of the offset is and if I do I'll post it here: http://wherehaveibeen.info/images/polye.html. The author of the "Polygonator" clued me into his service and using svg map images from his article here: http://www.electricfairground.com/2009/08/08/image-map-rollover-effects-using-jquerys-maphilight-plugin/. He advocates there, the tracing of png images into svg images via Inkscape. But since Wikipedia already has maps in SVG format, why not go straight to the code? It turns out that svg files basically already have the polygons separated and the border regions speciied, at least in the Wikipedia grey maps, http://en.wikipedia.org/wiki/Wikipedia:Blank_maps, they just need some cleaning up with the Polygonator.
I found if I opened up the SVG code in Notepad++ i could copy and paste in the entire contents of the SVG file and the polygonator will remove the unneeded code. A little clean up of the imagemap area tags is required afterwards but not much. The biggest problem is the mentioned generated area tags regions offests and the occasionl jumbled up overlapping locations of the imagemap areas in the generated code.
Well the real answer here appears to be that SVG files are almost imagemaps already and can be mildly processed to turn them into imagemaps, and Wikipedia certainly has plenty of SVG maps.
There are at least three projects that attempt to do this, with only some success at the moment. I'm kind of more interested in making an SVG file processing online image mapper service now that so might work on that project instead of just the map coloring one:
Polygonator - described here: http://www.electricfairground.com/2009/08/08/image-map-rollover-effects-using-jquerys-maphilight-plugin/ but the actual service is here: http://www.electricfairground.com/polygonator/index.html - is the simplest and best service or software so far I think. You have to manually dump the SVG XML text into the input field, but despite what the author says, I think you can dump the entire SVG file in the in field, not just the "M-z tag". The resulting area tags need editing to remove empty ones without coordinates and polygons with only two points.
Inkscapemap - http://sourceforge.net/projects/inkscapemap/ - chokes on complex SVG files such as those with shading. Also I couldn't get it to display as an HTML service even though I followed advice about using the main class of the jar file which I found described in the manifest file as well referring to the main jar file and the support file in an "archive" attribute.
http://davidlynch.org/blog/2008/03/creating-an-image-map-from-svg/ - very interesting project with many blog comments. The image maps again are not quite perfect and need editing.
I see I can use GD PHP's imagecolorat and cycle through all the pixels to find those that are black. This works:
<?php
$im = ImageCreateFromPNG("india.png");
$width = imagesx($im);
$height = imagesy($im);
for ($cy=0;$cy<$height;$cy++) {
echo '<p>';
for ($cx=0;$cx<$width;$cx++) {
$rgb = ImageColorAt($im, $cx, $cy);
$col = imagecolorsforindex($im, $rgb);
if ($col["red"] == 0 && $col["green"] == 0 && $col["blue"] ==0){
echo $cx.", ".$cy." ";
} else {echo "";}
}
}
?>
Can anybody suggest how to find the polygons in the huge multipolygon complex that results from running the above code on say a black and white 2 color map of India, where all the borders are black and the interior of the states and Indian Ocean is white??
Here is image of India: http://wherehaveibeen.info/images/india.png and the mess now of the coordinates for the imagemap that needs to be split up into separate polygons: http://wherehaveibeen.info/images/black.php

Resources