I'm currently working on a way to create a single-line diagram using Javascript. I'm currently able to connect two html elements using the following function:
adjustLine (from, to, line) {
var fT = from.offsetTop + from.offsetHeight/2;
var tT = to.offsetTop + to.offsetHeight/2;
var fL = from.offsetLeft + from.offsetWidth/2;
var tL = to.offsetLeft + to.offsetWidth/2;
var CA = Math.abs(tT - fT);
var CO = Math.abs(tL - fL);
var H = Math.sqrt(CA*CA + CO*CO);
var ANG = 180 / Math.PI * Math.acos( CA/H );
if(tT > fT){
var top = (tT-fT)/2 + fT;
}else{
var top = (fT-tT)/2 + tT;
}
if(tL > fL){
var left = (tL-fL)/2 + fL;
}else{
var left = (fL-tL)/2 + tL;
}
if(( fT < tT && fL < tL) || ( tT < fT && tL < fL) || (fT > tT && fL > tL) || (tT > fT && tL > fL)){
ANG *= -1;
}
top-= H/2;
line.style["-webkit-transform"] = 'rotate('+ ANG +'deg)';
line.style["-moz-transform"] = 'rotate('+ ANG +'deg)';
line.style["-ms-transform"] = 'rotate('+ ANG +'deg)';
line.style["-o-transform"] = 'rotate('+ ANG +'deg)';
line.style["-transform"] = 'rotate('+ ANG +'deg)';
line.style.top = top+'px';
line.style.left = left+'px';
line.style.height = H + 'px';
}
The function takes 3 parameters:
This works fine and outputs the following result:
However, the lines that connect the html elements are a straight line, I would like to have a more natural flow for a diagram, something like the following:
Any advice on how I could go about doing this? Any help is greatly appreciated!
Edit
I'm using html2canvas to create an image of the generated output. This is my code:
var myDiv = document.getElementById('content');
html2canvas(myDiv, {useCORS: true, allowTaint : true}).then(function (canvas) {
var imgData = canvas.toDataURL("image/png", 1.0);
var imgData2 = canvas2.toDataURL("image/png", 1.0);
var pdf = new jsPDF('l', 'pt', [HTML_Width, HTML_Height]);
pdf.internal.scaleFactor = 30;
pdf.addImage(imgData, 'PNG', 0, 0, HTML_Width, HTML_Height);
pdf.addPage();
pdf.addImage(imgData2, 'PNG', 0, 0, HTML_Width_2, HTML_Height_2);
pdf.save("my_file.pdf");
});
#Using display: inline-block To get all elements to appear on one line the easiest way is to: Set white-space property to nowrap on a parent element; Have display: inline-block set on all child elements.
To create line breaks in HTML, use the <br> tag. There is no closing tag necessary. In the code above, there will be a line break between "125 N 6th St" and "Brooklyn, NY 11249" that won't have the outrageous amount of space that appears between two paragraph elements.
HTML provides <hr> tag to draw horizontal line between two elements. You can also use <hr> tag between two divs to separate them properly.
So heree is my solution with SVG!
const xmlns = 'http://www.w3.org/2000/svg'
, svgLink = 'http://www.w3.org/1999/xlink'
, elmSVG = document.getElementById('elmSVG')
, bot_inversor = 80
, top_fotovolta = 300
;
for (let i=0;i<4;i++)
{
let x = 10 + (i*60)
, fotovolta = document.createElementNS(xmlns, 'use');
fotovolta.setAttributeNS(svgLink, 'xlink:href', '#fotovoltaico');
fotovolta.setAttributeNS(null, 'x', x);
fotovolta.setAttributeNS(null, 'y', top_fotovolta);
fotovolta.setAttributeNS(null, 'width', '50');
fotovolta.setAttributeNS(null, 'height', '70');
elmSVG.appendChild(fotovolta);
adjustLines(i);
}
function adjustLines(item)
{
let left = (item<2) // the hard part...
, b1 = 25 + (item *60) + (left?0:20)
, b2 = b1 + (left?20:-20)
, a1 = 105 + (item *10) + (left?0:10)
, a2 = a1 + (left?5:-5)
, l1 = 50 + (left?item:3-item) *30
, l2 = l1 + 10
;
let jLine1 = document.createElementNS(xmlns, 'polyline');
jLine1.setAttributeNS(null, 'points', `${b1},${top_fotovolta} ${b1},${bot_inversor+l1} ${a1},${bot_inversor+l1} ${a1},${bot_inversor}`);
elmSVG.appendChild(jLine1);
let jLine2 = document.createElementNS(xmlns, 'polyline');
jLine2.setAttributeNS(null, 'points', `${b2},${top_fotovolta} ${b2},${bot_inversor+l2} ${a2},${bot_inversor+l2} ${a2},${bot_inversor}`);
elmSVG.appendChild(jLine2);
}
#elmSVG {
width: 250px;
height: 380px;
background-color: #b4f0f0;
margin: 1em;
}
#elmSVG * {
fill:none;
stroke:#2f363d;
stroke-width:2px;
}
.curveSVG {
stroke-linecap:round;
}
<h2>Connecting Lines</h2>
<svg id="elmSVG" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 380">
<defs>
<symbol id="inversor" viewBox="0 0 70 70">
<rect x="0" y="0" width="70" height="70" />
<line x1="70" x2="0" y1="0" y2="70" />
<line x1="10" x2="30" y1="15" y2="15" />
<line x1="10" x2="30" y1="20" y2="20" />
<path d="M 40,55 Q 45,45 50,55 T 60,55" class="curveSVG" />
</symbol>
<symbol id="fotovoltaico" viewBox="0 0 50 70">
<rect x="0" y="0" width="50" height="70" />
<line x1="0" x2="25" y1="0" y2="20" />
<line x1="50" x2="25" y1="0" y2="20" />
</symbol>
</defs>
<use xlink:href="#inversor" x="90" y="10" width="70" height="70" />
</svg>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With