我想知道你是否可以帮我解决D3中的一般更新模式......
我试图将一个非常基本的数据数组显示为条形图,其中包含一个输入表单,用于向阵列添加新数据并在图表上动态更新。
有很多重复,因为我试图重构向svg添加新矩形的过程,但没有运气......
如果有人能向我解释如何将新对象添加到数据数组中,然后刷新将会非常棒的svg。我希望这个问题也属于主持人的指导方针......
到目前为止,这是我的代码:
app.js:
// set a width and height for the svg
var height = 500;
var width = 1000;
var barPadding = 10;
var barWidth = width / data.length - barPadding;
var maxPoints = d3.max(data, function(d){
return d.score;
});
var myScale = d3.scaleLinear()
.domain([0, maxPoints])
.range([height, 0]);
var svg = d3.select('svg')
.attr("height", height) //setting the height
.attr("width", width) // setting the width
.style("display", "block") // svgs are inline, hence needs to be block
.style("margin", "100px auto") // centering
.selectAll("rect") // creating nodes
.data(data) // binds data to the nodes
.enter() // goes into the enter selection
.append("rect")
.attr("width", barWidth)
.attr("height", function(d){
return height - myScale(d.score);
})
.attr("x", function(d, i){
return (barWidth + barPadding) * i;
})
.attr("y", function(d, i){
return myScale(d.score);
})
.attr("fill", "green");
// INPUT NEW DATA
var nameInput = "input[name='name']";
var scoreInput = "input[name='score']";
function addRect(){
barWidth = width / data.length - barPadding;
svg
.append("rect")
.attr("height", function(d){
return height - myScale(d.score);
})
.attr("x", function(d, i){
return (barWidth + barPadding) * i;
})
.attr("y", function(d, i){
return myScale(d.score);
})
.attr("fill", "green");
};
d3.select("form")
.on("submit", function() {
d3.event.preventDefault();
var firstInput = d3.select(nameInput)
.property("value");
var secondInput = d3.select(scoreInput)
.property("value");
data.push({player: firstInput, score: secondInput });
console.log(data);
svg
.data(data)
.enter();
addRect();
});
html:
<body>
<div class="display">
<svg
version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg"
id="letters">
</svg>
</div>
<div class="form">
<form action="">
<input type="text" placeholder="Name" name="name">
<input type="text" placeholder="Score" name="score">
<input type="submit">
</form>
</div>
<script src="https://d3js.org/d3.v4.js"></script>
<script src="data.js"></script>
<script src="app.js"></script>
</body>
data.js:
var data = [
{player: "Raph", score: 12},
{player: "Henry", score: 43},
{player: "James", score: 29},
{player: "Andrew", score: 200},
{player: "Ella", score: 87},
{player: "Bob", score: 3},
{player: "Lil", score: 19},
{player: "Jenny", score: 223},
{player: "Dad", score: 33},
{player: "Rhys", score: 45}
];
非常感谢您提前提供任何帮助,
拉夫
答案 0 :(得分:0)
在添加新矩形时,您还必须更新现有矩形的属性。
尝试如下所示 -
var data = [
{player: "Raph", score: 12},
{player: "Henry", score: 43},
{player: "James", score: 29},
{player: "Andrew", score: 200},
{player: "Ella", score: 87},
{player: "Bob", score: 3},
{player: "Lil", score: 19},
{player: "Jenny", score: 223},
{player: "Dad", score: 33},
{player: "Rhys", score: 45}
];
// set a width and height for the svg
var height = 200;
var width = 400;
var barPadding = 10;
var barWidth = width / data.length - barPadding;
var maxPoints = d3.max(data, function(d) {
return d.score;
});
var myScale = d3.scaleLinear()
.domain([0, maxPoints])
.range([height, 0]);
var svg = d3.select("svg")
.attr("height", height)
.attr("width", width)
.style("display", "block")
.style("margin", "10px 0px"); //changed for look and feel
//.style("margin", "100px auto");
drawRect(); //Creating rects
//Moved the code to create rectangles and style into a function.
function drawRect() {
var rect = svg
.selectAll("rect")
.data(data)
.enter()
.append("rect");
svg
.selectAll("rect")
.attr("width", barWidth)
.attr("height", function(d) {
return height - myScale(d.score);
})
.attr("x", function(d, i) {
return (barWidth + barPadding) * i;
})
.attr("y", function(d, i) {
return myScale(d.score);
})
.attr("fill", "green");
}
// INPUT NEW DATA
var nameInput = "input[name='name']";
var scoreInput = "input[name='score']";
d3.select("form")
.on("submit", function() {
d3.event.preventDefault();
var firstInput = d3.select(nameInput)
.property("value");
var secondInput = d3.select(scoreInput)
.property("value");
data.push({
player: firstInput,
score: secondInput
});
barWidth = width / data.length - barPadding;
drawRect(); //Adding new rects and update others
});
&#13;
<script src="https://d3js.org/d3.v4.js"></script>
<body>
<div class="display">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" id="letters">
</svg>
</div>
<div class="form">
<form action="">
<input type="text" placeholder="Name" name="name">
<input type="text" placeholder="Score" name="score">
<input type="submit">
</form>
</div>
</body>
&#13;