如何在d3中单击更改csv文件时更新区域图表中的文本?

时间:2014-07-17 17:30:15

标签: csv text d3.js charts area

我是D3的初学者。当我通过clickon更改csv文件时,我制作了区域图表。问题只是文字。来到新文本时,旧文本不会删除。

以下是具有更新功能的代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" >
<title>Otroška imena</title>
<script src="D3/d3.js"></script>
<script src="D3/d3.layout.cloud.js"></script>

<!-- Style -->
<link rel="stylesheet" type="text/css" href="mystyle.css">

</head>
<body>
<div id="option">
    <input type="button"value="Adam"onclick="zamenjaj(value)" />
    <input type="button"value="Aljaž"onclick="zamenjaj(value)" />
    <input type="button"value="Sara"onclick="zamenjaj(value)" />
</div>

<!-- JavaScript -->
<script>
window.funkcija1 = function(x){zamenjaj(x.value);}

//Dimensions of canvas
    var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 700 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;

// Set the ranges
var x = d3.scale.linear().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

// Define the axes
var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.format("d"));
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5);

//Area
var area = d3.svg.area()
    .interpolate("monotone")
    .x(function(d) { return x(d.leto); })
    .y0(height)
    .y1(function(d) { return y(d.st); });

// Line
var valueline = d3.svg.line()
.interpolate("monotone")
.x(function(d) { return x(d.leto); })
.y(function(d) { return y(d.st); });


//SVG canvas
var svg = 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 + ")");

// y grid lines
function make_y_axis() {return d3.svg.axis().scale(y).orient("left").ticks(5)}      

//**DATA**
d3.csv("Imena/Adam.csv",function(error, podatki) {
podatki.forEach(function(d) {d.st = +d.st;  });

// Compute the minimum and maximum
x.domain(d3.extent(podatki,function(d) { return d.leto; }));
y.domain([0, d3.max(podatki, function(d) { return d.st; })]);

// Add the filled area
svg.append("path")
    .attr("class", "area")
    .attr("d", area(podatki));

// Add the valueline path.
svg.append("path")      // Add the valueline path.
    .attr("class", "line")
    .attr("d", valueline(podatki));

// Draw the Y Grid lines
svg.append("g")         
    .attr("class", "grid")
    .call(make_y_axis().tickSize(-width, 0, 0).tickFormat(""))

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

// Add the Y Axis
svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("Stevilo");

    podatki.splice(1,20);   

    var napis = svg.selectAll().data(podatki).enter().append("text")
    napis
        .text(function(d){return d["ime"]})
        .attr("class","graftext")
        .attr("y",50).attr("x",50);
});

// ** Update podatki section (Called from the onclick)
function zamenjaj(ime_s) {

    // Get the podatki again
    d3.csv("Imena/" + ime_s + ".csv",function(error, podatki) {
    podatki.forEach(function(d) {
        d.st = +d.st;});

    // Select the section we want to apply our changes to
    var svgUpdate = d3.select("body").transition();

    // Scale the range of the data again 
    y.domain([0, d3.max(podatki, function(d) { return d.st; })]);

    // Make the changes
    svgUpdate.select(".area")
        .duration(750)
        .attr("d", area(podatki));
    svgUpdate.select(".line")   // change the line
        .duration(750)
        .attr("d", valueline(podatki));
    svgUpdate.select(".y.axis") // change the y axis
        .duration(750)
        .call(yAxis);  

    podatki.splice(1,20);   

    var napisUpdate = svg.selectAll(".text").data(podatki);
    napisUpdate.exit().remove();
    napisUpdate.enter().append("text")
        .text(function(d){return d["ime"]})
        .attr("class","graftext")
        .attr("y",80).attr("x",50).duration(750);
    });
}
</script>
</body>
</html>

这些页面帮助了我:thisthis,但遗憾的是它对我不起作用。谢谢你的帮助。

2 个答案:

答案 0 :(得分:0)

您正在使用.text类选择文本元素,但是当您在.enter()选区中创建文本元素时,您将为其提供一个.graftext类。你需要为你的新元素使用相同的类来进行选择,否则当计算数据连接时,它会认为你需要所有新元素,因为选择是空的。

试试这样:

// selects all elements with class of `graftext` and joins the data
var napisUpdate = svg.selectAll(".graftext").data(podatki);
  // remove excess elements for which there is no data 
  napisUpdate.exit().remove();
  // create new elements for each excess datapoint
  napisUpdate.enter().append("text")
    .attr("class","graftext")
    .attr("y",80).attr("x",50).duration(750);
  });
  // update existing elements with the new information
  napisUpdate.text(function(d){return d["ime"]});

答案 1 :(得分:0)

几个小时后我解决了这个问题。我改变了一些东西并且有效:

svg.append('text')
    .data(podatki)
    .attr('x', 30)
    .attr('y', 50)
    .attr("class","graftext")
    .text(function(d) { return d.ime })

在更新功能中:

podatki.splice(1,20);   
var svgUpdate = d3.select(".graftext").data(podatki);   
svgUpdate.exit().remove();
svgUpdate.enter().append("text");
svgUpdate.text(function(d) { return d.ime });