如何在D3中创建工具提示以在Graph中的节点上获取MouseOver上的图像

时间:2013-11-03 17:56:33

标签: javascript d3.js tooltip

我有一个D3应用程序正在形成一个图形,其中有一些节点显示图表的某些年份,并且它还显示了在节点上执行鼠标悬停事件时的一些信息。现在,当我们将鼠标悬停在图形的节点上时,我想在鼠标悬停事件上显示图像。我在tsv文件中做了一些更改,但它没有效果,图像也没有出现。我做了什么,

  <!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */

body { font: 12px Arial;}

path { 
    stroke: green;
    stroke-width: 2;
    fill: none;
}

.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}

div.tooltip {                   /* set the CSS for tooltip divs */
    position: absolute;         /* reference for measurement */
    text-align: center;         /* align the text to the center */
    width: 60px;                    /* set the width of the rectangle */
    height: 28px;                   /* set the height of the   rectangle */
    padding: 2px;                   /* set a border around the rectangle */
    font: 12px sans-serif;      /* set the font type for the tooltips */
    background: lightsteelblue; /* set the colour of the rectangle */
    border: 0px;                    /* turn off the border (0px) */
    border-radius: 8px;         /* set how rounded the edges of the rectangle is */
    pointer-events: none;           /* 'none' tells the mouse to ignore the rectangle */
}

</style>
<body>

<!-- load the d3.js library --> 
<script type="text/javascript" src="d3/d3.v3.min.js"></script>

<script>

    // Set the dimensions of the canvas / graph
    var margin = {top: 30, right: 20, bottom: 30, left: 50},
    width = 600 - margin.left - margin.right,
    height = 270 - margin.top - margin.bottom;

    // Parse the date / time
    var parseDate = d3.time.format("%d-%b-%y").parse;
    var formatTime = d3.time.format("%e %B");           // Format the date / time for tooltips


    // Set the ranges
    var x = d3.time.scale().range([0, width]);
    var y = d3.scale.linear().range([height, 0]);

    // Define the axes
    var xAxis = d3.svg.axis().scale(x)
    .orient("bottom").ticks(5);

    var yAxis = d3.svg.axis().scale(y)
    .orient("left").ticks(5);

    // Define the line
    var valueline = d3.svg.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.close); });

    // Define 'div' for tooltips
    var div = d3.select("body").append("div")   // declare the properties for the div used for the tooltips
    .attr("class", "tooltip")               // apply the 'tooltip' class
    .style("opacity", 0);                   // set the opacity to nil

    // Adds the svg canvas
    var svg = d3.select("body")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // Get the data from external file
    d3.tsv("data/data.tsv", function(error, data) {
        data.forEach(function(d) {
            d.date = parseDate(d.date);
            d.close = +d.close;
        });

        // Scale the range of the data
        x.domain(d3.extent(data, function(d) { return d.date; }));
        y.domain([0, d3.max(data, function(d) { return d.close; })]);

        // Add the valueline path.
        svg.append("path")      
        .attr("class", "line")
        .attr("d", valueline(data));

        // draw the scatterplot
        svg.selectAll("dot")                                    
        .data(data)                                         
        .enter().append("circle")                               
        .attr("r", 5)                                           // Made slightly larger to make recognition easier  
        .attr("cx", function(d) { return x(d.date); })       
        .attr("cy", function(d) { return y(d.close); })         // remove semicolon 
        // Tooltip stuff after this
        .on("mouseover", function(d) {                          // when the mouse goes over a circle, do the following
            div.transition()                                    // declare the transition properties to bring fade-in div
            .duration(200)                                  // it shall take 200ms
            .style("opacity", .9);                          // and go all the way to an opacity of .9
            div .html(formatTime(d.date) + "<br/>"  + d.close)  // add the text of the tooltip as html 
            .style("left", (d3.event.pageX) + "px")         // move it in the x direction 
            .style("top", (d3.event.pageY - 28) + "px");    // move it in the y direction
        })                                                  // 
        .on("mouseout", function(d) {                           // when the mouse leaves a circle, do the following
            div.transition()                                    // declare the transition properties to fade-out the div
            .duration(500)                                  // it shall take 500ms
            .style("opacity", 0);                           // and go all the way to an opacity of nil
        });                                                     // finis

        // Add the X Axis
        svg.append("g") 
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

        // Add the Y Axis
        svg.append("g") 
        .attr("class", "y axis")
        .call(yAxis);

    });

</script>
  </body>

这是我拥有的tsv文件

date    close
1-May-12    58.13
30-Apr-12   53.98
27-Apr-12   67.00
26-Apr-12   89.70
25-Apr-12   99.00
24-Apr-12   130.28
23-Apr-12   166.70
20-Apr-12   234.98
19-Apr-12   345.44
18-Apr-12   443.34
17-Apr-12   543.70
16-Apr-12   580.13
13-Apr-12   605.23
12-Apr-12   622.77
11-Apr-12   626.20
10-Apr-12   628.44
9-Apr-12    636.23
5-Apr-12    633.68
4-Apr-12    624.31
3-Apr-12    629.32
2-Apr-12    618.63
30-Mar-12   599.55
29-Mar-12   609.86
28-Mar-12   617.62
27-Mar-12   614.48
26-Mar-12   606.98

这里是tsv文件,我已将关闭值更改为一个图像字符串,即在606.98的最后一列中我将添加“1.png”,但它不会在图形上进行鼠标悬停... 。有人请帮忙

有人请帮忙......

1 个答案:

答案 0 :(得分:1)

您必须在每次鼠标悬停时在html中添加图像标记,并使用动态生成的图像路径。您可以使用div名称等动态生成

    string yourImagePath = ""; // you will have to set the image path here
    svg.selectAll("text")
             .data(dataset)
             .enter() //here you would add all the other d3 functions that make it sensible
    .on("mouseover", function(d) {  // the mouseover event    
                div.transition()        
                    .duration(200)      
                    .style("opacity", .85); 
                var string = "<img src= + " yourImagePath " + />";
                div .html(string) //this will add the image on mouseover
                    .style("left", (d3.event.pageX + 10) + "px")     
                    .style("top", (d3.event.pageY + 50) + "px")
                    .style("font-color", "white");

                }