文本与对象D3一起移动

时间:2014-04-10 10:44:17

标签: d3.js

我有一个与此http://bost.ocks.org/mike/nations/类似的代码。现在我想要两件事:

  1. 使用国家/地区名称命名每个点,名称应显示在Dots
  2. 下方
  3. 当气泡移动时,应在其后面形成线条形状的痕迹,这样用户就可以轻松比较每年的值。
  4. 有人可以帮助我实现这一目标。

    d3.json(
                    "datasetold.json",
                    function(heuristics) {
    
    
    /*var minY = d3.min(heuristics, function(d) { return d.RevenueInflationAdjusted[1]}),
        maxY = d3.max(heuristics, function(d) { return d.RevenueInflationAdjusted[1]});
    
    alert("Y   "+minY+"    "+maxY);
    var minX = d3.min(heuristics, function(d) { return d.NetIncome2008[1]}),
        maxX = d3.max(heuristics, function(d) { return d.NetIncome2008[1]
        });
    
        alert("X   "+minX+"    "+maxX);
    */
    var formatValue = d3.format(".2r");
    
    // Various accessors that specify the four dimensions of data to visualize.
    function x(d) {
        return d.NetIncome2008;
    }
    
    function y(d) {
        return d.RevenueInflationAdjusted;
    }
    //function y(d) {return d.Revenue2008;}
    function radius(d) {
        return d.RevenueInflationAdjusted;
    }
    function color(d) {
        return d.CompanyName;
    }
    function key(d) {
    
        //alert(d.Company);
        return d.Company;
    }
    
    var currentX, currentY, currentR, prevR, svg;
    var map = new Object();
    
    // Chart dimensions.
    var margin = {
        top : 100,
        right : 19.5,
        bottom : 19.5,
        left : 120.5
    }, width = 960 - margin.right, height = 500 - margin.top - margin.bottom;
    
    // Various scales. These domains make assumptions of data, naturally.
    var xScale = d3.scale.log().domain([ 10, 950 ]).range([ 0, width ]), 
        yScale = d3.scale.linear().domain([ 0, 800 ]).range([ height, 0 ]), //100, 3600
        radiusScale = d3.scale.sqrt().domain([ 0, 800 ]).range([ 0, 40 ]), colorScale = d3.scale.category10(), 
        prevRadiusScale = d3.scale.sqrt().domain([ 0, 800 ]).range([ 0, 40 ]), colorScale = d3.scale.category10();
    
    // The x & y axes.
    var xAxis = d3.svg.axis().orient("bottom").scale(xScale).ticks(15,d3.format(",d")), 
        yAxis = d3.svg.axis().scale(yScale).orient("left");
    
    // Create the SVG container and set the origin.
    svg = d3.select("#chart").append("svg").attr("width",
            width + margin.left + margin.right).attr("height",
            height + margin.top + margin.bottom + 450).append("g").attr(
            "transform", "translate(" + margin.left + "," + margin.top + ")");
    
    // Add the x-axis.
    svg.append("g").attr("class", "x axis").attr("transform",
            "translate(0," + height + ")").call(d3.svg.axis().scale(d3.scale.linear()).ticks(0))
                .transition().duration(4000)
                .call(xAxis);
    
    // Add the y-axis.
    svg.append("g").attr("class", "y axis").call(d3.svg.axis().scale(d3.scale.linear()).ticks(0))
                .transition().duration(4000)
                .call(yAxis);
    
    var line = svg.append("line")
                    .transition()
                    .delay(16000)
                    .duration(2000)
                    .attr("x1", 0)
                    .attr("y1", yScale(50))
                    .attr("x2", 940.5)
                    .attr("y2", yScale(50))
                    .style("stroke", "blue")
                    .attr("stroke-width", "1");
    
    
    // Add an x-axis label.
    svg.append("text")
    .transition()
    .delay(2000)
    .attr("class", "x label")
    .attr("text-anchor", "end")
    .attr("x", width)
    .attr("y", height+40)
    .style("font-size","12px")
    .style("fill","black")
    .style("stroke","black")
    .style("stroke-width","0")
    .text("NetIncome2008")
    .transition()
    .delay(4000)
    .duration(3000)
    .attr("x",width-350)
    .attr("y", height-200)
    .style("font-size","40px")
    .style("fill","white")
    .style("stroke","black")
    .style("stroke-width","1")
    .transition()
    .delay(7000)
    .duration(4000)
    .attr("x", width)
    .attr("y", height+40)
    .style("font-size","12px")
    .style("fill","black")
    .style("stroke","black")
    .style("stroke-width","0")
    ;
    
    // Add a y-axis label.
    svg.append("text")
    .transition()
    .delay(2000)
    .attr("class", "y label")
    .attr("text-anchor", "end")
    .attr("x",10)
    .attr("y", 6)
    .attr("dy", ".75em")
    .attr("transform", "rotate(-90)")
    .style("font-size","12px")
    .style("fill","black")
    .style("stroke","black")
    .style("stroke-width","0")
    .text("Revenue Inflation Adjusted")
    .transition()
    .delay(10000)
    .duration(3000)
    .attr("x",width-250)
    .attr("y", height+200)
    .attr("transform", "rotate(0)")
    .attr("y", 150)
    .style("font-size","40px")
    .style("fill","white")
    .style("stroke","black")
    .style("stroke-width","1")
    .transition()
    .delay(13000)
    .duration(4000)
    .attr("text-anchor", "end")
    .attr("x",10)
    .attr("y", 6)
    .attr("dy", ".75em")
    .attr("transform", "rotate(-90)")
    .style("font-size","12px")
    .style("fill","black")
    .style("stroke","black")
    .style("stroke-width","0");
    
    //labeling the threshold line
    svg.append("text")
        .transition()
        .delay(16000)
        .duration(2000)
        .attr("x",800)
        .attr("y", yScale(60))
        .style("fill","black")
        .style("font-size","12px")
        .style("stroke","black")
        .style("stroke-width","0")
        .text("Threshold Value:50m$")
        .transition()
        .delay(18000)
        .duration(4000)
        .attr("x",width-700)
        .attr("y", height-200)
        .style("font-size","40px")
        .style("fill","white")
        .style("stroke","black")
        .style("stroke-width","1")
        .transition()
        .delay(21000)
        .duration(4000)
        .attr("x",800)
        .attr("y", yScale(60))
        .style("font-size","12px")
        .style("fill","black")
        .style("stroke","black")
        .style("stroke-width","0")
        ;
    
    // Add the year label; the value is set on transition.
    var label = svg.append("text")
                        .attr("class", "year label")
                        .attr("text-anchor", "end")
                        .attr("y", height + 300)
                        .attr("x", width-600)
                        .text(1970);
    
    /*var naming = svg.append("text").selectAll(".dot")
                                                .attr("text-anchor", "end")
                                                .attr("y", 500)
                                                .attr("x", 500)
                                                .text("Company Name");*/
    
    
    
    
    // Load the data.
    
    
                    var bcolor;
    
    
                    //tooltip
                    var tip = d3.tip()
                              .attr('class', 'd3-tip')
                               .html(function(d) { 
                               if(get("" + key(d) + "prevR")<get("" + key(d) + "currentR")){
                                    bcolor = "green";
                               }
                               else
                               {
                               bcolor = "red    ";
                               }
    
    
                               return "<strong>Company:</strong><span style='color:"+bcolor+"'>" + d.Company+ "</span> <br> <strong>Type:</strong><span style='color:"+bcolor+"'> Finance Sector </span> <br><strong>Net Income (2008): &nbsp </strong><span style='color:"+bcolor+"'>" +formatValue(d.NetIncome2008) + "m$</span> <br> <strong>Revenue (Inflation Adjusted): &nbsp </strong><span style='color:"+bcolor+"'>" + formatValue(d.RevenueInflationAdjusted) + "</span>";})
                               ;
    
                        svg.call(tip);
    
    
    
                        // A bisector since many company's data is sparsely-defined.
                        var bisect = d3.bisector(function(d) {
                            return d[0];
                        });
    
                        // Add a dot per Company. Initialize the data at 1970, and set the colors.
                        var dot = svg.append("g")
                                        .attr("class", "dots")
                                        .selectAll("g")
                                        .data(interpolateData(1970))
                                        .enter().append("circle")
                                        .attr("class", "dot")
                                        .style("fill", function(d) {return colorScale(color(d));})
                                        .call(position)
                                        .sort(order)
                                        .on('mouseover', tip.show)
                                        .on('mouseout', tip.hide);
    
                        var prevDot = svg.append("g")
                                        .attr("class", "dots")
                                        .selectAll("g")
                                        .data(interpolateData(1970))
                                        .enter().append("circle")
                                        .attr("class", "dot")
                                        .style("fill", function(d) {return colorScale(color(d));})
                                        .call(previousPosition)
                                        .sort(order)
                                        .on('mouseover', tip.show)
                                        .on('mouseout', tip.hide);
    
    
    
                        var text = svg.selectAll("text")
                           .data(interpolateData(1970))
                           .enter()
                           .append("text");
    
    
                        // Add an overlay for the year label.
                        var box = label.node().getBBox();
    
                        var overlay = svg.append("rect").attr("class",
                                "overlay").attr("x", box.x).attr("y", box.y)
                                .attr("width", box.width).attr("height",
                                        box.height).on("mouseover",
                                        enableInteraction);
    
                        // Start a transition that interpolates the data based on year. 18000
                        svg.transition().delay(24000).duration(50000).ease("linear").tween(
                                "year", tweenYear).each("end",
                                enableInteraction);
    
                        // Positions the dots based on data.
                        function position(dot) {
    
                            dot
                            .attr("opacity", 0.8)
                            .attr("cx", function(d) {
                                currentX = xScale(x(d));
    
                                map["" + key(d) + "cx"] = currentX;
                                return currentX;
                            })
                            .attr("cy", function(d) {
                                currentY = yScale(y(d));
                                map["" + key(d) + "cy"] = currentY;
                                return currentY;
                            }).attr("r", function(d) {
                                currentR = radiusScale(radius(d));
                                map["" + key(d) + "currentR"] = currentR;
                                //alert("currentX"+currentX);
    
                                var cName = d.Company;
    
                                //svg.append("g").attr("y", currentY + currentR + 1).attr("x", currentX + 10).text(".");
                                //alert("currentX"+currentX);
    
    
    
                                return currentR;
                            });
    
    
                            /*var cName = get("" + key(d) + "cName");
                              alert(""+cName);
                                //svg.append("text").attr("y", currentY + currentR + 1).attr("x", currentX).text(cName);*/
                        } 
    
                                //var naminggg = svg.selectAll("text")
                                  // .data(interpolateData(1970), key)
                                   //.enter()
                                   //.append("text")
                                     // .attr("x", 500)
                                      //.attr("y", 500)
                                      //.text("Babu")
                                      //.attr("text-anchor", "middle");
    
    
    
                        // Previous position of the dots
                        function previousPosition(prevDot) {
                            prevDot
                            .attr("opacity", 0.4)
                            .attr("cx", function(d) {
                                return get("" + key(d) + "cx");
                            }).attr("cy", function(d) {
                                return get("" + key(d) + "cy");
                            }).attr("r", function(d) {                          
                                prevR = prevRadiusScale(radius(d));
                                map["" + key(d) + "prevR"] = prevR;
                                return prevRadiusScale(radius(d));
                            });
                        }
    
    
                        function positionText(text) {
    
                            text
                            .attr("opacity", 0.8)
                            .attr("x", function(d) {return xScale(x(d));})
                            .attr("y", function(d) {return yScale(y(d));})
                            .text(function(d){return d.Company;});
                            }
    
                        function get(key) {
    
    
    
                            return map[key];
                        }
    
                        // Defines a sort order so that the smallest dots are drawn on top.
                        function order(a, b) {
                            return radius(b) - radius(a);
                        }
    
                        // After the transition finishes, you can mouseover to change the year.
                        function enableInteraction() {
                            // alert("Inside Enable Interaction");
                            var yearScale = d3.scale.linear().domain(
                                    [ 1970, 2002 ]).range(
                                    [ box.x + 10, box.x + box.width - 10 ])
                                    .clamp(true);
    
                            // Cancel the current transition, if any.
                            // TODO Should disappear when not in use
                            svg.transition().duration(0);
    
                            overlay.on("mouseover", mouseover).on("mouseout",
                                    mouseout).on("mousemove", mousemove).on(
                                    "touchmove", mousemove);
    
                            function mouseover() {
    
                                label.classed("active", true);
                                naming.classed("active", true);
    
                            }
    
                            function mouseout() {
                                label.classed("active", false);
                                naming.classed("active", false);
                            }
    
                            function mousemove() {
    
                                displayYear(yearScale.invert(d3.mouse(this)[0]));
                            }
                        }
    
                        // Tweens the entire chart by first tweening the year, and then the data.
                        // For the interpolated data, the dots and label are redrawn.
                        function tweenYear() {
                            var year = d3.interpolateNumber(1970, 2002);
                            return function(t) {
                                displayYear(year(t));
                            };
                        }
    
                        // Updates the display to show the specified year.
                        function displayYear(year) {
                            if (Math.round(year) == 1970) {
                                dot.data(interpolateData(year), key).call(
                                        position).sort(order);
                            } else {
                                dot.data(interpolateData(year), key).call(
                                        position).sort(order);
                                prevDot.data(interpolateData(year - 1), key)
                                        .call(previousPosition).sort(order);
    
                            }
                            // var textLabel = svg.append("text").call(positionText);
    
    
                            label.text(Math.round(year));
                        }
    
                        var bata =  [
                            [5, 20], [480, 90], [250, 50], [100, 33], [330, 95],
                            [410, 12], [475, 44], [25, 67], [85, 21], [220, 88]
                          ];
    
                          svg.selectAll("text").data(bata).enter().append("text").attr("x", function(d) { alert(xScale(x(d))); return xScale(x(d)) + radiusScale(radius(d)) + 1;}).attr("y", function(d) { return yScale(y(d)) + radiusScale(radius(d)) + 1}).text("Bebu");
    
                        // Interpolates the dataset for the given (fractional) year.
                        function interpolateData(year) {                
                            return heuristics.map(function(d) { 
                                        return {
                                            Company : d.Company,
                                            CompanyName : d.CompanyName,
                                            NetIncome2008 : interpolateValues(d.NetIncome2008, year),
                                            RevenueInflationAdjusted : interpolateValues(d.RevenueInflationAdjusted,year)
                                        };
                                    });
                        }
    
                        // Finds (and possibly interpolates) the value for the specified year.
                        function interpolateValues(values, year) {
                            var i = bisect.left(values, year, 0,
                                    values.length - 1), a = values[i];
                            if (i > 0) {
                                var b = values[i - 1], t = (year - a[0])/ (b[0] - a[0]);
                                return (a[1] * (1 - t) + b[1] * t);
                            }
                            return a[1];
                        }
    
    
                    });
    

0 个答案:

没有答案