SVG newbie here. I'm trying to do an enhancement wherein country labels (as <div>) are included during conversion of an SVG map to PNG.
The map to be converted looks like this:
This is what it looks like in the DOM. div labels to be included are highlighted.
This is what I've tried so far:
var svg = $('svg', $(svgParentId));
// append map labels // From this line...
var outerHtmlColl = $(svgParentId).find('.marker-label'); //
//
_.forEach(outerHtmlColl, function(item){ //
svg = svg.append(item.outerHTML); //
}); // ...to this line
// check whether style should be applied
if (styleSheet) {
var styles = loadStyles([styleSheet]);
var defs = $('defs', svg);
if (!defs.length) {
svg.prepend('<defs></defs>');
defs = $('defs', svg).first();
}
var style = $('style', defs);
if (!style.length) {
defs.prepend('<style type="text/css"></style>');
style = $('style', defs).first();
style.html(styles);
}
}
var serializer = new XMLSerializer();
var svgStr = serializer.serializeToString(svg[0]);
var canvas = $('#hiddenCanvas')[0];
canvas.width = width;
canvas.height = height;
canvg(canvas, svgStr,
{
ignoreDimensions: true, //does not try to resize canvas
scaleWidth: width,
scaleHeight: height,
renderCallback: function () {
var pngImg = canvas.toDataURL("image/png");
func(pngImg.substring(22));
}
}
);
Unfortunately, this doesn't work as seen below:
I'm not sure exactly what I'm missing here (or if this is possible at all...). Any inputs would be greatly appreciated.
Thank you.
Div's are not valid SVG sub-elements, so moving them into the SVG won't work.
You should move the text in the div's into the SVG by converting the div elements to <text> elements. Use the text elements' x and y attributes to position the label within the SVG.
Related
Converting div block that includes sag d3 chart into the image throws an error Extra content at the end of the document
SVG2PNG() {
var canvas = document.createElement('canvas'); // Create a Canvas element.
var ctx = canvas.getContext('2d'); // For Canvas returns 2D graphic.
//var data = svg.outerHTML; // Get SVG element as HTML code.
var svg = document.querySelector('.chart-root').innerHTML;
console.log(svg)
var img = new Image();
img.src = 'data:image/svg+xml;base64,' + btoa(svg);
canvas.width = 300,
canvas.height = 500
img.onload = function() {
canvas
.getContext('2d')
.drawImage(img, 0, 0);
}
console.log(img.src)
//return await canvg(canvas, data); // Render SVG on Canvas.
},
I am using above method for converting a block that includes d3 chart inside it (which is an SVG) into image however when I click the link in the console from img.src it throws an error Extra content at the end of the document What is wrong and how can I fix this conversion problem and convert it into the image properly for passing it in the PDF later
I want to embed Amchart3/Webix charts into the SVG element. First of all I created foreign object in the SVG document, then set its position and size. Then appended Webix chart (which is html element like div and canvas) into the foreign object. It was displayed, however, the size of the chart got bigger. I tried amchart3, it also displayed larger than usual. What is the problem?
var elem = this.el(animEl);
var parent = elem.parentNode;
var foreignObject = document.createElementNS('http://www.w3.org/2000/svg', "foreignObject");
var x = (elem.getAttribute('x'));
var y = (elem.getAttribute('y'));
var width = (elem.getAttribute('width'));
var height = (elem.getAttribute('height'));
foreignObject.setAttribute("x", x);
foreignObject.setAttribute("y", y);
foreignObject.setAttribute("height", height);
foreignObject.setAttribute("width", width);
foreignObject.appendChild(chart.getNode());
parent.appendChild(foreignObject);
I am using the HTML5 Canvas. I have added images (BitmapImages) to the canvas and I now want to add simple tooltips to these bitmap images.
Is this possible ??? If so can someone tell / show me how I could achieve this ?
I am not sure if it makes a difference , but I am also using the Easel JS Framework ...
Here is an example of what I currently have:
var container = new Container(); // EaselJS Container
container.x = 100;
container.y = 100;
stage.addChild(container);
var image = new Image();
image.src = "image.png";
var bitmap = new Bitmap(image);
bitmap.x = 5;
bitmap.y = 5;
bitmap.mouseEnabled = true;
container.addChild(bitmap);
...
I have not tested this code, but basically a bitmap image is created and added to my stage. I now want to add a simple tool tip to my bitmap image, but cant seem to work out how :(
Any help would be greatly appreciated.
Cheers,
Jon.
Here's how I would do it:
stage.enableMouseOver();
bitmap.onMouseOver = function(e) {
stage.canvas.title = 'put your tooltip text here';
}
bitmap.onMouseOut = function(e) {
stage.canvas.title = '';
}
This works by using tooltips already provided by the browser.
i'm appending a text element to a svg via javascript. After appending i wanna set x and y coordinate, however, it returns me the wrong width of the text element when using it to calculate x.
Interesting:
In Chrome, when actualize the page via F5 or button it returns wrong width, when pressing enter in the adress bar, the width is right - strange!
Here is the small code:
var capt = document.createElementNS("http://www.w3.org/2000/svg", "text");
// Set any attributes as desired
capt.setAttribute("id","capt");
capt.setAttribute("font-family","Righteous");
capt.setAttribute("font-size","30px");
capt.setAttribute("fill", "rgb(19,128,183)");
var myText = document.createTextNode(this.options.captTxt);
capt.appendChild(myText);
this.elements.jSvgElem.append(capt);
capt.setAttribute("x", this.options.windowWidth-this.options.spacer-document.getElementById("capt").offsetWidth);
capt.setAttribute("y", this.options.captY+$('#capt').height());
OK, the problem seems to be that the browser doesn't calculate the correct width when using an other font. Not setting a font results in a correct width.
I solved the problem by setting the reference point ("alignment-point") to the upper right corner ot the text element by setting attributes:
capt.setAttribute("text-anchor", "end");
capt.setAttribute("alignment-baseline", "hanging");
This way i do not have to subtract the width and add the height of the element!
There is a bug:http://code.google.com/p/chromium/issues/detail?id=140472
it just pre init some functions that calculates text width so you should call this function before(i'm sure that there is several extra lines that can be deleted):
fixBug = function () {
var text = makeSVG("text", { x: 0, y: 0, fill: "#ffffff", stroke: '#ffffff'});
text.textContent = "";
var svg = $("svg")[0];
svg.appendChild(text);
var bbox = text.getBBox();
var Twidth = bbox.width;
var Theight = bbox.height;
svg.removeChild(text);
}
$("svg") - Jquery selector
How can I dynamically set the image size ratio depending on the returned image in raphael?
Here is some code to give you an idea:
var viewer = Raphael(0,0,scrWidth, scrHeight);
viewer.image(dynamicUrl, 140, 140,300, scaledHeight);
Thank you
You can load the image outside the DOM and get its dimensions... You can put this inside a function:
var myImg = new Image();
myImg.src = dynamicUrl;
myImg.onload = function() {
var width = myImg.width;
var height = myImg.height;
var scale = 0.5; // for example
var viewer = Raphael(0,0,width, height); // or whatever other size
viewer.image(dynamicUrl, 0, 0, width*scale, height*scale); // scale image
// after the image is in the viewer you can use .scale()
}
jsFiddle
Now you can divide or multiply both width and height to scale. Make sure you pay attention to the timing.
Also, once the image is in Raphael, you can use .scale()