1

我正在使用 d3.js 制作树形图,我需要帮助编写一些 JS 代码来更改悬停行为,使其不会溢出到包含 div#graphic-treemap 之外。

简化 HTML 结构,如下所示:

<div id="graphics">
    <div class="treemap">
        <div id="graphic-treemap">
            <div class="node">
                <a href="#">
                    <span class="name">Name</span>
                    <strong class="value">R$ 3 Bi</strong>
                    <span class="more-info">
                        <span class="name-inside">Name</span>
                        <span class="year-and-amount">R$ 3 Bi</span>
                        <span class="percent">15% valor total do orçamento</span>
                    </span>
                </a>
            </div>
        </div>
    </div>
</div>

这是 CSS 的一部分,用于澄清悬停的事情:

#graphics .treemap .node a .more-info {
    display: none;
    position: absolute;
    top: 20%;
    left: 15%;
    background-color: #FFF;
    padding: 10px 20px;
    text-align: center;
    box-shadow: 1px 1px 2px #444;
    z-index: 10;
}
#graphics .treemap .node a:hover .more-info {
    display: block;
}

树形图的最终输出如下所示:http: //jsfiddle.net/tatianeps/GYsEa/

当鼠标悬停在某个 div.node 上时,请参见右下角,该节点内的 span.more-info 内没有文本会溢出 div#graphic-treemap。

在生成树形图的 JS 和我一直在处理但没有成功的一些代码下方。

adjustHoverPosition我在代码末尾尝试了函数。也有node.on('mouseover',function(d){ });,但删除了其中的代码,因为它也不起作用。

任何帮助将不胜感激。

