Centering SVG image inside parent SVG - javascript

I am preparing a presentation in HTML/CSS/Javascript using the following code. What I want is to centre an SVG image in the main SVG. From what I understand, the viewBox of the main SVG establishes a new coordinate system. So, when I try to centre the image using the half of its width (similar to "text-anchor="middle"") I do not get what I expect, the image is shifted but not enough to be in the centre.
<!doctype html>
<meta charset="utf-8">
<script src="./js/d3.js"></script>
<style>
body {
margin:0;
/*border: 5px solid green; /*for testing*/
display:block;
padding-top: 0px;
height: 100vh;
background-color: rgba(0,0,0,1);
font-family: Helvetica;
}
body svg {
/*border: 1px solid #C1543D;*/ /*for testing*/
display:block;
margin: auto;
}
.slideBackground {
fill: white;
}
.slideHeader{
font-size: 38;
}
</style>
<body>
<svg width="100%" height="100%" viewBox="0 0 1024 768"> <!-- 1024 and 768 are expressed in units of the SVG's viewport (NOT pixels)-->
<rect class="slideBackground" x="0%" y="0%" width="100%" height="100%"/> <!-- rect for viewbox-->
<g id="equation">
<svg x="50%" y="70%" width="30%" height="6%" viewBox="0 0 35 5" preserveAspectRatio="xMidYMid">
<image x="0" y="0" width="100%" height="100%" xlink:href="bayesTheorem.svg"></image>
</svg>
</g>
</svg>
</body>
<script>
var eqSVG = document.getElementById("equation");
var rec = eqSVG.getBoundingClientRect().width;
d3.select("#equation").attr("transform", "translate(" + (-rec/2) + ",0)")
</script>

I fixed the issue. I just changed image x="0" to image="-50%" and removed the D3 selection

Related

How can I make the black part transparent to show the white background?

