2013-08-20 8 views
9

Ich mache eine Visualisierung mit der D3-Javascript-Bibliothek. Ich möchte Tooltips für einige Elemente der Visualisierung erstellen und mein Kunde möchte, dass sie wie "Papierschnipsel/Post-its" aussehen. Anfangs habe ich einfache DIVs für die Tooltips erstellt, wobei ich einige nette CSS-Tricks verwendet habe, um das gewünschte Aussehen zu erzeugen. (inspiriert von this tutorial)Größenanpassung des SVG-ForeignObject-Elements an das HTML-Element

Ich möchte die Tooltips in das SVG foreignObject-Element kapseln, so dass es besser zur Visualisierung passt und ich sie leicht manipulieren kann. (z. B. Zoomen/Panning) Meine Frage ist also: Wie bekomme ich die richtige Größe des DIV, das innerhalb des foreignObject-Elements liegt, damit ich die Größe des foreignObject-Elements genau einstellen kann? Vor allem bei der Verwendung von Rand/Padding/Schatten ....

Ich fand es heraus mit .getBoundingClientRect() aber ich weiß nicht, ob dies der beste Weg ist.

Hier ist ein Code-Beispiel:

var body = d3.select("body"); 

var svg = body.append("svg"); 

var tooltipContainer = svg.append("svg:g"); 

var html = tooltipContainer.append("foreignObject") 
var div = html.append("xhtml:div") 
    .attr('class', 'paper-tooltip') 
    .html("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam.  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum  dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet,  consectetur adipiscing elit. Donec eu enim quam. "); 

var bcr = div[0][0].getBoundingClientRect(); 

html.attr('x', 50) 
    .attr('y', 50) 
    .attr('width', bcr.width) 
    .attr('height', bcr.height); 

svg.call(d3.behavior.zoom().on('zoom', redrawOnZoom)); 

function redrawOnZoom(){ 
    tooltipContainer.attr('transform', 'translate(' + d3.event.translate + ')' + ' scale(' +   d3.event.scale + ')'); 
}; 

Hier ist ein funktionierendes jsFiddle Beispiel: http://jsfiddle.net/jhe8Y/1/

EDIT:

Ich erkennen, dass für verschiedene Schatten-Box Einstellungen der .getBoundingClientRect() wird nicht funktionieren. Ich erkannte auch, dass mit meiner ersten Lösung die .getBoundingClientRect() zu groß zurückgibt, vor allem auf die richtige Größe.

Also habe ich einen anderen Weg versucht, mit der jQuerys .OuterWidth (true) /. OuterHeight (true) und die Schattengröße manuell berechnen. Das scheint gut zu funktionieren, aber es fühlt sich schrecklich an, so etwas zu tun.

Gibt es einen anderen Weg, wie man die genaue Größe eines DIV mit all seinen Komponenten bekommt?

Aktualisiert jsFiddle ist hier: http://jsfiddle.net/jhe8Y/3/

Antwort

0

ich damit vor gekämpft habe, und ich habe festgestellt, dass die einfachste Sache zu tun, verlassen nur auf Bootstrap's Tooltip.

z.

// title: this is what gets shown as the title in the tooltip 
d3.select('svg').attr('title','This is my tooltip title'); 

// content: this will show up as the content if you go for 
// popovers instead . 
d3.select('svg').attr('data-content','This is some content'); 

// set the options – read more on the Bootstrap page linked to above 
$('svg').popover({ 
    'trigger':'hover' 
    ,'container': 'body' 
    ,'placement': 'top' 
    ,'white-space': 'nowrap' 
    ,'html':'true' // preserve html formatting 
}); 

Es läuft darauf hinaus, das Hinzufügen title und data-content Attribute, was auch immer svg Element, das Sie in dem Hinzufügen interessiert sind tootltips zu. Stellen Sie dann den Inhalt gleich wie gewünscht ein. Also, in Ihrem Fall wäre die html

<div class='paper-tooltip'>Lorem ipsum dolor sit amet, ... etc etc.</div> 

Verwandte:

How do I show a bootstrap tooltip with an SVG object; Question on Stack Overflow

Bootstrap Tooltips

My super-short blog post on it

0

Sie brauchen nicht, es zu vergrößern und runter. Es gibt keinen wirklichen Nutzen davon, oder?Dann können Sie sowohl foreignObjectheight als auch width auf 1 setzen, und über CSS set foreignObject { overflow: visible; }.

Verwandte Themen