d3js bar graph with x+y axes: x轴值分布
d3js bar graph with x+y axes: x axis value distribution
我正在尝试显示带有 x 轴和 y 轴的垂直条形图。我得到了带有 y 轴的条形图,但是我在 x 轴上遇到了困难。
x 轴文本标签与条的宽度均匀分布,但是:x 轴上有 markers/vertical 行,宽度不同,尤其是第一部分和最后一部分,即使我已指定 scaleBand
和 domain
。
我的代码:
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg class="v5chart" width="960" height="500"></svg>
<style>
/*Rectangle bar class styling*/
.bar {
fill: #0080FF
}
.bar:hover {
fill: #003366
}
/*Text class styling*/
.text {
fill: white;
font-family: sans-serif
}
</style>
<script>
////VERTICAL BAR CHART WITH SVG AND NAMES
// Create data array of values to visualize
var dataArray = [{ "Player": "John Doe", "Points": 23 }, { "Player": "Jane Doe", "Points": 13 }, { "Player": "Mary Jane", "Points": 21 }, { "Player": "Debasis Das", "Points": 14 }, { "Player": "Nishant", "Points": 37 }, { "Player": "Mark", "Points": 15 }, { "Player": "Andrew", "Points": 18 }, { "Player": "Simon", "Points": 34 }, { "Player": "Lisa", "Points": 30 }, { "Player": "Marga", "Points": 20 }];
// Create variable for the SVG
var canvas = d3.select(".v5chart1").append("g").attr("transform", "translate(20,30)");
var canvasWidth = 500;
var maxValue = d3.max(dataArray, function (d) { return d.Points; });
var canvasHeight = maxValue*10;
var heightScale = d3.scaleLinear()
.domain([0, d3.max(dataArray, function (d) { return d.Points; })])
.range([canvasHeight, 0]); //use max value (37) * 10
var y_axis = d3.axisLeft()
.scale(heightScale);
var x = d3.scaleBand()
.rangeRound([0, canvasWidth], .1);
x.domain(dataArray.map(function (d) { return d.Player; }));
var x_Axis = d3.axisBottom(x);
// Select, append to SVG, and add attributes to rectangles for bar chart
canvas.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("class", "bar")
.attr("height", function (d, i) { return (d.Points * 10) })
.attr("width", canvasWidth/dataArray.length)
.attr("x", function (d, i) { return (i * (canvasWidth / dataArray.length)) })
.attr("y", function (d, i) { return canvasHeight - (d.Points * 10) });
// Select, append to SVG, and add attributes to text
canvas.selectAll("text")
.data(dataArray)
.enter().append("text")
.text(function (d) { return d.Points })
.attr("class", "text")
.attr("x", function (d, i) { return (i * (canvasWidth / dataArray.length)) + (canvasWidth / dataArray.length)/2 })
.attr("y", function (d, i) { return canvasHeight + 20 - (d.Points * 10) });
canvas.append("g")
.attr("transform", "translate(0,0)")
.call(y_axis);
canvas.append("g")
.attr("transform", "translate(0," + canvasHeight + ")")
.call(x_Axis)
.selectAll("text")
.attr("x",40)
.attr("transform", function (d) {
return "rotate(65)"
});
</script>
我已经检查过这里:https://www.d3-graph-gallery.com/graph/custom_axis.html
您应该已经正确阅读了您提供的 link 中的 scaleBand
示例:
scaleBand
提供了一种方便的 bandwidth()
方法来为您提供每个柱的宽度
d3js
中的 od axis 的想法是您不需要自己进行计算,因此在您的情况下,您只需将玩家名称传递给 x
函数即可坐标计算给你。
- 同样适用于
y
计算,但我把这个留给你自己弄清楚,一点也不难。
- 关于
scaleBand
的另一个小事,你使用的是 rangeRound()
方法,我不熟悉,但是如果你使用 range()
方法结合 padding()
正如您 link 编辑的示例,然后通过调整填充值,您可以控制栏的宽度,而不会影响 x 轴。值越高,条形越细,条形之间的 space 越多。
////VERTICAL BAR CHART WITH SVG AND NAMES
// Create data array of values to visualize
var dataArray = [{ "Player": "John Doe", "Points": 23 }, { "Player": "Jane Doe", "Points": 13 }, { "Player": "Mary Jane", "Points": 21 }, { "Player": "Debasis Das", "Points": 14 }, { "Player": "Nishant", "Points": 37 }, { "Player": "Mark", "Points": 15 }, { "Player": "Andrew", "Points": 18 }, { "Player": "Simon", "Points": 34 }, { "Player": "Lisa", "Points": 30 }, { "Player": "Marga", "Points": 20 }];
// Create variable for the SVG
var canvas = d3.select(".v5chart").append("g").attr("transform", "translate(20,30)");
var canvasWidth = 500;
var maxValue = d3.max(dataArray, function (d) { return d.Points; });
var heightScale = d3.scaleLinear()
.domain([0, d3.max(dataArray, function (d) { return d.Points; })])
.range([maxValue * 10, 0]); //use max value (37) * 10
var y_axis = d3.axisLeft()
.scale(heightScale);
var x = d3.scaleBand()
.range([0, canvasWidth]).padding([0.1]);
x.domain(dataArray.map(function (d) { return d.Player; }));
var x_Axis = d3.axisBottom(x);
// Select, append to SVG, and add attributes to rectangles for bar chart
canvas.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("class", "bar")
.attr("height", function (d, i) { return (d.Points * 10) })
.attr("width", x.bandwidth())
.attr("x", function (d, i) { return x(d.Player); })
.attr("y", function (d, i) { return 370 - (d.Points * 10) });
// Select, append to SVG, and add attributes to text
canvas.selectAll("text")
.data(dataArray)
.enter().append("text")
.text(function (d) { return d.Points })
.attr("class", "text")
.attr("text-anchor", "middle")
.attr("x", function (d, i) { return x(d.Player)+x.bandwidth()/2; })
.attr("y", function (d, i) { return 390 - (d.Points * 10) });
canvas.append("g")
.attr("transform", "translate(0,0)")
.call(y_axis);
canvas.append("g")
.attr("transform", "translate(0,370)")
.call(x_Axis);
.bar {
fill: #0080FF
}
.bar:hover {
fill: #003366
}
/*Text class styling*/
.text {
fill: white;
font-family: sans-serif
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg class="v5chart" width="960" height="500"></svg>
我正在尝试显示带有 x 轴和 y 轴的垂直条形图。我得到了带有 y 轴的条形图,但是我在 x 轴上遇到了困难。
x 轴文本标签与条的宽度均匀分布,但是:x 轴上有 markers/vertical 行,宽度不同,尤其是第一部分和最后一部分,即使我已指定 scaleBand
和 domain
。
我的代码:
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg class="v5chart" width="960" height="500"></svg>
<style>
/*Rectangle bar class styling*/
.bar {
fill: #0080FF
}
.bar:hover {
fill: #003366
}
/*Text class styling*/
.text {
fill: white;
font-family: sans-serif
}
</style>
<script>
////VERTICAL BAR CHART WITH SVG AND NAMES
// Create data array of values to visualize
var dataArray = [{ "Player": "John Doe", "Points": 23 }, { "Player": "Jane Doe", "Points": 13 }, { "Player": "Mary Jane", "Points": 21 }, { "Player": "Debasis Das", "Points": 14 }, { "Player": "Nishant", "Points": 37 }, { "Player": "Mark", "Points": 15 }, { "Player": "Andrew", "Points": 18 }, { "Player": "Simon", "Points": 34 }, { "Player": "Lisa", "Points": 30 }, { "Player": "Marga", "Points": 20 }];
// Create variable for the SVG
var canvas = d3.select(".v5chart1").append("g").attr("transform", "translate(20,30)");
var canvasWidth = 500;
var maxValue = d3.max(dataArray, function (d) { return d.Points; });
var canvasHeight = maxValue*10;
var heightScale = d3.scaleLinear()
.domain([0, d3.max(dataArray, function (d) { return d.Points; })])
.range([canvasHeight, 0]); //use max value (37) * 10
var y_axis = d3.axisLeft()
.scale(heightScale);
var x = d3.scaleBand()
.rangeRound([0, canvasWidth], .1);
x.domain(dataArray.map(function (d) { return d.Player; }));
var x_Axis = d3.axisBottom(x);
// Select, append to SVG, and add attributes to rectangles for bar chart
canvas.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("class", "bar")
.attr("height", function (d, i) { return (d.Points * 10) })
.attr("width", canvasWidth/dataArray.length)
.attr("x", function (d, i) { return (i * (canvasWidth / dataArray.length)) })
.attr("y", function (d, i) { return canvasHeight - (d.Points * 10) });
// Select, append to SVG, and add attributes to text
canvas.selectAll("text")
.data(dataArray)
.enter().append("text")
.text(function (d) { return d.Points })
.attr("class", "text")
.attr("x", function (d, i) { return (i * (canvasWidth / dataArray.length)) + (canvasWidth / dataArray.length)/2 })
.attr("y", function (d, i) { return canvasHeight + 20 - (d.Points * 10) });
canvas.append("g")
.attr("transform", "translate(0,0)")
.call(y_axis);
canvas.append("g")
.attr("transform", "translate(0," + canvasHeight + ")")
.call(x_Axis)
.selectAll("text")
.attr("x",40)
.attr("transform", function (d) {
return "rotate(65)"
});
</script>
我已经检查过这里:https://www.d3-graph-gallery.com/graph/custom_axis.html
您应该已经正确阅读了您提供的 link 中的 scaleBand
示例:
scaleBand
提供了一种方便的bandwidth()
方法来为您提供每个柱的宽度d3js
中的 od axis 的想法是您不需要自己进行计算,因此在您的情况下,您只需将玩家名称传递给x
函数即可坐标计算给你。- 同样适用于
y
计算,但我把这个留给你自己弄清楚,一点也不难。 - 关于
scaleBand
的另一个小事,你使用的是rangeRound()
方法,我不熟悉,但是如果你使用range()
方法结合padding()
正如您 link 编辑的示例,然后通过调整填充值,您可以控制栏的宽度,而不会影响 x 轴。值越高,条形越细,条形之间的 space 越多。
////VERTICAL BAR CHART WITH SVG AND NAMES
// Create data array of values to visualize
var dataArray = [{ "Player": "John Doe", "Points": 23 }, { "Player": "Jane Doe", "Points": 13 }, { "Player": "Mary Jane", "Points": 21 }, { "Player": "Debasis Das", "Points": 14 }, { "Player": "Nishant", "Points": 37 }, { "Player": "Mark", "Points": 15 }, { "Player": "Andrew", "Points": 18 }, { "Player": "Simon", "Points": 34 }, { "Player": "Lisa", "Points": 30 }, { "Player": "Marga", "Points": 20 }];
// Create variable for the SVG
var canvas = d3.select(".v5chart").append("g").attr("transform", "translate(20,30)");
var canvasWidth = 500;
var maxValue = d3.max(dataArray, function (d) { return d.Points; });
var heightScale = d3.scaleLinear()
.domain([0, d3.max(dataArray, function (d) { return d.Points; })])
.range([maxValue * 10, 0]); //use max value (37) * 10
var y_axis = d3.axisLeft()
.scale(heightScale);
var x = d3.scaleBand()
.range([0, canvasWidth]).padding([0.1]);
x.domain(dataArray.map(function (d) { return d.Player; }));
var x_Axis = d3.axisBottom(x);
// Select, append to SVG, and add attributes to rectangles for bar chart
canvas.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("class", "bar")
.attr("height", function (d, i) { return (d.Points * 10) })
.attr("width", x.bandwidth())
.attr("x", function (d, i) { return x(d.Player); })
.attr("y", function (d, i) { return 370 - (d.Points * 10) });
// Select, append to SVG, and add attributes to text
canvas.selectAll("text")
.data(dataArray)
.enter().append("text")
.text(function (d) { return d.Points })
.attr("class", "text")
.attr("text-anchor", "middle")
.attr("x", function (d, i) { return x(d.Player)+x.bandwidth()/2; })
.attr("y", function (d, i) { return 390 - (d.Points * 10) });
canvas.append("g")
.attr("transform", "translate(0,0)")
.call(y_axis);
canvas.append("g")
.attr("transform", "translate(0,370)")
.call(x_Axis);
.bar {
fill: #0080FF
}
.bar:hover {
fill: #003366
}
/*Text class styling*/
.text {
fill: white;
font-family: sans-serif
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg class="v5chart" width="960" height="500"></svg>