Seeking guidance on implementing the general update pattern in D3...
My goal is to create a basic bar chart displaying data from an array, with an input form to add new data and dynamically update the chart.
Struggling with repetition while trying to refactor the process of adding rectangles to the svg...
If anyone can explain how to add a new object to the data array and refresh the svg, that would be greatly appreciated. I hope this question complies with moderator guidelines...
Current code snippet:
app.js:
// defining 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)
.attr("width", width)
.style("display", "block")
.style("margin", "100px auto")
.selectAll("rect")
.data(data)
.enter()
.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}
];
Appreciate any assistance provided,
Raph