Add inline labels to a horizontal bar with pure SVG - svg

I use the bellow SVG code to build a horizontal bar chart. It is OK, but I need also two inline labels before and after the chart. I know how to add them with HTML and CSS, but I want to solve this only with pure SVG. How to do this?
<svg class="chart" width="300px" height="40">
<g transform="translate(0,0)">
<rect width="82%" height="22" fill="lightskyblue"></rect>
<rect width="100%" height="22" style="fill:none; stroke-width:1; stroke:gray;"></rect>
<text y="30" dx="0.25em" dy=".35em">0</text>
<text x="20%" y="10" dy=".35em" fill="red">|</text>
<text x="20%" y="30" dx="-0.25em" dy=".35em" fill="red">13</text>
<text x="100%" y="30" dx="-1.25em" dy=".35em">63</text>
</g>
</svg>
This is what I have now:
And this is what I want:

In order to make it work I'm using your code as a nested svg inside a larger svg element. Please observe I'm using a viewBox attribute where the x component has a negative value (-50) making space for the text.
svg{border:solid;}
<svg class="chart" width="300px" viewBox="-50 0 400 40">
<text y="20" x="-45">TXT</text>
<text x="345" y="20" text-anchor="end">TXT</text>
<svg viewBox="0 0 300 40" width="300">
<rect width="82%" height="22" fill="lightskyblue"></rect>
<rect width="100%" height="22" style="fill:none; stroke-width:1; stroke:gray;"></rect>
<text y="30" dx="0.25em" dy=".35em">0</text>
<text x="20%" y="10" dy=".35em" fill="red">|</text>
<text x="20%" y="30" dx="-0.25em" dy=".35em" fill="red">13</text>
<text x="100%" y="30" dx="-1.25em" dy=".35em">63</text>
</svg>
</svg>
I must tell you that I wouldn't percentages for the position and size of the rects. I would have done it using user units (without unit identifier) and I wouldn't have needed to wrap it in another svg element.
UPDATE
the OP is commenting
Can you give another example, without percentages for the position and size of the rects and without wrapping it in another svg element
svg{border:solid}
<svg class="chart" width="300px" viewBox="-50 0 400 40">
<text y="20" x="-45">TXT</text>
<text x="345" y="20" text-anchor="end">TXT</text>
<rect width="246" height="22" fill="lightskyblue"></rect>
<rect width="300" height="22" style="fill:none; stroke-width:1; stroke:gray;"></rect>
<text y="30" dx="0.25em" dy=".35em">0</text>
<text x="60" y="10" dy=".35em" fill="red">|</text>
<text x="60" y="30" dx="-0.25em" dy=".35em" fill="red">13</text>
<text x="300" y="30" dx="-1.25em" dy=".35em">63</text>
<svg>

Related

What is the relationship between font-size and x/y percentages for positioning text elements in an SVG?

I am trying to center text in an area based on some shapes.
In the example below, each square has a height and width of 50% of the SVG. I am trying to center the very large "X" character. Intuitively, I thought setting the text's x and y to the center of any square (25%,25% or 25%,75% or 75%,75% or 75%,25%), but it is off. I need to adjust the percentage a little more to center them.
In the example below, it looks like my intuition is wrong in the upper left square, whereas adjusting the y% a little centers it in the upper right square. The smaller blue and green squares are included to show exactly where 25%,25% and 25%,75% are.
I notice that this changes when font size changes as well. Is there a way to center text based on the font size using percentages? What key concept am I missing for understanding why this doesnt work?
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 200 200">
<style>
.f{font-family:monospace;font-size:80pt}
</style>
<rect width="50%" height="50%" y="0%" fill="red"/>
<rect width="50%" height="50%" y="50%" fill="green"/>
<rect width="50%" height="50%" y="0%" x="50%" fill="yellow"/>
<rect width="50%" height="50%" y="50%" x="50%" fill="blue"/>
<text x="25%" y="25%" class="f" dominant-baseline="middle" text-anchor="middle">X</text>
<text x="75%" y="29%" class="f" dominant-baseline="middle" text-anchor="middle" fill="blue">X</text>
<rect width="25%" height="25%" y="25%" x="25%" fill="blue"/>
<rect width="25%" height="25%" y="25%" x="75%" fill="green"/>
</svg>
Looks like you want dominant-baseline="central" rather than middle.
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 200 200">
<style>
.f{font-family:monospace;font-size:80pt}
</style>
<rect width="50%" height="50%" y="0%" fill="red"/>
<rect width="50%" height="50%" y="50%" fill="green"/>
<rect width="50%" height="50%" y="0%" x="50%" fill="yellow"/>
<rect width="50%" height="50%" y="50%" x="50%" fill="blue"/>
<text x="25%" y="25%" class="f" dominant-baseline="central" text-anchor="middle">X</text>
<text x="75%" y="29%" class="f" dominant-baseline="central" text-anchor="middle" fill="blue">X</text>
<rect width="25%" height="25%" y="25%" x="25%" fill="blue"/>
<rect width="25%" height="25%" y="25%" x="75%" fill="green"/>
</svg>
The font allows for all characters to be displayed.
You need to change the baseline
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/alignment-baseline
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/baseline-shift

