简体   繁体   中英

How to create tooltip in D3 to get image on MouseOver on a node in a Graph

I have a D3 application that is forming a graph which have some nodes over it which show some years of the graph , and it also shows some information when do an mouseover event on the nodes. Now I want to show images on mouseover event when we hover on the nodes of the graph. I have made some changes in tsv file but it is not effecting and the images are not coming.here is what I have done,

  <!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>

And this the tsv file I have

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

here is the tsv file here I have changed the close values to a string of image ie in last column in the place of 606.98 I will add "1.png" but it is not coming on mouseover on the graph....Someone please help

Somebody please help...

You will have to add image tag in the html on every mouseover, with a dynamically generated image path. You could dynamically generate that using the div names etc

    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");

                }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM