[英]How to add a tooltip at the end of the line chart in D3
我有一條LOESS線,我想添加一個工具提示以對其進行標記。
我試圖獲取線的最后一點的坐標,但是我得到了一個字符串並且無法獲取最后一點
loessRegression_e = d3.regressionLoess()
.x(d => d.fecha_de_libertad)
.y(d => d.EXTERNADO)
.bandwidth(0.20);
var valueline = d3.line()
.x(function(d) { return x(d[0]); })
.y(function(d) { return y(d[1]); })
.curve(d3.curveCatmullRom);
console.log(valueline(loessRegression_e(data))) // Here is where I tried to get the coordinates of the line, but it is a string, and a pain to slice it
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("display", "none");
div
.text(d3.event.pageX + ", " + d3.event.pageY)
.style("left", (d3.event.pageX - 34) + "px")
.style("top", (d3.event.pageY - 12) + "px");
svg.append("path")
.data([loessRegression_e(data)])
.attr("class", "line_e")
.attr("d", valueline);
// Add the x-axis.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickFormat(d3.timeFormat("%Y-%m-%d")));
// Add the y-axis.
svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(y));
// Add the points!
svg.selectAll(".point")
.data(data)
.enter().append("path")
.attr("class", "point")
.attr("d", d3.symbol().type(d3.symbolSquare))
.attr("transform", function(d) { return "translate(" + x(d.fecha_de_libertad) + "," + y(d.COMPURGADO) + ")"; });
您可以綁定添加一個mouseover事件以顯示要懸停的數據點。 例如:
svg.append("path")
.data([loessRegression_e(data)])
.attr("class", "line_e")
.attr("d", valueline)
.on( 'mouseover', function( d ) {
$( '.tooltip' ).text( "(" + d.x + "," + d.y ")" );
$( '.tooltip' ).show();
})
.on( 'mouseout', function( d ) {
$('.tooltip').hide();
});
假設您使用的是jquery,但如果沒有,則可以輕松進行修改。
編輯:對不起,我忽略了一些事情。 您不能在不使用異物的情況下將div直接添加到svg中,也不能將文本追加到圓上。 因此,您可以將div添加到html中,並使用d3將div與綁定的數據一起放置。 我已經附加了一個(草率的)最小工作示例,您可以在繪制線並根據最后一個元素顯示標簽時作為參考。 免責聲明:我敢肯定有一個更優雅的解決方案。
<!DOCTYPE html>
<html>
<head>
<style>
.tool-tip {
background-color: blue;
height: 50px;
width: 50px;
z-index: 10;
position: absolute;
visibility: hidden;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
#svg-container {
position: relative;
}
</style>
</head>
<body>
<div id="svg-container" >
<div class='tool-tip'>WTF</div>
</div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.1/d3.js"></script>
</body>
<script>
let data = [{'x': 0, 'y': 0}, {'x':1, 'y': 1}, {'x': 2, 'y': 2}, {'x': 3, 'y': 3}]; //made up data
let width = 500;
let height = 500;
let svg = d3.select( "#svg-container" ).append( "svg" ).attr( 'height', height ).attr( 'width', width ).attr( 'id', 'my-svg' )
let xscale = d3.scaleLinear()
.domain( [0, 4])
.range( [ 0, width] )
let yscale = d3.scaleLinear()
.domain( [0, 4] )
.range( [ height, 0] )
let myline = d3.line()
.x(d => xscale(d.x))
.y(d => yscale(d.y))
svg.append("path")
.data( [data] )
.attr("class", "line")
.attr("d", myline);
let point = svg.selectAll( 'circle' )
.data( data )
.enter()
.append( 'circle' )
.attr( 'r', 5 )
.attr( 'cx', function(d) { return xscale( d.x ); })
.attr( 'cy', function(d) { return yscale( d.y ); })
.attr( 'fill', 'red' )
.attr( 'class', 'my-circle' )
//You start here
//grab the last data point that you want to add a label to
let label = svg.select( '.my-circle:last-of-type')
//use fill method as a hook to bind the data to the label
.attr( 'fill', function( d ) {
//get the position to place the label from your data point
let x = parseFloat($( this ).attr( 'cx' ));
let y = parseFloat($( this ).attr( 'cy' ));
//get the raw data point to display
let x_invert = xscale.invert( x );
let y_invert = yscale.invert( y );
//use jquery to set the x and position using offset of 15 - may need to add your
// svg x and y starting points if somewhere offset from the page
$( '.tool-tip' ).text( "(" + d.x + "," + d.y + ")");
$( '.tool-tip' ).css( 'left', (x + 15) + 'px' );
$( '.tool-tip' ).css( 'top', (y + 15) + 'px');
$( '.tool-tip' ).css( 'visibility', 'visible');
//return the fill as we only called this to display the label.
return $( this ).attr( 'fill' );
})
</script>
</html>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.