var graphics =
{
    debug: true,

    init: function() {
        graphics.load();
    },

    load: function() {
        if ( typeof graphics_at_page != 'undefined' ) {
            if ( typeof graphics_at_page[ 'map' ] != 'undefined' ) {
                graphics.map.init( graphics_at_page[ 'map' ], 0 );
            }

            if ( typeof graphics_at_page[ 'treemap' ] != 'undefined' ) {
                graphics.treemap.init( graphics_at_page[ 'treemap' ] );
            }

            if ( typeof graphics_at_page[ 'bar' ] != 'undefined' ) {
                graphics.bar.init( graphics_at_page[ 'bar' ], 0 );
            }
        }
    },

    load_script: function( url, callback )
    {
        $.getScript( url, callback );
    },

    load_json: function( url, callback )
    {
        $.get(
            url,
            'json',
            function(data) {
                callback( data );
            }
        );
    },

    log: function( object ) {
        if ( graphics.debug ) console.log( object );
    },

    treemap:
    {
        url:        [],
        data:       [],
        started:    false,
        title:      'title',

        init: function( url ) {
            graphics.treemap.url = url;
            graphics.treemap.load();
        },

        load: function() {
            if ( typeof d3 != 'undefined' ) {
                graphics.treemap.create();
            } else {
                if ( typeof d3 === 'undefined' ) {
                    graphics.load_script( 'js/d3.min.js', graphics.treemap.create );
                }
            }
        },

        create: function() {
            if ( typeof d3 === 'undefined' || graphics.treemap.started ) {
                return false;
            } else {
                graphics.treemap.started = true;
            }

            $( '#graphics .treemap' ).prepend( '<div id="graphic-treemap"></div>' );

            addLoader($('#graphics .treemap'));

            graphics.treemap.graphic    = d3.layout.treemap().size([665, 445]).sort(function(a,b) { return a.size - b.size; }).sticky(true).value( function( d ){ return d.size; });
            graphics.treemap.div        = d3.select( '#graphics .treemap #graphic-treemap' );

            d3.json (
            graphics.treemap.url[ 0 ],
            function( error, root ) {
                var node = graphics.treemap.div.datum( root ).selectAll( '.node' )
                    .data( graphics.treemap.graphic.nodes )
                    .enter().append( 'div' )
                    .attr( 'class', 'node' )
                    .call( graphics.treemap.position )
                    .style( 'background', function( d ) { return d.color; } )
                    .html( function( d ) {
                        return '<a href="' + d.link + '"><span class="name">' + d.name + '</span>' + 
                                    '<strong class="value" style="' + ( graphics.treemap.adjustFontSize(d.size) ) + '">' + d.amount + '</strong>' +
                                    '<span class="more-info" style="border:8px solid '+ d.color +';">' +
                                        '<span class="name-inside" style="color:'+ d.color +';">' + d.name + '</span>' + 
                                        '<span class="year-and-amount">' + d.totalAmount + '</span>' + 
                                        '<span class="percent">' + d.percent + ' valor total do orçamento' + '</span>' + 
                                    '</span>' +
                                '</a>';
                    })
                    .call( graphics.treemap.adjustTreemapText )
                    .call( graphics.treemap.adjustHoverPosition );

                /*node.on('mouseover',function(d){
                });*/

                removeLoader($('#graphics .treemap'));
            });
        },

        position: function() {
            this.style( 'left', function(d) { return d.x + "px"; })
                .style( 'top', function(d) { return d.y + "px"; })
                .style( 'width', function(d) { return d.dx + "px"; })
                .style( 'height', function(d) { return d.dy + "px"; });
        },

        adjustFontSize: function(size){
            if(size < 1){ return ' display:none;'; }
            else if(size>=1 && size <=12){ return ' font-size:24px;'; }
            else if(size> 12 && size <=50) { return ' font-size:'+ size*2 +'px;'; }
            else if(size> 50 && size <=100) { return ' font-size:'+ size*1.5 +'px;'; }
            else return ' font-size:150px;';
        },

        adjustTreemapText: function(){
            $('.treemap .node').each(function(){
                if($(this).width() == 0) { $(this).attr('style','display:none;');    }
            });
            $('.treemap .node a .name, .treemap .node a .value').each(function(){
                var thisHeight = $(this).height()+20;
                var thisParentHeight = $(this).parents('a').innerHeight();
                if(thisHeight >= thisParentHeight){ $(this).attr('style','display:none;'); }
            });
            $('.treemap .node a .name').each(function(){
                var text = $(this).text();
                $(this).append('<em class="temporary" style="display:inline;">'+text+'<em/>');

                var thisHeight = $(this).height()+30;
                var thisParentHeight = $(this).parents('a').innerHeight();
                if(thisHeight >= thisParentHeight){
                    var temporaryWidth = $(this).find('.temporary').width()+10;
                    var thisParentWidth = $(this).parents('a').innerWidth();
                    if(temporaryWidth >= thisParentWidth){ $(this).attr('style','display:none;'); }
                }

                $(this).find('.temporary').remove();
            });
        },

        adjustHoverPosition: function(){
            $('.treemap .node').each(function(index){
                if(index > 0){
                    var leftStr = $(this).css('left');
                    var left = parseInt(leftStr.replace('px',''));

                    var topStr = $(this).css('top');
                    var top = parseInt(topStr.replace('px',''));

                    if(left > 332) { $(this).find('.more-info').css('left','').css({right:'15%'}); }
                    if(top > 222) { $(this).find('.more-info').css('top','').css({bottom:'20%'}); }
                }
            });
        }
    }
};

function addLoader(loaderContainer) {
    loaderContainer.prepend('<div class="loader"><span class="loading"></span></div>');
}

function removeLoader(loaderContainer) {
    loaderContainer.find('.loader').remove();
}

$(document).ready(
    function() {
        graphics.init();
    }
);

编辑:我正在尝试使用 jQuery UI .position(),但它似乎不起作用。

adjustHoverPosition: function(){
    $('.treemap .node a span.more-info').position({
        collision: "flip",
        within: "#graphic-treemap"
    });
}
4

0 回答 0