question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

SVG Axis Label Text Wrap

See original GitHub issue

Hi, thanks for this sweet project! I know SVG <text> elements don’t quite wrap yet, and I was wondering if I’ve missed a way to get axis label text to wrap that currently exists in this project? I’ve come across https://github.com/d3plus/d3plus-text, but I’m unsure of ways to interop between nivo & d3. There is also the hacky <tspan> element which could be deployed at some level, but that feels like I’m barking up the wrong tree.

Has this problem already been solved? If not, is it planned on being solved, or is help required?

image

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:37 (10 by maintainers)

github_iconTop GitHub Comments

21reactions
ByronBeckercommented, Jan 21, 2019

In case this is helpful to anyone, I wrote a somewhat flexible getTspanGroups function that can be inserted to the same place in rpearce’s code.

Just a heads up - this was written in Typescript

const getTspanGroups = (value: string, maxLineLength: number, maxLines: number = 2) => {
        const words = value.split(' ')
        
        type linesAcc = {
            lines: string[],
            currLine: string
        }

        //reduces the words into lines of maxLineLength
        const assembleLines: linesAcc = words.reduce( (acc: linesAcc, word: string) => {
            //if the current line isn't empty and the word + current line is larger than the allowed line size, create a new line and update current line
            if ( (word + acc.currLine).length > maxLineLength && acc.currLine !== '') {
                return {
                    lines: acc.lines.concat([acc.currLine]),
                    currLine: word
                }
            }
            //otherwise add the word to the current line
            return {
                ...acc,
                currLine: acc.currLine + ' ' + word 
            } 
            
        }, {lines: [], currLine: ''})

        //add the ending state of current line (the last line) to lines
        const allLines = assembleLines.lines.concat([assembleLines.currLine])

        //for now, only take first 2 lines due to tick spacing and possible overflow
        const lines = allLines.slice(0, maxLines)
        let children: JSX.Element[] = []
        let dy = 0

        lines.forEach( (lineText, i) => {
            children.push(
                <tspan x={0} dy={dy} key={i}>
                    {
                        // if on the second line, and that line's length is within 3 of the max length, add ellipsis
                        (1 === i && allLines.length > 2) ? lineText.slice(0, maxLineLength - 3) + '...' : lineText
                    }
                </tspan> 
            )
            //increment dy to render next line text below
            dy += 15
        });

        return children
    }
9reactions
rpearcecommented, Nov 25, 2018

Update: here’s what I’m currently going with…

axisBottom={{
  tickSize: 0,
  tickPadding: 25,
  tickRotation: 0,
  renderTick: ({
    opacity,
    textAnchor,
    textBaseline,
    textX,
    textY,
    theme,
    value,
    x,
    y
  }) => {
    return (
      <g
        transform={`translate(${x},${y})`}
        style={{ opacity }}
      >
        <text
          alignmentBaseline={textBaseline}
          style={theme.axis.ticks.text}
          textAnchor={textAnchor}
          transform={`translate(${textX},${textY})`}
        >
          {getTspanGroups(value)}
        </text>
      </g>
    )
  }
}}

where getTspanGroups is an Array of <tspan> elements that are no longer than 15 characters (not dynamic … but passable).

Best I can do for now!

Read more comments on GitHub >

github_iconTop Results From Across the Web

SVG Wrapping text on x-axis - Stack Overflow
I am trying to wrap some text on a bar graph i am creating using D3. ... How to align them right.? Here's...
Read more >
Text wrapping in Vega JS Charts (SVG and Canvas) - Gramener
To rotate x-axis labels, labelAngle property is used in the code snippet. The labels no more overlap with neighboring labels but are overlapping...
Read more >
Text Wrap Axis / Alan Mar - Observable
Text Wrap Axis. Taken from Mike Bostock's example on how to wrap really long tick texts. Included an example on how to wrap...
Read more >
Wrapping, truncating, and auto-rotating axis labels - amCharts
By default, labels are truncated with a triple-dot for an ellipsis. You can use label's ellipsis property to set it to any other...
Read more >
Wrapping Long Labels 2.0 - Popular Blocks
forked from mbostock's block: Wrapping Long Labels 2.0 ... .1, .3); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found