score:18
when talking about rotating svg text, there are multiple different aspects:
how the browser determines where to position the next character based on the previous character's position;
how the characters are rotated relative to the baseline (
rotate
attribute);how the final text block as a whole is rotated relative to the coordinate system (
transform
attribute).
full, rather difficult to comprehend, specs here.
the 'writing-mode' property is supposed to change the first aspect without affecting the others, but as you discovered it's not implemented at all in firefox, while ie rotates the text but doesn't respect the horizontal-glyph rule.
theoretically, you should be able to get the same effect by combining the rotate and transform attributes: transform the entire <text>
element to rotate it into a vertical position, then reverse-rotate the individual characters to get them back to horizontal. but in practice, it gets messy...
for starters, the double rotations cause the text to be end up on the left of your (x,y) point, so if (x,y) is (0,0) it will be clipped outside the svg without supplemental shift. because of the transforms, you'll need a negative dy
value to move the text back to the right of the anchor point.
second, there is the fact that the rotation is applied to each character in place, the spacing of the characters isn't adjusted to account for the fact that an "l" is much taller than it is wide. so unless you're using monospace, things look pretty jumbled up. you're supposed to be able to change the letter spacing with the kerning
and letterspacing
properties, but browser support for those is also poor: ie11 doesn't seem to acknowledge the kerning value, and firefox doesn't acknowledge either.
a final option is to take control of the layout yourself: use the power of d3 and the string .split("")
method to break your title into single-character <tspan>
elements that can be positioned one below each other and centered neatly within the <text>
element. the downside is that this adds extra dom elements, you can still select the block of text as a whole, just the same as you could select a phrase in an html paragraph even if each letter was styled as a separate <span>
. i'm not sure if screen readers will automatically assume that there are spaces between the letters, though...
comparison
this fiddle tries out the three ways to get horizontal characters in a vertical text label (writing-mode vs double rotate vs splitting into <tspan>
s):
http://jsfiddle.net/hx5th/11/
code:
var svg = d3.select("body").append("svg");
//green text, uses writing-mode property //
svg.append("text")
.attr("x", 40)
.attr("y", 40)
.attr("id", "title")
.attr("font-size", 50)
.attr("style", "fill: lightgreen; writing-mode: tb; glyph-orientation-vertical: 0")
.text("top 100 mentions");
//black text, uses a double rotate //
svg.append("text")
.attr("x", 40)
.attr("y", 40)
.attr("id", "title")
.attr("font-size", 50)
.attr("rotate", -90)
.attr("dx", "1em")
.attr("dy", "-1em")
.attr("kerning", 0)
.attr("letter-spacing", "0.5em")
.attr("transform", "translate(150,0) rotate(90)")
.text("top 100 mentions");
//blue text, uses d3 to create a series of tspans//
svg.append("text")
.attr("x", 40)
.attr("y", 40)
.attr("font-size", 50)
.attr("id", "title")
.style("fill", "blue")
.attr("transform", "translate(300,0)")
.attr("text-anchor", "middle")
.selectall("tspan")
.data("top 100 mentions".split(""))
.enter().append("tspan")
.attr("x", 0)
.attr("dy", "0.8em")
.text(function(d){return d;});
results (all on a windows 7 system):
chrome 33
ie 11
firefox
i think this is d3 for the win...
score:0
you can control the position and orientation of text by binding it to a path element. example below with a running version on jsfiddle:
var svg = d3.select("body").append("svg"),
pi = math.pi;
var arc = d3.svg.arc()
.innerradius(150)
.outerradius(180)
.startangle(0)
.endangle(-pi/2)
var path = svg.append("path")
.attr("id","path1")
.attr("d","m150 150 l150 20 z")
.attr("style","stroke:rgb(255,0,0);stroke-width:2")
// add a text label.
var text = svg.append("text")
.attr("x", 6)
.attr("dy", 15);
text.append("textpath")
.attr("stroke","black")
.attr("xlink:href","#path1")
.text("abc");
score:0
this should do what you want (although i don't know how to express it in d3):
<text x="100" y="100" transform="rotate(90, 100, 100)" style="glyph-orientation-horizontal: 270;">some vertical text not rotated</text>
obviously change the x and y coords to your own values.
score:0
for firefox, the only thing i can find that they have implemented as of ff 30 is textlength. i added a fourth append of text to ameliabr's jsfiddle to demonstrate. it still looks like crap thought and d3 is still the winner. http://jsfiddle.net/hx5th/11/
//black text, uses a double rotate //
svg.append("text")
.attr("x", 40)
.attr("y", 40)
.attr("id", "title")
.attr("font-size", 50)
.attr("rotate", -90)
.attr("dx", "1em")
.attr("dy", "-1em")
.attr("textlength", "12.8em")
.attr("transform", "translate(450,0) rotate(90)")
.text("top 100 mentions");
score:1
html embedded in svg:
<svg
x="0px" y="0px"
width="200px" height="200px"
viewbox="0 0 200 200"
>
<foreignobject
x="20" y="20"
width="160" height="160"
>
<!-- we must set xmlns attribute
for foreignobject.childnode -->
<div
xmlns="http://www.w3.org/1999/xhtml"
style="
/* html-css vertical text */
writing-mode: vertical-lr;
text-orientation: upright;
line-height: 2em;
font-family: sans-serif;
font-size: 150%;
"
>hello<br/> world</div>
</foreignobject>
</svg>
Source: stackoverflow.com
Related Query
- Text on vertical bars not showing using d3.js
- Rotated rectangle not match text bbox
- d3.js - rotated text label not align with points exactly
- How to write vertical text from bottom to top without using transform rotate?
- SVG foreignObject contents do not display unless plain text
- NVD3 chart fails to calculate legend text length in Chrome, since Window.getComputedStyle does not return font-size correctly
- Appended text not showing in d3 v4
- vertical text in d3 (not rotated)
- How to center 90ยบ rotated text in SVG
- Appended text not appearing when using D3
- D3.js text element does not display unicode character correctly
- text not showing in forcelayout d3js but present in view
- With D3, how can I set attribute ("fill", "none") of axis path and line, but not text (without editing stylesheet)
- splitting text for some bold and some not on functional javascript piece
- SVG text element text-anchor="middle" not working in Firefox
- Text not displaying in the middle of circles in d3js
- Why is constructor function not setting <h6> text correctly?
- text elements not visible when appended from function
- Vertical alignment between an SVG rect and SVG text using D3 and javascript
- D3.js v4, not able to see text
- Can not break long sentence in a D3-generated SVG text
- Text does not stay wrapped on d3 tree nodes
- How to make sure text in treemap cell do not overflow?
- Text and Rectangle not align
- d3js text not showing on node graph
- Text inside non-transparent rectangle is not visible
- Text not showing as label in D3 force layout
- Why my rotated tick values are not getting displayed completely d3js?
- D3 bar chart bar text labels not visible properly
- Text appended to path does not show
More Query from same tag
- Donut Pie Chart - Add a Title - NVd3.js
- Tweening a object-based d3.svg.arc diagram (without redrawing it).
- How to import XML data using d3.js?
- TypeError/Undefined when adding conditional formatting to my bar chart
- D3.js Chord Diagram - Make chords touch the pulled apart arc
- d3.js pan and zoom jumps when using mouse after programatic zoom
- In d3 what does the construct .data([]).exit().remove() mean?
- D3: how to disable zoom on icons with background image?
- How can I get reliable data updates with objects in D3?
- Iterating through circle elements in d3
- How to add mouse hover properties to pie drawn on a node in d3?
- Loading Image till external json data loads for collapsible tree -d3.js
- d3.js on click zoom function not working
- 'Autofocus' attribute works once, but not twice, on input elements
- cannot use d3 to create a word cloud
- Getting Undefined property from Object created with d3.js
- Why is initial drag position incorrect when using a scale?
- D3 Treemap multiple parameter summing up the stack
- Paint the apartment and the town of different colors in d3.js
- Why does d3.select() return array of array?
- D3 Ticks on x axis wrong
- The nodes are not changed their positions as the number of ticks in X-axis changed
- Capturing mouseover events on two overlapping elements
- how to draw left and right rectangle sliders over x-axis of d3 graph chart
- D3 js line chart with tooltip on hover with multiple line chart
- AngularJS Filter causing a $digest cycle errors
- Zoomable treemap in D3 v4
- D3 draw children paths under parents
- How do we change the tick values generated by a linear scale in a d3.js line plot?
- D3 zoom in on brush extent