Je suis nouveau sur d3.js
. Je veux mapper les données JSON
dans un graphique à barres groupées comme indiqué sur la figure comme exemple https: //i.stack.imgur.com/9BLVz.png. Je sais qu'il y a un problème avec ma mise à l'échelle x. Selon mon graphique, x devrait montrer les mois et les heures sur l'axe des y. Cela me donne 6 barres mais pour une raison quelconque, les barres se chevauchent. Quelqu'un pourrait-il m'aider ici.
Données JSON provenant de MariaDB en tant qu'objet.
[
{"name":"jhon","hours":"9","months":"August"},
{"name":"jack","hours":"8","months":"August"},
{"name":"jhon","hours":"7","months":"July"},
{"name":"jack","hours":"6","months":"July"},
{"name":"jhon","hours":"4","months":"June"},
{"name":"jack","hours":"5","months":"June"}
]
Code
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.bar {
fill: steelblue;
stroke:black
}
.bar:hover {
fill: brown;
}
.axis--x path {
display: none;
}
</style>
<svg width="500" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 40},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("http://localhost:8888/index.php?r=emp/gethours", function(d) {
var ydomain=d3.extent(d,function(d){return d.hours;});
x.domain(d.map(function(d,i) {return d.months}));
y.domain(ydomain);
g.selectAll(".bar")
.data(d)
.enter().append("rect")
.attr("x", function(d,i) { return x(d.months) })
.attr("y", function(d) {return y(d.hours); })
.attr("width", 40)
.attr("height", function(d) { return height - y(d.hours); })
});
</script>
Après suggestion, ma modification des données et du code est
Le graphique à barres généré pour cela est https://i.stack.imgur.com/VowEA.png
[{"name":"jhon","hours":"8","months":"June","emp_id":"1"},{"name":"jack","hours":"6","months":"June","emp_id":"2"},{"name":"jhon","hours":"6","months":"July","emp_id":"1"},{"name":"jack","hours":"7","months":"July","emp_id":"2"},{"name":"jhon","hours":"8","months":"August","emp_id":"1"},{"name":"jack","hours":"9","months":"August","emp_id":"2"}]
<style>
.bar {
fill: steelblue;
stroke:black
}
.bar:hover {
fill: brown;
}
.axis--x path {
display: none;
}
</style>
<svg width="500" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 40},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var z = d3.scaleOrdinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
d3.json("http://localhost:8888/index.php?r=emp/gethours", function(d) {
var ymaxdomain=d3.max(d,function(d){return parseInt(d.hours);});
var x1domain=d3.extent(d,function(d){return parseInt(d.emp_id);});
x.domain(d.map(function(d) {return d.months}));
y.domain([0,ymaxdomain]);
var x1=d3.scaleBand().rangeRound([0, x.bandwidth()]);
x1.domain(x1domain);
g.selectAll(".bar")
.data(d)
.enter().append("rect")
.attr("x", function(d,i) {console.log(d,i); return (x(d.months)+x1(parseInt(d.emp_id))); })
.attr("y", function(d) {return y(d.hours); })
.attr("width",x1.bandwidth())
.attr("height", function(d) { return height - y(parseInt(d.hours)); })
.attr("fill", function(d,i) { return z(d.emp_id); });
g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y).ticks(null, "s"))
.append("text")
.attr("x", 2)
.attr("y", y(y.ticks().pop()) + 0.5)
.attr("dy", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "start")
.text("Hours");
});
</script>
3 réponses
Données Json
[{"name":"jhon","hours":"8","months":"June","emp_id":"1"},
{"name":"jack","hours":"6","months":"June","emp_id":"2"},
{"name":"jim","hours":"7","months":"June","emp_id":"3"},
{"name":"tim","hours":"4","months":"June","emp_id":"4"},
{"name":"jhon","hours":"6","months":"July","emp_id":"1"},
{"name":"jack","hours":"7","months":"July","emp_id":"2"},
{"name":"jim","hours":"8","months":"July","emp_id":"3"},
{"name":"tim","hours":"6","months":"July","emp_id":"4"},
{"name":"jhon","hours":"8","months":"August","emp_id":"1"},
{"name":"jack","hours":"9","months":"August","emp_id":"2"},
{"name":"jim","hours":"7","months":"August","emp_id":"3"},
{"name":"tim","hours":"8","months":"August","emp_id":"4"}]
Et la réponse ----------------------------------------------- ----------
Image de graphique à barres groupée https://i.stack.imgur.com/1ud5S.png
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.bar {
fill: steelblue;
stroke:black
}
.bar:hover {
fill: brown;
}
.axis--x path {
display: none;
}
</style>
<svg width="600" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 40},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var z = d3.scaleOrdinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
d3.json("http://localhost:8888/index.php?r=emp/gethours", function(d) {
var ymaxdomain=d3.max(d,function(d){return d.hours;});
x.domain(d.map(function(d) {return d.months}));
y.domain([0,ymaxdomain]);
var x1=d3.scaleBand().rangeRound([0, x.bandwidth()]);
x1.domain(d.map(function(d) {return d.emp_id;}));
g.selectAll(".bar")
.data(d)
.enter().append("rect")
.attr("x", function(d,i) {return (x(d.months)+x1(d.emp_id)); })
.attr("y", function(d) {return y(d.hours); })
.attr("width",x1.bandwidth())
.attr("height", function(d) { return height - y(d.hours); })
.attr("fill", function(d,i) { return z(d.emp_id); });
g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y))
.append("text")
.attr("x", 2)
.attr("y", y(y.ticks().pop()) + 0.5)
.attr("dy", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "start")
.text("Hours");
});
</script>
Comme dans https://bl.ocks.org/mbostock/3887051 vous avez besoin d'un deuxième x axe pour déplacer votre rect pour chaque "groupe". regardez var x1;
son domaine est .rangeRound([0, x0.bandwidth()]);
.
Dans votre code, vous pouvez le faire
var d = [
{"name":"jhon","hours":"9","months":"August","group":0},
{"name":"jack","hours":"8","months":"August","group":1},
{"name":"jhon","hours":"7","months":"July","group":0},
{"name":"jack","hours":"6","months":"July","group":1},
{"name":"jhon","hours":"4","months":"June","group":0},
{"name":"jack","hours":"5","months":"June","group":1}
]
x1.domain([0,1])
...
.attr("x", function(d) { return x(d.months)+x1(d.group) })
Oh j'ai trouvé votre problème changer
var ydomain=d3.extent(d,function(d){return d.hours;});
À
var ymaxdomain=d3.max(d,function(d){return d.hours;});
y.domain([0,ymaxdomain]);
Votre valeur minimale sur l'axe y était de 4 au lieu de 0
Edit: vous devez également déplacer la définition de la plage de x1 APRÈS avoir défini le domaine x:
x.domain(d.map(function(d,i) {return d.months}));
// this should go after
var x1=d3.scaleBand().rangeRound([0, x.bandwidth()]);
Questions connexes
De nouvelles questions
d3.js
D3.js est une bibliothèque JavaScript pour créer des visualisations interactives liées aux données de documents à l'aide de HTML, SVG et Canvas.