#myElement {
width: 50px;
height: 300px;
background: linear-gradient(0deg, #4a94cd, #fe49a6);
display: flex;
flex-direction: column;
justify-content: space-evenly;
}
#myBar {
width: 100%;
height: 10px;
background: #000;
}
<div id="myElement">
<div id="myBar"></div>
<div id="myBar"></div>
<div id="myBar"></div>
<div id="myBar"></div>
<div id="myBar"></div>
<div id="myBar"></div>
<div id="myBar"></div>
<div id="myBar"></div>
<div id="myBar"></div>
<div id="myBar"></div>
</div>
How can I make the black part transparent to show the background behind,The background won't always be white,maybe a picture,The color part is a gradient of the whole
Change the id attribute to class for the div myBar and change the background to white.
We can target each of myBar elements using nth-child selector
.myBar:nth-child(1),.myBar:nth-child(2) and so on. I have added a sample below.
We can also use images as background by adding background-image property to the css definition.
#myElement {
width: 50px;
height: 300px;
background: linear-gradient(0deg, #4a94cd, #fe49a6);
display: flex;
flex-direction: column;
justify-content: space-evenly;
}
.myBar {
width: 100%;
height: 10px;
background: white;
}
.myBar:nth-child(1){
background:red;
}
----------
<div id="myElement">
<div class="myBar"></div>
<div class="myBar"></div>
<div class="myBar"></div>
<div class="myBar"></div>
<div class="myBar"></div>
<div class="myBar"></div>
<div class="myBar"></div>
<div class="myBar"></div>
<div class="myBar"></div>
<div class="myBar"></div>
</div>
I remember seeing in another post of yours that you want to make a progress bar (you should mention these things to make it easier for others to answer with relevant answers). And you probably want to change the height dynamically or something with this one div (to simulate the progress).
You can use the css property clip-path to achieve the effect of alternating between your gradient and a transparent background:
.container {
background: url(https://picsum.photos/id/999/360);
padding: 20px;
width: 320px;
}
#myElement {
width: 50px;
height: 320px;
background: linear-gradient(0deg, #4a94cd, #fe49a6);
clip-path: polygon(
0 0,100% 0,100% 20px,0 20px,
0 30px,100% 30px,100% 50px,0 50px,
0 60px,100% 60px,100% 80px,0 80px,
0 90px,100% 90px,100% 110px,0 110px,
0 120px,100% 120px,100% 140px,0 140px,
0 150px,100% 150px,100% 170px,0 170px,
0 180px,100% 180px,100% 200px,0 200px,
0 210px,100% 210px,100% 230px,0 230px,
0 240px,100% 240px,100% 260px,0 260px,
0 270px,100% 270px,100% 290px,0 290px,
0 300px,100% 300px,100% 320px,0 320px
);
}
<!--
I just added the container to show a background image behind
the element with the clip-path
-->
<div class="container">
<div id="myElement"></div>
</div>
You can create it easily using svg masking technique because using divs will not work
As you will see on running the snippet that the image is behind the svg but looks very clear as the black part is now transparent.
#myElement {
width: 50px;
height: 300px;
position: relative;
}
img{
position: absolute;
left: 0;
top: 0;
z-index: -1;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="src/style.css">
</head>
<body>
<svg width="50" height="300" id="myElement">
<defs>
<linearGradient xl=0 x2=0 y1=0 y2=1 id="Gradient">
<stop stop-color="#fe49a6" offset="0%" />
<stop stop-color="#4a94cd" offset="100%" />
</linearGradient>
<pattern id="pattern" x="0" y="0" width="50" height="30" patternUnits="userSpaceOnUse">
<rect x=0 y=0 width=50 height=20 fill="#999" />
</pattern>
<mask id="mask-gradient" x="0" y="0" width="50" height="300">
<rect x="0" y="0" width="50" height="300" fill="url(#pattern)" />
</mask>
</defs>
<rect id="rect1" fill=url(#Gradient) x="0" y="0" width="50" height="300" mask="url(#mask-gradient)" />
</svg>
</div>
<img src="https://images.unsplash.com/photo-1667400104714-53da4894bf18?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387&q=80">
</body>
</html>
This is a job for mask
#myElement {
width: 50px;
height: 300px;
background: linear-gradient(0deg, #4a94cd, #fe49a6);
-webkit-mask: linear-gradient(0deg,#0000 10px, #000 0) 0 0/100% 10%;
}
body {
background: orange;
}
<div id="myElement">
</div>

Export svg to png/tiff with foreignObject

Im using https://github.com/jgraph/drawio (mxgraph) for a project. I use AngularJS for frontend and NodeJS/Express for backend. The idea is to do a diagram design and then be able to export it/print it among other things.
Im able to interact with the backend and do the diagram but having trouble with the printing/rendering.
The problem is that the generated svg contains foreinObject for a QR and Barcode. While the diagram is rendered/displayed on the frontend, i need to generate a png/tiff in order to send it to a printer, but nodejs is not capable to render the foreinObject elements. I
tested canvg, sharp on node but foreignObject are not supported (according to some issues on github).
This is an example svg:
<svg width='600' height='500'>
<g xmlns="http://www.w3.org/2000/svg" fill="#464445" font-family="Lucida Console" pointer-events="none" text-anchor="middle" font-size="72px">
<text x="350" y="135">ABCDEF12345</text>
</g>
<g xmlns="http://www.w3.org/2000/svg">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 130px; margin-left: 300px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #774400; ">
<div style="display: inline-block; font-size: 11px; font-family: Arial, Helvetica; color: rgb(119, 68, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;">
<img src="data:image/png;base64,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" />
</div>
</div>
</div>
</foreignObject>
<text x="300" y="133" fill="#774400" font-family="Arial,Helvetica" font-size="11px" text-anchor="middle">[Object]</text>
</switch>
</g>
<g xmlns="http://www.w3.org/2000/svg">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 340px; margin-left: 450px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #774400; ">
<div style="display: inline-block; font-size: 11px; font-family: Arial, Helvetica; color: rgb(119, 68, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;">
<div title="Diagram Title">
<canvas style="display: none;" width="200" height="200"></canvas>
<img style="display: block;" src="data:image/png;base64,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" />
</div>
</div>
</div>
</div>
</foreignObject>
<text x="450" y="343" fill="#774400" font-family="Arial,Helvetica" font-size="11px" text-anchor="middle">[Object]</text>
</switch>
</g>
</svg>
And should look like this: Test svg. With sharp/canvg the QR and barcode are not displayed and instead [Object] is displayed on the final png/tiff. Even tryied C# SVG NuGet and htm2canvas for rendering on backend with same issue.
I've seen some posts on how to render canvas.toDataURL to png with but i dont have a object on the document DOM since mxgraph works differently and only have the final available as string. Any ideas on how can i remove the foreignObjects or how to modify the svg manually?
Is possible to "create" a canvas element and render the svg inside and then export it?
So, after #ccprog answer, i realized what i needed to do. I was trying badly to create a new canvas, copy the child element attributes, render again, use libraries to do that with no success.
With that answer the idea was simple: Grab the img src, create new child, remove foreignObject.
I had some issues with the x,y coordinates since the image was not centered (mxgraph uses padding-top and margin-left) and the code end up being this
var newXml = xmlCanvas.root;
for(var i = 0; i < newXml.children.length; i++){
var child = newXml.children[i];
if(child.tagName == 'g' && child.children[0].tagName == "switch"){
var imgChild = child.getElementsByTagName("img")[0];
var foreignObjectChild = child.getElementsByTagName("foreignObject")[0];
var textChild = child.getElementsByTagName("text")[0];
var image = document.createElement("image");
image.setAttribute("href", imgChild.src);
let marginLeft = Number(foreignObjectChild.firstChild.style.marginLeft.replace("px", ""));
image.setAttribute("x", marginLeft - imgChild.naturalWidth/2);
let paddingTop = Number(foreignObjectChild.firstChild.style.paddingTop.replace("px", ""));
image.setAttribute("y", paddingTop - imgChild.naturalHeight/2);
image.setAttribute("xmlns", "http://www.w3.org/2000/svg");
newXml.children[i].firstChild.appendChild(image);
newXml.children[i].firstChild.removeChild(foreignObjectChild);
newXml.children[i].firstChild.removeChild(textChild);
}
}
Its kinda hardcoded for this example but it works. Not expert on javascript but this probably can be optimized/rewrited in a better way.
One issue i encountered is that the final svg has the tags "<a0:image" and "<a1:image" etc... but then i use regex and remove de a0/a1/aN. Dont know why, probably some bug on how i create/append the child elements.

Scrolling with multiple SVGs

I am trying to create 4 svg based charts one below another.
After charts are loaded, I can see only 2 and half charts which get occupied on web browser without scrolling.
I can see scroll bars enabled in left and at the bottom but they don't scroll much.
<div overflow="auto">
<svg id="chart1" style="overflow-y:scroll"></svg>
<svg id="chart2" style="overflow-y:scroll"></svg>
<svg id="chart3" style="overflow-y:scroll"></svg>
<svg id="chart4" style="overflow-y:scroll"></svg>
</div>
Above are 4 svg and below is the css for each of them.
#chart1 {
width: 100%;
height: 100%;
position: absolute;
}
When I minimize the webpage, I can see 4 charts otherwise 2 and half only.
What all I have tried:
1. enabling auto-scroll for html, body
2. enabling scroll in svg (similar to above code).
3. increasing html and body height and width.
html, body {
width: 100%;
height: 200%;
margin: 0px;
padding: 0px;
}
Here is a example on jsfiddle, each svg has a data-no, and one common class. It is more easy with this example for you to explain what you expect exactly...
https://jsfiddle.net/ericsm/ondtxmp2/
and here the code too :
each svg take 100% of body.
<HTML>
<HEAD>
<style type="text/css">
.container-charts {
border:solid 8px blue;
div : 100%;
}
.chart {
width: 100%;
height: 100%;
border:dashed 2px green;
}
html, body {
margin: 0px;
padding: 0px;
}
</style>
</HEAD>
<BODY>
<div class="container-charts" overflow="auto">
<svg class="chart" data-no="1">
<ellipse cx="100" cy="80" rx="100" ry="50" style="fill:yellow;stroke:purple;stroke-width:2" />
</svg>
<svg class="chart" data-no="2">
<ellipse cx="100" cy="80" rx="100" ry="50" style="fill:blue;stroke-width:2" />
</svg>
<svg class="chart" data-no="3">
<ellipse cx="100" cy="80" rx="100" ry="50" style="fill:gray;stroke-width:2" />
</svg>
<svg class="chart" data-no="3">
<ellipse cx="100" cy="80" rx="100" ry="50" style="fill:black;stroke-width:2" />
</svg>
</div>
</BODY>
</HTML>

IE & Firefox rendering incorrectly but not in Chrome, Safari & Chromium browsers

All,
There is a double walled circle and a text. Ideally the text should be rendered within the circle but in IE & Firefox , the circle is coming down and the text on the top. The issue can be seen using the below code.
Any help or advice on how to get it fixed in IE & firefox is much appreciated.
<div class="col-xs-4 col-sm-2">
<div style="margin-top: 20px; position: relative; display: inline-block; max-width: 116px; max-height: 116px;">
<svg width="100%" height="100%" viewBox="0 0 418 418" tabindex="-1">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-31.000000, -31.000000)" stroke="#9B9B9B" stroke-width="2" fill="#FFFFFF">
<g transform="translate(32, 32)">
<path d="M208,416 C322.875228,416 416,322.875228 416,208 C416,93.124772 322.875228,0 208,0 C93.124772,0 -9.09494702e-13,93.124772 -9.09494702e-13,208 C-9.09494702e-13,322.875228 93.124772,416 208,416 Z"></path>
<path d="M208,398.666667 C313.302292,398.666667 398.666667,313.302292 398.666667,208 C398.666667,102.697708 313.302292,17.3333333 208,17.3333333 C102.697708,17.3333333 17.3333333,102.697708 17.3333333,208 C17.3333333,313.302292 102.697708,398.666667 208,398.666667 Z"></path>
</g></g></g>
</svg>
<span style="font-size: 24px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">400</span>
</div>
</div>
The styling you have added to the divs pushes the number outside of the SVG.
I would just avoid the problem in the first place by using an SVG <text> element that you can position inside the svg.
You might have to fiddle with the x and y values a bit.
ps: There's also a <circle> element you could use instead of a <path>.
<svg width="100%" height="100%" viewBox="0 0 418 418" tabindex="-1">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-31.000000, -31.000000)" stroke="#9B9B9B" stroke-width="2" fill="#FFFFFF">
<g transform="translate(32, 32)">
<path d="M208,416 C322.875228,416 416,322.875228 416,208 C416,93.124772 322.875228,0 208,0 C93.124772,0 -9.09494702e-13,93.124772 -9.09494702e-13,208 C-9.09494702e-13,322.875228 93.124772,416 208,416 Z"></path>
<path d="M208,398.666667 C313.302292,398.666667 398.666667,313.302292 398.666667,208 C398.666667,102.697708 313.302292,17.3333333 208,17.3333333 C102.697708,17.3333333 17.3333333,102.697708 17.3333333,208 C17.3333333,313.302292 102.697708,398.666667 208,398.666667 Z"></path>
</g>
</g>
</g>
<text x="47%" y="49%" style="font-size: 32px;">400</text>
</svg>
I don't know what are your constraints, but to render these circles in particular I'd play with border-radius: 50% and display: flex:
.circle {
border: 2px solid #888;
border-radius: 50%; /* make the border a circle */
display: flex; /* align the content vertically and horizontally */
align-items: center; /* same */
justify-content: space-around; /* same */
}
<div class="circle" style="width: 100px; height: 100px;">
<div class="circle" style="width: 90px; height: 90px;">
400
</div>
</div>