How to make SVG black bar with centered text responsive?

I'm trying to make an SVG element fit to the bottom of the page with "Loading..." text centered regardless of the container's width. This is my current code which isn't working as the message is always in a fixed position.
<svg id="svg-bottom" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs></defs>
<g id="bottom">
<rect height="40" width="100%" y="0" x="0" fill="#000000" fill-opacity="0.676460598" id="panel"></rect>
<text id="status" font-family="GothamRounded-Medium, Gotham Rounded" font-size="20" font-weight="400" fill="#FFFFFF">
<tspan x="190.97" y="16">Loading…</tspan>
</text>
</g>
I solved the above with the following:
<text font-family="GothamRounded-Medium, Gotham Rounded" font-size="20" font-weight="400" fill="#FFFFFF" x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">Loading…</text>

What is the data-value attribute in SVG?

I was looking at this article
And particularly this code,
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="graph" aria-labelledby="title" role="img">
<title id="title">A line chart showing some information</title>
<g class="grid x-grid" id="xGrid">
<line x1="90" x2="90" y1="5" y2="371"></line>
</g>
<g class="grid y-grid" id="yGrid">
<line x1="90" x2="705" y1="370" y2="370"></line>
</g>
<g class="labels x-labels">
<text x="100" y="400">2008</text>
<text x="246" y="400">2009</text>
<text x="392" y="400">2010</text>
<text x="538" y="400">2011</text>
<text x="684" y="400">2012</text>
<text x="400" y="440" class="label-title">Year</text>
</g>
<g class="labels y-labels">
<text x="80" y="15">15</text>
<text x="80" y="131">10</text>
<text x="80" y="248">5</text>
<text x="80" y="373">0</text>
<text x="50" y="200" class="label-title">Price</text>
</g>
<g class="data" data-setname="Our first data set">
<circle cx="90" cy="192" data-value="7.2" r="4"></circle>
<circle cx="240" cy="141" data-value="8.1" r="4"></circle>
<circle cx="388" cy="179" data-value="7.7" r="4"></circle>
<circle cx="531" cy="200" data-value="6.8" r="4"></circle>
<circle cx="677" cy="104" data-value="6.7" r="4"></circle>
</g>
</svg>
And I was wondering what data-value attribute was. When I tried googling for some documentation I only found this page, which said:
The data-* SVG attributes are called custom data attributes. They let SVG markup and its resulting DOM share information that standard attributes can't, usually for scripting purposes. Their custom data are available via the SVGElement interface of the element the attributes belong to, with the SVGElement.dataset property.
And since I'm new at SVG, I wasn't sure what this meant. If someone could elucidate me on what data-value is that would be great!

Cut off half of the SVG's text element

How can I make this
to look like this
So I want to halve the text element. I don't want to hide half of the text outside of SVG. Hiding it outside of g would be ok, but haven't found solution.
<svg width="500" height="500">
<g transform="translate(50,50)">
<rect width="80" height="50" style="fill:rgb(0,0,255);"/>
<text font-size="40" x="0" y="15" fill="black">SVG</text>
</g>
</svg>
JSFIDDLE:
http://jsfiddle.net/64nkLcdy/
Use the clip-path property :
<svg width="500" height="500">
<defs>
<clipPath id="myClip">
<rect width="80" height="50" />
</clipPath>
</defs>
<g transform="translate(50,50)">
<rect width="80" height="50" style="fill:rgb(0,0,255);" />
<text font-size="40" x="0" y="15" fill="black" clip-path="url(#myClip)">SVG</text>
</g>
</svg>
Use an <svg> element rather than a <g> as the svg element will clip its contents by default. The overflow property controls clipping i.e overflow="visible" doesn't clip but overflow="hidden" does.
<svg width="500" height="500">
<svg transform="translate(50,50)" width="80" height="50" overflow="hidden">
<rect width="80" height="50" style="fill:rgb(0,0,255);"/>
<text font-size="40" x="0" y="15" fill="black">SVG</text>
</svg>
</svg>

SVG Text and Rect position

I have this code:
<g pointer-events="default">
<g>
<g x="0" y="0" width="145" height="47" regroup="false">
<text x="0" y="0">
<tspan x="0" y="0">some text</tspan>
</text>
</g>
<g x="0" y="0" width="80" height="60" regroup="false">
<rect x="0" y="0" width="80" height="60" fill="white" />
</g>
</g>
</g>
There is one css rule box-sizing: border-box;which is apply to all elements.
It produce that:
The grid is coming from a sliding element from the first <g>.
I don't understand why the text element and the rect are not displayed at the same y.
Does anyone have any idea?

Resources