Pergunta

I'm happily using tipsy for my d3.js graphs, but now I noticed that tipsy is cutting off text if it's too long.

For instance the line containing the word CALCULATOR is cut off:

Text of tooltip is cut off

Is there a way to extend the width of the tooltip or autosize it according to the longest line of the tooltip text (I didn't find anything in the docs)?

Foi útil?

Solução

I ended up writing my own tooltips module for D3 (see below). It uses require.js. I use it like this:

define('myD3module',
// This module depends on the following modules
['tooltips', 'd3'], 
    function (tooltips, d3){

// Code omitted...

var node = svg.selectAll('g.node');
var nodeEnter = node.enter().append('g')
.on('mouseover', onMouseOver)                  
.on('mouseout', onMouseOut);

// Code omitted...

var onMouseOver = function(d){
       tooltips.showTooltip(d, getTooltipText);
};

var onMouseOut = function(d){
        tooltips.hideTooltip(d);
};

// Code omitted...
var getTooltipText = function(d){
    var tipText = '';
    var name = d.name;
    if(typeof name != 'undefined'){
        tipText += 'Name = ' + name + '<br>';
    }
    return tipText;
};

This is the module.

// This module shows tooltips near the user's cursor. The text of the tooltip must be provided by the consumer of this module. This module can be used with require.js.
define('tooltips',
// Required modules:
['d3','jquery'],
function (d3, $){

    // Contains the tooltip. This div will be repositioned as needed.
    var tooltip = d3.select('body').append('div')   
                    .attr('class', 'tooltip')               
                    .style('opacity', 0);

    // This CSS styles the tooltip
    var css = './config/tooltip.css';
    var link = document.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    link.href = css;
    document.getElementsByTagName('head')[0].appendChild(link);

    var hideTooltip = function (d) {       
            tooltip.style('opacity', 0);   
        },

        /** Show the tooltip. The text is defined by a function and the element the mouse cursor is placed on. */
        showTooltip = function (elem, getTooltipText){      
            tooltip.style('opacity', 0.9);      
            var text = getTooltipText(elem);
            var tipWidth = getTooltipWidth(text);
            // Draw the tips below the mouse cursor
            var tipYpos = d3.event.pageY + 20;
            tooltip.html(text)  
                // The tooltip is centered below the cursor
                .style('left', (d3.event.pageX - tipWidth/2) + 'px')     
                .style('top', tipYpos + 'px')
                .style('width', tipWidth + 'px')
                .style('height', getTooltipHeight(text) + 'px');
        },

        /**
         * The tooltip spans all the text's lines vertically.
         */
         getTooltipHeight = function (text) {

            var totalHeight = 0;
            var lines = text.split('<br>');
            for (var i = 0; i < lines.length; i++){
                var line = $.trim(lines[i]);
                // Ignore empty strings
                if(line.length > 0){
                    var span = document.createElement('span');
                    span.innerHTML = line;
                    $('body').append(span);
                    totalHeight +=  $(span).height();
                    $(span).remove();
                }
            }
            return totalHeight;
        },

        /*
         * The width of the tooltip is the width of the longest line in the tooltip text
         */
        getTooltipWidth = function (text){

            var lines = text.split('<br>');
            // Append a dummy span containing the current line to the DOM. The browser calculates the width of that span
            var maxWidth = d3.max(lines, function(line) {
                    var span = document.createElement('span');
                    span.innerHTML = line;
                    $('body').append(span);
                    var spanWidth = $(span).width();
                    $(span).remove();
                    return spanWidth; 
                    });
            return maxWidth;
        };

        // These functions are public
        return {
            showTooltip: showTooltip,
            hideTooltip: hideTooltip
        };
    }
);

This is the tooltip.css:

.tooltip {   
    position: absolute;           
    text-align: center;           
    font: 12px sans-serif;        
    background-color: rgb(95,230,245);   
    border-radius: 2px;           
    pointer-events: none;         
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top