简体   繁体   中英

How to align d3js tooltip in center of time divisions?

I'm creating a tooltip that shows the y-value as you mouse over the graph region. However, I notice that the jump in value occurs on the x0 value tick, rather than the middle, between the x0 and x1 value ticks. If you look at the image below, you can see the red line represents the x-position of the cursor and how the y-value is incorrectly placed for x0+1px to (x1+x0)/2 [where x0 is the 15th and x1 is the 16th].

工具提示对齐屏幕截图

Here is my code, which is borrowing heavily from this example .

AC.bisectDate = d3.bisector(function(d) { return d.date; }).left;

function mousemoveall(){;
    var x0 = AC.charts[0].x.invert(d3.mouse(this)[0]);
    AC.charts.forEach(function(thisChart){
        mousemove(thisChart,x0);
    });

}

function mousemove(thisChart,x0){

    var i = AC.bisectDate(thisChart.chartData, x0, 1),
        d0 = thisChart.chartData[i - 1],
        d1 = thisChart.chartData[i],
        d = x0 - d0.date > d1.date - x0 ? d1 : d0;
    var mydata = thisChart.chartData[i][AC.props[thisChart.id]];

    thisChart.focus.attr("transform","translate(" 
        + (thisChart.x(d.date) + thisChart.margin.left) + "," 
        + (thisChart.margin.top + (thisChart.height * thisChart.id) + (10 * thisChart.id) 
        + thisChart.y(mydata) ) + ")");
    thisChart.focus.select("text").text(mydata);    

}   

How would I go about having the y-value jump take place exactly between the 15th and the 16th, rather than at the 15th?

There is a possibility that you have not correctly returned the mouse position by omitting a line in your mousemove function.

If you re-check Mikes example you will see a line var x0 = x.invert(d3.mouse(this)[0]), which returns the x position on the screen of the mouse ( d3.mouse(this)[1] would return the y position). The x.invert function reverses the process that is used to map the domain (date) to range (position on screen). So it takes the position on the screen and converts it into an equivalent date!

It is possible that you have included this somewhere else in your code, but I would check this first.

If you want another example to check out try this which explains an almost identical example.

I discovered that the reason I was experiencing these jumps was that I needed to decrement the index whenever the mouse passed over the interface between the two x-values (in this case, two dates). Creating this i2 variable that adjusts for the transition fixed my tracking problem. The modified mousemove function is below:

function mousemove(thisChart,x0){
    var i = AC.bisectDate(thisChart.chartData, x0, 1),
        i2 = i,
        d0 = thisChart.chartData[i - 1],
        d1 = thisChart.chartData[i],
        d = x0 - d0.date > d1.date - x0 ? d1 : d0;

    if (x0 - d0.date <= d1.date - x0) {i2 = i-1;}

    var mydata = thisChart.chartData[i2][AC.props[thisChart.id]],
        yPos = thisChart.y(mydata)+10+thisChart.margin.top,
        xPos = +thisChart.x(d.date) + +thisChart.margin.left;
    thisChart.focus.attr("transform","translate(" + xPos + "," + yPos + ")");
    thisChart.focus.select("text").text(mydata);    
}   

I'm not sure why I couldn't find this sort of if statement in other examples' code, while their tooltip alignment seemed fine. Maybe I have something strange in my code, or maybe their datasets are so densely packed you don't notice the awkward jump?

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