简体   繁体   English

D3折线图上的标签不起作用

[英]Labels on a D3 line chart not working

I want to have "tooltips" on my line chart permanently (in, other words, I want labels). 我想永久地在我的折线图上有“工具提示”(换句话说,我想要标签)。 Code I have written for this is below, but it doesn't even show any such tooltip/label on my chart. 我为此编写的代码如下,但它甚至没有在我的图表上显示任何此类工具提示/标签。 What would be the problem? 会出现什么问题?

<!DOCTYPE   html>
<style>
    body {
        font: 15px sans-serif;
    }
    .axis line, .axis path {
        fill:  none;
        stroke: gray;
        stroke-width:4;
        shape-rendering: crispEdges;
    }
    div.tooltip {   
        position: absolute;           
        text-align: center;           
        width: 60px;                  
        height: 28px;                 
        padding: 2px;             
        font: 12px sans-serif;        
        background: lightsteelblue;   
        border: 0px;      
        border-radius: 8px;           
        pointer-events: none;         
    }

    .line {
        fill: none;
        stroke: steelblue;
        stroke-width: 3px;
    }
</style>
<html>
<body>
<script type="text/javascript" src="d3.v3.min.js"></script>
<script type="text/javascript">

    var data = [
      {time:0,ftRem1:100,ftRem2:100,ftRem3:100},{time:4,ftRem1:95.7,ftRem2:89.4,ftRem3:88.9},
      {time:4.5,ftRem1:94.9,ftRem2:87.3,ftRem3:86.7},{time:8.5,ftRem1:93.8,ftRem2:84.3,ftRem3:83.2},
      {time:32.5,ftRem1:91.2,ftRem2:76.8,ftRem3:73.7},{time:56.5,ftRem1:87.8,ftRem2:67.1,ftRem3:61.7},
      {time:58.5,ftRem1:87.5,ftRem2:66.4,ftRem3:60.8},{time:82.5,ftRem1:83.7,ftRem2:55.7,ftRem3:47.6},
      {time:94.5,ftRem1:82.3,ftRem2:51.5,ftRem3:42.4}
    ];

    var margin = {top: 20,left: 30, bottom: 30,right: 40},
        height = 500 - margin.top - margin.bottom,
        width = 900 - margin.left - margin.right;

    var color = d3.scale.category10();

    var x = d3.scale.linear()
        .range([0,width]);

    var y = d3.scale.linear()
        .range([height,0]);

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

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom");

    var chart = 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+")");

    var line = d3.svg.line()
        .x(function(d){return x(d.hours);})
        .y(function(d){return y(d.ftRem);})
        .interpolate("linear");

    color.domain(d3.keys(data[0]).filter(function(d){ return d!='time' }));
    var points = color.domain().map(function(duration){
        return {
            ftPoints:duration,
            values: data.map(function(d){
            return{hours: d.time,ftRem: d[duration]};
        })
      }
    });

    x.domain([0,d3.max(data,function(d){return d.time})]);
    y.domain([
        0,
        d3.max(points,function(c){ return d3.max(c.values,function(d){ return d.ftRem;});})
    ]);
    chart.append("g")
        .attr("class","x axis")
        .attr("transform","translate(0,"+height+")")
        .call(xAxis);
    chart.append("g")
        .attr("class","y axis")
        .call(yAxis);

    var freshTime=chart.selectAll(".ftpoint")
        .data(points)
        .enter().append("g")
        .attr("class","ftpoint");

    freshTime.append("path")
        .attr("class","line")
        .attr("d",function(d,i){return line(d.values);})

    var lineColor = ["#1abc9c","#3498db","#e74c3c"];
    freshTime.select(".line")
        .style("stroke",function(d,i){return lineColor[i];})

    Step = ["","a","b","c","d","e","f","g","h"];

    var tooltip = chart.selectAll(".tooltip")
        .data(points[0].values)
       .enter()
        .append("div")
        .attr("class","tooltip")
        .style("left", function (d) { return y(d.hours)+"px";})
        .style("top", function (d) { return x(d.ftRem)+"px";})
        .text(function(d,i) { return Step[i]; });

</script>
</body>
</html>

You would be better off if you use just svg elements within your chart. 如果你在图表中只使用svg元素,那会更好。 Its just not practical to mix and match svg and divs. 混合和匹配svg和div是不切实际的。 So, you can just use svg element text for labels (you created class "tooltip" for the purpose of labels, maybe you should change the name of the class, since you actually want labels, not tooltips): 所以,你可以只使用svg元素文本作为标签(为了标签你创建了类“tooltip”,也许你应该更改类的名称,因为你实际上想要标签,而不是工具提示):

var tooltip = chart.selectAll(".tooltip")
                   .data(points[0].values)
                  .enter()
                   .append("text")
                   .attr("class","tooltip")
                   .attr("y", function (d) { return y(d.hours)+"px";})
                   .attr("x", function (d) { return x(d.ftRem)+"px";})
                   .text(function(d,i) { return Step[i]; });

(note: if you make this change, labels will appear, but I guess their positions are not Ok, but thats problem of different kind that you must solve) (注意:如果你做了这个改变,标签会出现,但我猜他们的位置不好,但那是你必须解决的不同类型的问题)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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