Michael Slevin
Michael Slevin

Reputation: 73

Text alignment with unknown length

I have a series of vertical boxes with labels of systems in them. Next to those I need to place a set of two numbers (transaction successes and failures). It should look something like this:

System A    (1000, 121)
System B    (323, 142)
System C    (600, 42)
System D    (1337, 66)

My issue is this: I'm having a hard time figuring out how to line up the parentheses and comma for the number. I can get the width of the "System" strings using .getComputedTextWidth(), and offsetting the transaction numbers from that is simple. The numbers can range from 1 to 5 digits (at the high end, the numbers are truncated from 199,200 to 199.2k).

How can I have the parentheses and commas move to match the lengths of the numbers? These numbers are constantly changing to I can't just hard code it. I'm using D3, so the boxes and text are all in SVG format. To make it easier, I could align all of the opening parentheses with a static offset from the system names.

Added trickiness: the transaction numbers can't just be one string- the "successes" (first number) must be in green and the "failures" (second number) must be in red. As far as I know there isn't a way to selectively color a string.

Please let me know if I am being unclear, or you need to see a picture or an example.

Thanks!

Upvotes: 1

Views: 95

Answers (1)

ckersch
ckersch

Reputation: 7687

You can use tspan elements in your text to give different words different colors and still keep them in line, rather than manually lining up a bunch of different text elements.

MDN tspan page.

Your dom would look like this:

<svg>
  <text xml:space="default" x="30" y="15">
      <tspan class="system">System</tspan>
      <tspan>A (<tspan>
      <tspan class="success">1000</tspan>
      <tspan>,<tspan>
      <tspan class="failures"> 121</tspan>
      <tspan> )<tspan>
  </text>
</svg>

This css will color the text:

.system{ fill: blue; }
.success{ fill: green; }
.failures{ fill: red; }

You can append the tspans to the text one at a time in d3, like so:

var myText = d3.select('svg').append('text')
  .attr("x", 90)
  .attr("y", -257)

myText.append('tspan')
    .text('System')
    .classed('system', true);

myText.append('tspan')
    .text('A (');

//etc.

Upvotes: 2

Related Questions