JS draw an arrow pointing from one div to another

I have the following code:
<div id="parent">
<div class="child" id="air1">Medium 1</div>
<div class="child" id="glass">Medium 2</div>
<div class="child" id="air2">Medium 1</div>
</div>
<style>
#parent {
background: #999;
padding: 0px;
}
#glass {
background: #666;
}
.child {
background: #ccc;
height: 200px;
margin: 0px;
}
</style>
I want to draw an arrow from #air1 into #glass using an svg. I added the following code into the div to draw an example arrow:
<svg width="300" height="100">
<defs>
<marker id="arrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill:red;" />
</marker>
</defs>
<path d="M30,150 L100,50"
style="stroke:red; stroke-width: 1.25px; fill: none;
marker-end: url(#arrow);"
/>
</svg>
I don't want the arrow pointed in a random direction though, I want it to point into #glass like this:
Also, how would I go about drawing a less steep arrow like this as well:
How can I do this?
You can achieve that by using positioning (inserting the svg into the first section and set it to position: absolute;) and adjusting the offset of the path element. To make the arrow pointing down, just use a negative value for the second value of the path description attribute.
For more information see w3schools about path.
#parent {
background: #999;
padding: 0px;
}
#glass {
background: #666;
}
.child {
background: #ccc;
height: 200px;
margin: 0px;
position: relative;
}
svg {
position: absolute;
left: 0;
}
<div id="parent">
<div class="child" id="air1">Medium 1
<svg width="400" height="200">
<defs>
<marker id="arrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill:red;" />
</marker>
</defs>
<path d="M-600,-10 L300,195" style="stroke:red; stroke-width: 1.25px; fill: none; marker-end: url(#arrow);" />
</svg>
</div>
<div class="child" id="glass">Medium 2</div>
<div class="child" id="air2">Medium 1</div>
</div>

Categories

Resources