Reputation: 41
I'm making a js function to plot data into a new div each time it is called, the problem is that it is that some appends are not working for the second call, I need your help to know what's wrong.
Screenshot demonstrating the differences between first and second call results
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var data = [];
data.push({
date: " 2019-03-25 00:00:00 ",
value: 509
});
data.push({
date: " 2019-03-26 00:00:00 ",
value: 505
});
data.push({
date: " 2019-03-27 00:00:00 ",
value: 504
});
data.push({
date: " 2019-03-28 00:00:00 ",
value: 517
});
data.push({
date: " 2019-03-29 00:00:00 ",
value: 376
});
data.push({
date: " 2019-03-30 00:00:00 ",
value: 474
});
data.push({
date: " 2019-03-31 00:00:00 ",
value: 504
});
data.push({
date: " 2019-04-01 00:00:00 ",
value: 510
});
data.push({
date: " 2019-04-02 00:00:00 ",
value: 507
});
data.push({
date: " 2019-04-03 00:00:00 ",
value: 516
});
data.push({
date: " 2019-04-04 00:00:00 ",
value: 529
});
data.push({
date: " 2019-04-05 00:00:00 ",
value: 380
});
data.push({
date: " 2019-04-06 00:00:00 ",
value: 455
});
data.push({
date: " 2019-04-07 00:00:00 ",
value: 513
});
function plot(arg) {
var ddd = arg;
var margin = {
top: 20,
right: 20,
bottom: 70,
left: 40
};
var width = 600 - margin.left - margin.right;
var height = 300 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format(" %Y-%m-%d %H:%M:%S ").parse;
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format("%d/%m"));
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(7);
var div = d3.select("body").append("div");
var svg = div.append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom);
var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
ddd.forEach(function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
});
x.domain(ddd.map(function(d) {
return d.date;
}));
y.domain([0, d3.max(ddd, function(d) {
return d.value;
})]);
g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis).selectAll("text").style("text-anchor", "end").attr("dx", "-.8em").attr("dy", "-.55em").attr("transform", "rotate(-90)");
g.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(0)").attr("y", -13).attr("dy", ".71em").style("text-anchor", "end").text("Count");
g.selectAll("bar").data(ddd).enter().append("rect").style("fill", "steelblue").attr("x", function(d) {
return x(d.date);
}).attr("width", x.rangeBand()).attr("y", function(d) {
return y(d.value);
}).attr("height", function(d) {
return height - y(d.value);
});;
}
plot(data);
plot(data);
</script>
</body>
Upvotes: 1
Views: 226
Reputation: 3898
Your function plot()
has a side effect
- its changing input data array.
If you pass copies there everything will be fine:
plot(data.map(a => Object.assign({}, a)));
plot(data.map(a => Object.assign({}, a)));
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var data = [];
data.push({
date: " 2019-03-25 00:00:00 ",
value: 509
});
data.push({
date: " 2019-03-26 00:00:00 ",
value: 505
});
data.push({
date: " 2019-03-27 00:00:00 ",
value: 504
});
data.push({
date: " 2019-03-28 00:00:00 ",
value: 517
});
data.push({
date: " 2019-03-29 00:00:00 ",
value: 376
});
data.push({
date: " 2019-03-30 00:00:00 ",
value: 474
});
data.push({
date: " 2019-03-31 00:00:00 ",
value: 504
});
data.push({
date: " 2019-04-01 00:00:00 ",
value: 510
});
data.push({
date: " 2019-04-02 00:00:00 ",
value: 507
});
data.push({
date: " 2019-04-03 00:00:00 ",
value: 516
});
data.push({
date: " 2019-04-04 00:00:00 ",
value: 529
});
data.push({
date: " 2019-04-05 00:00:00 ",
value: 380
});
data.push({
date: " 2019-04-06 00:00:00 ",
value: 455
});
data.push({
date: " 2019-04-07 00:00:00 ",
value: 513
});
function plot(arg) {
var ddd = arg;
var margin = {
top: 20,
right: 20,
bottom: 70,
left: 40
};
var width = 600 - margin.left - margin.right;
var height = 300 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format(" %Y-%m-%d %H:%M:%S ").parse;
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format("%d/%m"));
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(7);
var div = d3.select("body").append("div");
var svg = div.append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom);
var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
ddd.forEach(function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
});
x.domain(ddd.map(function(d) {
return d.date;
}));
y.domain([0, d3.max(ddd, function(d) {
return d.value;
})]);
g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis).selectAll("text").style("text-anchor", "end").attr("dx", "-.8em").attr("dy", "-.55em").attr("transform", "rotate(-90)");
g.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(0)").attr("y", -13).attr("dy", ".71em").style("text-anchor", "end").text("Count");
g.selectAll("bar").data(ddd).enter().append("rect").style("fill", "steelblue").attr("x", function(d) {
return x(d.date);
}).attr("width", x.rangeBand()).attr("y", function(d) {
return y(d.value);
}).attr("height", function(d) {
return height - y(d.value);
});;
}
plot(data.map(a => Object.assign({}, a)));
plot(data.map(a => Object.assign({}, a)));
</script>
</body>
UPD: After inspecting your code once more i've figure out that you can simply extract this code:
var parseDate = d3.time.format(" %Y-%m-%d %H:%M:%S ").parse;
data.forEach(function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
});
from plot
function and place it before calling plot
function, here is working solution:
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var data = [];
data.push({
date: " 2019-03-25 00:00:00 ",
value: 509
});
data.push({
date: " 2019-03-26 00:00:00 ",
value: 505
});
data.push({
date: " 2019-03-27 00:00:00 ",
value: 504
});
data.push({
date: " 2019-03-28 00:00:00 ",
value: 517
});
data.push({
date: " 2019-03-29 00:00:00 ",
value: 376
});
data.push({
date: " 2019-03-30 00:00:00 ",
value: 474
});
data.push({
date: " 2019-03-31 00:00:00 ",
value: 504
});
data.push({
date: " 2019-04-01 00:00:00 ",
value: 510
});
data.push({
date: " 2019-04-02 00:00:00 ",
value: 507
});
data.push({
date: " 2019-04-03 00:00:00 ",
value: 516
});
data.push({
date: " 2019-04-04 00:00:00 ",
value: 529
});
data.push({
date: " 2019-04-05 00:00:00 ",
value: 380
});
data.push({
date: " 2019-04-06 00:00:00 ",
value: 455
});
data.push({
date: " 2019-04-07 00:00:00 ",
value: 513
});
function plot(arg) {
var ddd = arg;
var margin = {
top: 20,
right: 20,
bottom: 70,
left: 40
};
var width = 600 - margin.left - margin.right;
var height = 300 - margin.top - margin.bottom;
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format("%d/%m"));
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(7);
var div = d3.select("body").append("div");
var svg = div.append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom);
var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(ddd.map(function(d) {
return d.date;
}));
y.domain([0, d3.max(ddd, function(d) {
return d.value;
})]);
g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis).selectAll("text").style("text-anchor", "end").attr("dx", "-.8em").attr("dy", "-.55em").attr("transform", "rotate(-90)");
g.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(0)").attr("y", -13).attr("dy", ".71em").style("text-anchor", "end").text("Count");
g.selectAll("bar").data(ddd).enter().append("rect").style("fill", "steelblue").attr("x", function(d) {
return x(d.date);
}).attr("width", x.rangeBand()).attr("y", function(d) {
return y(d.value);
}).attr("height", function(d) {
return height - y(d.value);
});;
}
var parseDate = d3.time.format(" %Y-%m-%d %H:%M:%S ").parse;
data.forEach(function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
});
plot(data);
plot(data);
</script>
</body>
Upvotes: 1