d3多线图工具提示值数据未定义

时间:2016-06-29 01:07:17

标签: javascript d3.js tooltip

我的部分工具提示文字存在此多线图的问题。它正确地找到了名称,但是当我尝试访问该行的y值时,它将以未定义的形式返回。

数据结构在控制台中如下所示:

screenshot of console

我需要来自"逮捕的价值:"片段显示在工具提示中。现在它说未定义。

这是我的代码。工具提示位在最后。

        <div id="graph">
            <div id="tooltip" class="hidden">
                <p id="value">value</p>
            </div>
     </div>
           <script type="text/javascript">
                  var w = 700
                      h = 500

        var margin = {top: 20, right: 140, bottom: 130, left: 100},
            width = w - margin.left - margin.right,
            height = h - margin.top - margin.bottom;

        var parseDate = d3.time.format("%Y").parse;

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

        var color = d3.scale.ordinal()
            .range([ "#43736C", "#29403C", "#f4b400", '#000'])
            //"#29403C", "#463573", "#f4b400", "#43736C", "#43736C", "#f4b400"        ]);

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

        var line = d3.svg.line()
            .x(function(d) {return x(d.year); })
            .y(function(d) {return y(d.arrests); });

        var svg = d3.select("#graph").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 + ")");

        d3.csv("https://spreadsheets.google.com/tq?key=1DNo1v8lYRzzZA6kPdQ77HrREhzkW1nDwktNQm2MXSio&tqx=out:csv", function(error, data) {
            if (error) throw error;

            color.domain(d3.keys(data[0]).filter(function(key) {return key !== "year"; }));

            data.forEach(function(d) {
                d.year = parseDate(d.year);
                });

            var populations = color.domain().map(function(name) {
                return {
                    name: name,
                    values: data.map(function(d) {
                        return {year: d.year, arrests: +d[name]};
                        })
                    };
                });

            var populations = populations.filter(function(d){
                return d.name!== "";
                });

            console.log(populations);

            x.domain(d3.extent(data, function(d) {return d.year; }));

            y.domain([0, 15000]);

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

            svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                    .attr("class", "yLabel")
                    .attr("transform", "rotate(-90)")
                    .attr("y", 0)
                    .attr("dy", "-6em")
                    .style("text-anchor", "end")
                    .text("Number of arrests");

            var pop = svg.selectAll(".pop")
                .data(populations)
                .enter().append("g")
                .attr("class", "pop");

            pop.append("path")
                .attr("class", "line")
                .attr("d", function(d) { return line(d.values); })
                .style("stroke", function(d) {return color(d.name); });

            var legend = svg.selectAll(".legend")
                .data(populations.slice())
                .enter().append("g")
                    .attr("class", "legend")
                    .attr("transform", function(d, i) {return "translate(0,"+ i * 20 + ")"});


            legend.append("rect")
                .data(populations)
                .attr("x", width)
                .attr("width", 18)
                .attr("height", 18)
                .style("fill", function(d) {return color(d.name);});

            legend.append("text")
                .attr("x", w - 220)
                .attr("y", 9)
                .attr("dy", ".35em")
                .style("text-align", "left")
                .text(function(d) {return d.name});


            svg.selectAll("path")
                .on("mouseover", function(d) {
                    var xPosition = d3.event.pageX;
                    var yPosition = d3.event.pageY;
                    console.log(d.values);
                    d3.select("#tooltip")
                        .style("left", xPosition + "px")
                        .style("top", yPosition + "px") 
                        .select("#value")
                        .text(d.name + " " + d.values.arrests);

                    d3.select("#tooltip").classed("hidden", false);             
                        })
                .on("mouseout", function(){
                    d3.select("#tooltip").classed("hidden", true);
                    });



            });

1 个答案:

答案 0 :(得分:1)

看起来您的问题是您的鼠标悬停行为是在路径上。该路径的数据是整个系列,即使你正在考虑它,就好像你只是在一年的时间里。所以d的价值不是你所期望的。 d.values是该系列每年的整个数据集(例如Misdemeanor)。

相反,你应该为每个地方与每个系列的线相交的每个地方添加不可见的点标记,并将工具提示行为放在那些 - 这个SO问题的答案 - d3.js tooltips on path - 可能会有所帮助。