我正在使用 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"
});
}