FIDDLE
https://jsfiddle.net/vmt9z401/
HTML
<svg id="svg-timer" xmlns="http://www.w3.org/2000/svg">
<line class="timer-hours" x1="8.3333333333333%" y1="0" x2="8.3333333333333%" y2="325"></line>
<text x="8.3333333333333%" y="340" text-anchor="middle" fill="black">1H</text>
<line class="timer-hours" x1="16.666666666667%" y1="0" x2="16.666666666667%" y2="325"></line>
<text x="16.666666666667%" y="340" text-anchor="middle" fill="black">2H</text>
<line class="timer-hours" x1="25%" y1="0" x2="25%" y2="325"></line>
<text x="25%" y="340" text-anchor="middle" fill="black">3H</text>
<line class="timer-hours" x1="33.333333333333%" y1="0" x2="33.333333333333%" y2="325"></line>
<text x="33.333333333333%" y="340" text-anchor="middle" fill="black">4H</text>
<line class="timer-hours" x1="41.666666666667%" y1="0" x2="41.666666666667%" y2="325"></line>
<text x="41.666666666667%" y="340" text-anchor="middle" fill="black">5H</text>
<line class="timer-hours" x1="50%" y1="0" x2="50%" y2="325"></line>
<text x="50%" y="340" text-anchor="middle" fill="black">6H</text>
<line class="timer-hours" x1="58.333333333333%" y1="0" x2="58.333333333333%" y2="325"></line>
<text x="58.333333333333%" y="340" text-anchor="middle" fill="black">7H</text>
<line class="timer-hours" x1="66.666666666667%" y1="0" x2="66.666666666667%" y2="325"></line>
<text x="66.666666666667%" y="340" text-anchor="middle" fill="black">8H</text>
<line class="timer-hours" x1="75%" y1="0" x2="75%" y2="325"></line>
<text x="75%" y="340" text-anchor="middle" fill="black">9H</text>
<line class="timer-hours" x1="83.333333333333%" y1="0" x2="83.333333333333%" y2="325"></line>
<text x="83.333333333333%" y="340" text-anchor="middle" fill="black">10H</text>
<line class="timer-hours" x1="91.666666666667%" y1="0" x2="91.666666666667%" y2="325"></line>
<text x="91.666666666667%" y="340" text-anchor="middle" fill="black">11H</text>
<line class="timer-quarters" x1="2.0833333333333%" y1="0" x2="2.0833333333333%" y2="350"></line>
<line class="timer-quarters" x1="4.1666666666667%" y1="0" x2="4.1666666666667%" y2="350"></line>
<line class="timer-quarters" x1="6.25%" y1="0" x2="6.25%" y2="350"></line>
<line class="timer-quarters" x1="10.416666666667%" y1="0" x2="10.416666666667%" y2="350"></line>
<line class="timer-quarters" x1="12.5%" y1="0" x2="12.5%" y2="350"></line>
<line class="timer-quarters" x1="14.583333333333%" y1="0" x2="14.583333333333%" y2="350"></line>
<line class="timer-quarters" x1="18.75%" y1="0" x2="18.75%" y2="350"></line>
<line class="timer-quarters" x1="20.833333333333%" y1="0" x2="20.833333333333%" y2="350"></line>
<line class="timer-quarters" x1="22.916666666667%" y1="0" x2="22.916666666667%" y2="350"></line>
<line class="timer-quarters" x1="27.083333333333%" y1="0" x2="27.083333333333%" y2="350"></line>
<line class="timer-quarters" x1="29.166666666667%" y1="0" x2="29.166666666667%" y2="350"></line>
<line class="timer-quarters" x1="31.25%" y1="0" x2="31.25%" y2="350"></line>
<line class="timer-quarters" x1="35.416666666667%" y1="0" x2="35.416666666667%" y2="350"></line>
<line class="timer-quarters" x1="37.5%" y1="0" x2="37.5%" y2="350"></line>
<line class="timer-quarters" x1="39.583333333333%" y1="0" x2="39.583333333333%" y2="350"></line>
<line class="timer-quarters" x1="43.75%" y1="0" x2="43.75%" y2="350"></line>
<line class="timer-quarters" x1="45.833333333333%" y1="0" x2="45.833333333333%" y2="350"></line>
<line class="timer-quarters" x1="47.916666666667%" y1="0" x2="47.916666666667%" y2="350"></line>
<line class="timer-quarters" x1="52.083333333333%" y1="0" x2="52.083333333333%" y2="350"></line>
<line class="timer-quarters" x1="54.166666666667%" y1="0" x2="54.166666666667%" y2="350"></line>
<line class="timer-quarters" x1="56.25%" y1="0" x2="56.25%" y2="350"></line>
<line class="timer-quarters" x1="60.416666666667%" y1="0" x2="60.416666666667%" y2="350"></line>
<line class="timer-quarters" x1="62.5%" y1="0" x2="62.5%" y2="350"></line>
<line class="timer-quarters" x1="64.583333333333%" y1="0" x2="64.583333333333%" y2="350"></line>
<line class="timer-quarters" x1="68.75%" y1="0" x2="68.75%" y2="350"></line>
<line class="timer-quarters" x1="70.833333333333%" y1="0" x2="70.833333333333%" y2="350"></line>
<line class="timer-quarters" x1="72.916666666667%" y1="0" x2="72.916666666667%" y2="350"></line>
<line class="timer-quarters" x1="77.083333333333%" y1="0" x2="77.083333333333%" y2="350"></line>
<line class="timer-quarters" x1="79.166666666667%" y1="0" x2="79.166666666667%" y2="350"></line>
<line class="timer-quarters" x1="81.25%" y1="0" x2="81.25%" y2="350"></line>
<line class="timer-quarters" x1="85.416666666667%" y1="0" x2="85.416666666667%" y2="350"></line>
<line class="timer-quarters" x1="87.5%" y1="0" x2="87.5%" y2="350"></line>
<line class="timer-quarters" x1="89.583333333333%" y1="0" x2="89.583333333333%" y2="350"></line>
<line class="timer-quarters" x1="93.75%" y1="0" x2="93.75%" y2="350"></line>
<line class="timer-quarters" x1="95.833333333333%" y1="0" x2="95.833333333333%" y2="350"></line>
<line class="timer-quarters" x1="97.916666666667%" y1="0" x2="97.916666666667%" y2="350"></line>
</svg>
CSS
#svg-timer {
width: 100%;
display: block;
height: 350px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2);
font-family: Arial;
}
.timer-hours {
stroke: rgb(0, 0, 0);
stroke-width: 1;
}
.timer-quarters {
stroke: rgb(0, 0, 0);
stroke-width: 0.03em;
}
Description
I want to draw 11 lines, one for each hour - which are all the same (timer-hours class). They got a text beneath them. Everything works fine to this point.
Question
The lines have different thicknesses - why do they have not the same "thickness" ?
I got two different screens and i get the problem on both.
I also tried with
stroke-width: 0.1em;
but there is no change.
Do i need another unit (px)?
On the Screenshot, it also looks different?!
Screenshot
Add shape-rendering: crispEdges;
#svg-timer {
width: 100%;
display: block;
height: 350px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2);
font-family: Arial;
shape-rendering: crispEdges;
}
.timer-hours {
stroke: rgb(0, 0, 0);
stroke-width: 1;
}
.timer-quarters {
stroke: rgb(0, 0, 0);
stroke-width: 0.03em;
}
<svg id="svg-timer" xmlns="http://www.w3.org/2000/svg">
<line class="timer-hours" x1="8.3333333333333%" y1="0" x2="8.3333333333333%" y2="325"></line>
<text x="8.3333333333333%" y="340" text-anchor="middle" fill="black">1H</text>
<line class="timer-hours" x1="16.666666666667%" y1="0" x2="16.666666666667%" y2="325"></line>
<text x="16.666666666667%" y="340" text-anchor="middle" fill="black">2H</text>
<line class="timer-hours" x1="25%" y1="0" x2="25%" y2="325"></line>
<text x="25%" y="340" text-anchor="middle" fill="black">3H</text>
<line class="timer-hours" x1="33.333333333333%" y1="0" x2="33.333333333333%" y2="325"></line>
<text x="33.333333333333%" y="340" text-anchor="middle" fill="black">4H</text>
<line class="timer-hours" x1="41.666666666667%" y1="0" x2="41.666666666667%" y2="325"></line>
<text x="41.666666666667%" y="340" text-anchor="middle" fill="black">5H</text>
<line class="timer-hours" x1="50%" y1="0" x2="50%" y2="325"></line>
<text x="50%" y="340" text-anchor="middle" fill="black">6H</text>
<line class="timer-hours" x1="58.333333333333%" y1="0" x2="58.333333333333%" y2="325"></line>
<text x="58.333333333333%" y="340" text-anchor="middle" fill="black">7H</text>
<line class="timer-hours" x1="66.666666666667%" y1="0" x2="66.666666666667%" y2="325"></line>
<text x="66.666666666667%" y="340" text-anchor="middle" fill="black">8H</text>
<line class="timer-hours" x1="75%" y1="0" x2="75%" y2="325"></line>
<text x="75%" y="340" text-anchor="middle" fill="black">9H</text>
<line class="timer-hours" x1="83.333333333333%" y1="0" x2="83.333333333333%" y2="325"></line>
<text x="83.333333333333%" y="340" text-anchor="middle" fill="black">10H</text>
<line class="timer-hours" x1="91.666666666667%" y1="0" x2="91.666666666667%" y2="325"></line>
<text x="91.666666666667%" y="340" text-anchor="middle" fill="black">11H</text>
<line class="timer-quarters" x1="2.0833333333333%" y1="0" x2="2.0833333333333%" y2="350"></line>
<line class="timer-quarters" x1="4.1666666666667%" y1="0" x2="4.1666666666667%" y2="350"></line>
<line class="timer-quarters" x1="6.25%" y1="0" x2="6.25%" y2="350"></line>
<line class="timer-quarters" x1="10.416666666667%" y1="0" x2="10.416666666667%" y2="350"></line>
<line class="timer-quarters" x1="12.5%" y1="0" x2="12.5%" y2="350"></line>
<line class="timer-quarters" x1="14.583333333333%" y1="0" x2="14.583333333333%" y2="350"></line>
<line class="timer-quarters" x1="18.75%" y1="0" x2="18.75%" y2="350"></line>
<line class="timer-quarters" x1="20.833333333333%" y1="0" x2="20.833333333333%" y2="350"></line>
<line class="timer-quarters" x1="22.916666666667%" y1="0" x2="22.916666666667%" y2="350"></line>
<line class="timer-quarters" x1="27.083333333333%" y1="0" x2="27.083333333333%" y2="350"></line>
<line class="timer-quarters" x1="29.166666666667%" y1="0" x2="29.166666666667%" y2="350"></line>
<line class="timer-quarters" x1="31.25%" y1="0" x2="31.25%" y2="350"></line>
<line class="timer-quarters" x1="35.416666666667%" y1="0" x2="35.416666666667%" y2="350"></line>
<line class="timer-quarters" x1="37.5%" y1="0" x2="37.5%" y2="350"></line>
<line class="timer-quarters" x1="39.583333333333%" y1="0" x2="39.583333333333%" y2="350"></line>
<line class="timer-quarters" x1="43.75%" y1="0" x2="43.75%" y2="350"></line>
<line class="timer-quarters" x1="45.833333333333%" y1="0" x2="45.833333333333%" y2="350"></line>
<line class="timer-quarters" x1="47.916666666667%" y1="0" x2="47.916666666667%" y2="350"></line>
<line class="timer-quarters" x1="52.083333333333%" y1="0" x2="52.083333333333%" y2="350"></line>
<line class="timer-quarters" x1="54.166666666667%" y1="0" x2="54.166666666667%" y2="350"></line>
<line class="timer-quarters" x1="56.25%" y1="0" x2="56.25%" y2="350"></line>
<line class="timer-quarters" x1="60.416666666667%" y1="0" x2="60.416666666667%" y2="350"></line>
<line class="timer-quarters" x1="62.5%" y1="0" x2="62.5%" y2="350"></line>
<line class="timer-quarters" x1="64.583333333333%" y1="0" x2="64.583333333333%" y2="350"></line>
<line class="timer-quarters" x1="68.75%" y1="0" x2="68.75%" y2="350"></line>
<line class="timer-quarters" x1="70.833333333333%" y1="0" x2="70.833333333333%" y2="350"></line>
<line class="timer-quarters" x1="72.916666666667%" y1="0" x2="72.916666666667%" y2="350"></line>
<line class="timer-quarters" x1="77.083333333333%" y1="0" x2="77.083333333333%" y2="350"></line>
<line class="timer-quarters" x1="79.166666666667%" y1="0" x2="79.166666666667%" y2="350"></line>
<line class="timer-quarters" x1="81.25%" y1="0" x2="81.25%" y2="350"></line>
<line class="timer-quarters" x1="85.416666666667%" y1="0" x2="85.416666666667%" y2="350"></line>
<line class="timer-quarters" x1="87.5%" y1="0" x2="87.5%" y2="350"></line>
<line class="timer-quarters" x1="89.583333333333%" y1="0" x2="89.583333333333%" y2="350"></line>
<line class="timer-quarters" x1="93.75%" y1="0" x2="93.75%" y2="350"></line>
<line class="timer-quarters" x1="95.833333333333%" y1="0" x2="95.833333333333%" y2="350"></line>
<line class="timer-quarters" x1="97.916666666667%" y1="0" x2="97.916666666667%" y2="350"></line>
</svg>
The lines have different thicknesses - why do they have not the same "thickness" ?
The answer is "because of anti-aliasing". Antialiasing is the use of semi-transparent pixels along the edges of a shape. The purpose is to smooth out the look of the edges to simulate the fact that the edge of the shape is covering only a portion of the edge pixels. So, for example, a black shape that covers only half of a pixel will be drawn as a black pixel that is 50% transparent. Resulting in a 50% grey pixel, assuming it is on a white background.
Your lines have erratic widths because of anti-aliasing, and is exacerbated by the fact that your lines are positioned at inconsistent places relative to pixel boundaries.
Anti-aliasing is great, but it has limits. Using shape-rendering="crispEdges" can help.
But a possibly better solution is to choose a graph size so that your graph lines align to pixel boundaries. You either have to choose whole pixel coordinates, or half (0.5) coordinate values depending on whether your stroke-width is even or odd.
See this answer for more information:
https://stackoverflow.com/a/23376793/1292848
Related
The SVG example currently visually looks perfect except I want to achieve the same result without padding.
The padding's purpose is to force the red/blue lines 40px to the right to make space for the axis whilst also stopping it from overflowing on the right side of the graph.
I'm trying to remove the padding, but then I need to find a new way to shift JUST the "lines" 40px to the right without using x="40px" width="calc(100% - 40px)" because this syntax also isn't compatible with Sharp, or older browsers.
Is there any way to remove the padding and shift the lines 40px right whilst also constraining it within the box model of the SVG?
(final note: I don't want to use 'responsive' units in any logic that moves the lines)
JSFiddle of line graph: https://jsfiddle.net/Lefsqo3j/14/
<div style="height:148px;width:300px;overflow:hidden;resize:both">
<svg overflow="visible" style="padding:24px 0px 24px 40px" height="100%" width="100%">
<svg role="img" viewBox="0 0 300 100" preserveAspectRatio="none">
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<line y1="0" y2="100" x1="0" x2="0" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="75" x2="75" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="150" x2="150" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="225" x2="225" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="300" x2="300" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="0" y2="0" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="25" y2="25" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="50" y2="50" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="75" y2="75" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="100" y2="100" stroke-width="0.2" stroke="black"></line>
</svg>
</svg>
<svg x="100%" overflow="visible">
<text text-anchor="end" dy="-8px">
<tspan fill="red"> ⬤</tspan>
Line A<tspan fill="blue"> ⬤</tspan>
Line B
</text>
</svg>
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<path
d="M 0 75 M 0 75 L 75 50 L 150 15 L 225 67 L 300 67 L 300 67"
stroke-width="3"
stroke="red"
fill="transparent"
vector-effect="non-scaling-stroke"
></path>
<path
d="M 0 92 M 0 92 L 75 72 L 150 80 L 225 50 L 300 50 L 300 50"
stroke-width="3"
stroke="blue"
fill="transparent"
></path>
</svg>
<svg overflow="visible">
<text x="0%" text-anchor="end" y="0%">
40
</text>
<text x="0%" text-anchor="end" y="25%">
30
</text>
<text x="0%" text-anchor="end" y="50%">
20
</text>
<text x="0%" text-anchor="end" y="75%">
10
</text>
<text x="0%" text-anchor="end" y="100%">
0
</text>
<g style="transform: translateX(0%);">
<text y="100%" dy="16px">
5
</text>
</g>
<g style="transform: translateX(25%);">
<text y="100%" dy="16px">
10
</text>
</g>
<g style="transform: translateX(50%); ">
<text y="100%" dy="16px">
15
</text>
</g>
<g style="transform: translateX(75%); ">
<text y="100%" dy="16px">
20
</text>
</g>
<g text-anchor="end" style="transform: translateX(100%);">
<text y="100%" dy="16px">
25
</text>
</g>
</svg>
</svg>
</div>
I've modified the SVG and brought the content inside the content box. Dimensions scale uniformly maintaining aspect ratio.
<div style="height:148px;
width:300px;
overflow:hidden;
resize:both;
background-color: wheat;
">
<svg class="chart" overflow="visible">
<style>
.chart {
width: 100%;
height: 100%;
font-size: 14px;
padding-bottom: 24px;
}
/* background color for entire chart */
.chart-background {
fill: rgb(230, 249, 255);
}
/* styling for only the graph part */
.graph {
background-color: transparent;
}
/* grid lines style */
.chart .grid>line {
stroke-width: 0.5;
stroke: green;
}
.legend {
background-color: wheat;
}
.labels {
background-color: transparent !important;
}
.back {
background-color: wheat;
}
</style>
<rect class="chart-background" height="100%" width="100%" />
<svg viewBox="0 0 340 140" x="40" y="24" preserveAspectRatio="none">
<g class="grid">
<line y1="0" y2="100" x1="0" x2="0"></line>
<line y1="0" y2="100" x1="75" x2="75"></line>
<line y1="0" y2="100" x1="150" x2="150"></line>
<line y1="0" y2="100" x1="225" x2="225"></line>
<line y1="0" y2="100" x1="300" x2="300"></line>
<line x1="0" x2="300" y1="0" y2="0"></line>
<line x1="0" x2="300" y1="25" y2="25"></line>
<line x1="0" x2="300" y1="50" y2="50"></line>
<line x1="0" x2="300" y1="75" y2="75"></line>
<line x1="0" x2="300" y1="100" y2="100"></line>
</g>
</svg>
<svg>
<g class="legend">
<text x="100%" text-anchor="end" dy="16">
<tspan fill="red"> ⬤</tspan>Line A<tspan fill="blue"> ⬤</tspan>Line B
</text>
</g>
</svg>
<svg overflow="visible" x="40" y="24" height="70%" width="88%" style="margin-bottom: 24px;">
<g class="labels" style="font-size: 12px;">
<text x="0%" text-anchor="end" y="0%">40</text>
<text x="0%" text-anchor="end" y="25%">30</text>
<text x="0%" text-anchor="end" y="50%">20</text>
<text x="0%" text-anchor="end" y="75%">10</text>
<text x="0%" text-anchor="end" y="100%">0</text>
<text y="100%" dy="16px">5</text>
<text y="100%" dy="16px" x="22%">10</text>
<text y="100%" dy="16px" x="48%">15</text>
<text y="100%" dy="16px" x="74%">20</text>
<text y="100%" dy="16px" dx="-20px" x="100%">25</text>
</g>
</svg>
<svg viewBox="0 0 340 140" x="40" y="24" preserveAspectRatio="none">
<g class="plot">
<path d="M 0 75 M 0 75 L 75 50 L 150 15 L 225 67 L 300 67 L 300 67" stroke-width="3" stroke="red"
fill="transparent" vector-effect="non-scaling-stroke"></path>
<path d="M 0 92 M 0 92 L 75 72 L 150 80 L 225 50 L 300 50 L 300 50" stroke-width="3" stroke="blue"
fill="transparent"></path>
</g>
</svg>
</svg>
</div>
Sharpjs:
const svgBuffer = Buffer.from(svgImage);
const image = await sharp(svgBuffer, {})
.resize({ width: 500, fit: sharp.fit.inside, position: 'centre' })
.toFile('e:/svg-image.png');
Old answer
We can wrap the original svg content in a new <svg> tag. And with custom styles the original svg can be positioned such that overflow will be visible:
const sharp = require('sharp');
async function svgToImage(svgImage) {
try {
const wrapped = `<svg id='wrapper' width="600" height="400">
<style>
#wrapper > svg{
transform: scale(.9) translate(25px, 25px) ;
}
</style>
${svgImage}
</svg>`;
const svgBuffer = Buffer.from(wrapped);
//const image = await sharp(svgBuffer, {}).resize(500).toFile('e:/svg-image.png');
const image = await sharp({
create: {
width: 600,
height: 400,
channels: 4,
background: { r: 220, g: 255, b: 220, alpha: 1 },
},
})
.composite([{ input: svgBuffer, top: 0, left: 0 }])
.png()
.toFile('e:/svg-image.png');
} catch (error) {
console.log(error);
}
}
const svgImage = `
<svg overflow="visible" style="padding:24px 0px 24px 40px">
<svg role="img" viewBox="0 0 300 100" preserveAspectRatio="none">
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<line y1="0" y2="100" x1="0" x2="0" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="75" x2="75" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="150" x2="150" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="225" x2="225" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="300" x2="300" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="0" y2="0" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="25" y2="25" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="50" y2="50" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="75" y2="75" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="100" y2="100" stroke-width="0.2" stroke="black"></line>
</svg>
</svg>
<svg x="100%" overflow="visible">
<text text-anchor="end" dy="-8px">
<tspan fill="red"> ⬤</tspan>
Line A<tspan fill="blue"> ⬤</tspan>
Line B
</text>
</svg>
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<path
d="M 0 75 M 0 75 L 75 50 L 150 15 L 225 67 L 300 67 L 300 67"
stroke-width="3"
stroke="red"
fill="transparent"
vector-effect="non-scaling-stroke"
></path>
<path
d="M 0 92 M 0 92 L 75 72 L 150 80 L 225 50 L 300 50 L 300 50"
stroke-width="3"
stroke="blue"
fill="transparent"
></path>
</svg>
<svg overflow="visible">
<text x="0%" text-anchor="end" y="0%">40</text>
<text x="0%" text-anchor="end" y="25%">30</text>
<text x="0%" text-anchor="end" y="50%">20</text>
<text x="0%" text-anchor="end" y="75%">10</text>
<text x="0%" text-anchor="end" y="100%">0</text>
<text y="100%" dy="16px">5</text>
<text y="100%" dy="16px" x="25%">10</text>
<text y="100%" dy="16px" x="50%">15</text>
<text y="100%" dy="16px" x="75%">20</text>
<text y="100%" dy="16px" x="100%">25</text>
</svg>
</svg>`;
svgToImage(svgImage);
Output:
On x axis the labels didn't behave because of bug and bug related to transform. So I had to modify the x label tags.
This question already has answers here:
Why is SVG stroke-width : 1 making lines transparent?
(6 answers)
Closed 2 years ago.
Why are some of my lines in svg thicker than others?
All of them are on whole number coords. "stroke-width: 0.5" was my last attempt to create 1px line. I had tryed also elsewhere mentioned shape-rendering: crispedges with stroke of 1 pixel but with same setup those lines which appears thicker on image were straight 2px instead of 1. I would love to fix that somehow but even knowledge about how its determined which lines get thicker by what rule would be very appretiated. I dont understand why its so hard to make consistent 1px thick line using svg.
My code:
#my-svg {
width : 500px;
height: 500px;
margin: .5em;
}
#my-svg line {
stroke:black;
stroke-width:0.5;
}
<svg id="my-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<line x1="0" y1="26" x2="380" y2="26" ></line>
<line x1="0" y1="52" x2="380" y2="52" ></line>
<line x1="0" y1="78" x2="380" y2="78" ></line>
<line x1="0" y1="104" x2="380" y2="104"></line>
<line x1="0" y1="130" x2="380" y2="130"></line>
<line x1="0" y1="156" x2="380" y2="156"></line>
<line x1="0" y1="182" x2="380" y2="182"></line>
<line x1="40" y1="0" x2="40" y2="182"></line>
<line x1="240" y1="0" x2="240" y2="182"></line>
<line x1="300" y1="0" x2="300" y2="182"></line>
<line x1="380" y1="0" x2="380" y2="182"></line>
</svg>
Example when using stroke-width: 1 and shape-rendering: crispedges:
i used a html document and a seperated online editor to check your code twice. Your code is corect! It seems to be a browser visualisation error...
Quick tip: your code line can also end like this: stroke:black; stroke-width:0.5" />
If the error persists, please provide us with additional information such as browser, version, full code review, etc.
The Way it work for me:
<!DOCTYPE html>
<html>
<body>
<svg height="500" width="500" viewbox="0 0 500 500">
<line x1="0" y1="26" x2="380" y2="26" style="stroke:black; stroke-width:0.5" />
<line x1="0" y1="52" x2="380" y2="52" style="stroke:black; stroke-width:0.5" />
<line x1="0" y1="78" x2="380" y2="78" style="stroke:black; stroke-width:0.5" />
<line x1="0" y1="104" x2="380" y2="104" style="stroke:black; stroke-width:0.5" />
<line x1="0" y1="130" x2="380" y2="130" style="stroke:black; stroke-width:0.5" />
<line x1="0" y1="156" x2="380" y2="156" style="stroke:black; stroke-width:0.5" />
<line x1="0" y1="182" x2="380" y2="182" style="stroke:black; stroke-width:0.5" />
<line x1="40" y1="0" x2="40" y2="182" style="stroke:black; stroke-width:0.5" />
<line x1="240" y1="0" x2="240" y2="182" style="stroke:black; stroke-width:0.5" />
<line x1="300" y1="0" x2="300" y2="182" style="stroke:black; stroke-width:0.5" />
<line x1="380" y1="0" x2="380" y2="182" style="stroke:black; stroke-width:0.5" />
</svg>
</body>
</html>
How can i draw something like this in Html ?
<svg height="210" width="500">
<line x1="0" y1="100" x2="200" y2="100" style="stroke:rgb(255,0,0);stroke-width:2" />
<line x1="200" y1="50" x2="200" y2="150" style="stroke:rgb(255,250,0);stroke-width:2" />
<line x1="200" y1="50" x2="300" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />
<line x1="200" y1="150" x2="300" y2="150" style="stroke:rgb(255,0,0);stroke-width:2" />
</svg>
You can use something like the following:
https://jsfiddle.net/qj0672yx/2/
#leftbox {
float:left;
margin-top:65px;
margin-right: 10px;
}
#rightbox{
float:right;
margin-top:0px;
margin-left:0px;
}
#middlebox{
float:left;
margin-right:0px;
}
<div id = "leftbox">
<h2>TESTTESTTEST </h2> </div>
<div>
</div id = "middlebox">
<svg height="210">
<line x1="0" y1="100" x2="200" y2="100" style="stroke:rgb(0,0,0);stroke-width:2" />
<line x1="200" y1="50" x2="200" y2="150" style="stroke:rgb(0,0,0);stroke-width:2" />
<line x1="200" y1="50" x2="300" y2="50" style="stroke:rgb(0,0,0);stroke-width:2" />
<line x1="200" y1="150" x2="300" y2="150" style="stroke:rgb(0,0,0);stroke-width:2" />
</svg>
</div>
<div id = "rightbox">
<h2>TESTTESTTEST </h2> </div>
</div>
However using bootstrap for its grid system and ease to specify and locate the divs would be more logical in your situation. See the link for grid system:
https://getbootstrap.com/docs/4.3/layout/grid/
I wanted to create a graphics where there will be a rectangle node in the center and from each of it's corner edges, draw a cross line. That means 4 lines in 4 corner edge of the rectangle.
I could only show some lines in the top left edge of the rectangle. Can anyone guide me on how to show other three lines from that rectangle, please? I did not understand the line concept from the docs
Here is the demo
<svg width="800" height="600" viewbox="0 0 800 600" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 250 100)">
<rect width="200" height="60" rx="5" ry="5">
</rect>
<text x="100" y="30" font-size="14" text-anchor="middle" fill="white">
Root Node
</text>
<line x1="0" y1="0" x2="0" y2="90" stroke="black" stroke-width="3" transform="rotate(-220)"/>
<line x1="0" y1="0" x2="10" y2="90" stroke="black" stroke-width="3" transform="rotate(-220)"/>
<line x1="0" y1="0" x2="10" y2="90" stroke="black" stroke-width="3" transform="rotate(-220)"/>
<line x1="0" y1="0" x2="10" y2="90" stroke="black" stroke-width="3" transform="rotate(-220)"/>
</g>
</svg>
http://jsbin.com/jucosalice/edit?html,output
To draw cross lines at each corner without calculating coordinates, you can use rotate and translate properties:
<svg width="800" height="600" viewbox="0 0 800 600" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 250 100)">
<rect width="200" height="60" rx="5" ry="5">
</rect>
<text x="100" y="30" font-size="14" text-anchor="middle" fill="white">
Root Node
</text>
<line x1="0" y1="0" x2="100" y2="0" transform="rotate(-135)" stroke="black" stroke-width="3"/>
<line x1="0" y1="0" x2="100" y2="0" transform="translate(200 0) rotate(-45)" stroke="black" stroke-width="3"/>
<line x1="0" y1="0" x2="100" y2="0" transform="translate(0 60) rotate(135)" stroke="black" stroke-width="3"/>
<line x1="0" y1="0" x2="100" y2="0" transform="translate(200 60) rotate(45)" stroke="black" stroke-width="3"/>
</g>
</svg>
Explanation:
The X axis is from left to right, the Y axis is from top to bottom. The direction of rotation is clockwise. So, the code
<line x1="0" y1="0" x2="100" y2="0" transform="translate(200 0) rotate(-45)" stroke="black" stroke-width="3"/>
draws a line from (0,0) to (100,0), translate(shift) it by 200 unit in X direction towards right (as it is width of main rectangle), and then rotate it by -45 deg to get its slope.
See here for their documentation.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<svg width="800" height="600" viewbox="0 0 800 600" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 250 100)">
<rect width="200" height="60" rx="5" ry="5"></rect>
<text x="100" y="30" font-size="14" text-anchor="middle" fill="white">
Root Node
</text>
<line x1="0" y1="0" x2="-75" y2="-75" stroke="black" stroke-width="3"/>
<line x1="200" y1="60" x2="275" y2="135" stroke="black" stroke-width="3"/>
<line x1="200" y1="0" x2="275" y2="-75" stroke="black" stroke-width="3"/>
<line x1="0" y1="60" x2="-75" y2="135" stroke="black" stroke-width="3"/>
</g>
</svg>
</body>
</html>
SVG Line at this point isn't drawing line at this coordinates (x1="200" x2="0" y1="200" y2="200") . This problem happens only in Firefox. What mistake did I make?
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<line x1="0" x2="200" y1="0" y2="0" style="stroke:rgb(255,0,0);stroke-width:2"></line>
<line x1="200" x2="200" y1="0" y2="200" style="stroke:rgb(255,0,0);stroke-width:2"></line>
<line x1="0" x2="0" y1="0" y2="200" style="stroke:rgb(255,0,0);stroke-width:2"></line>
<line x1="200" x2="0" y1="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2"></line>
</svg>