问题
I have the following code for a d3 bar chart from csv with header. I have removed code to mention only the relevant parts. I am using d3 v5.
data.csv:
Plan, TotalTime, Time1, Time2
A, 0.07, 0.04, 0.03
B, 0.08, 0.02, 0.06
index.js
d3.csv("data.csv", d3.autoType).then(function(data) {
x.domain(data.map(function(d) { return d.Plan; }));
y.domain([0, d3.max(data, function(d) { return d.TotalTime; })]);
g.selectAll(.bar)
.data(data)
.enter().append("rect")
.attr("class", "TotalBar")
.attr("x", function (d) { return x(d.Plan) ;})
.attr("y", function (d) { return y(d.TotalTime) ;})
.attr("height", function (d) { return height - y(d.TotalTime) ;})
Similar code for Time1 and Time2 columns
});
I am going to have the scenario where there won't be any headers. The 1st column and 2nd column will always be Plan and TotalTime respectively. In addition the number of Time columns will be varying. In this case, how to set the axes domain? I have the following code
data.csv
A, 0.08, 0.04, 0.03, 0.01
B, 0.09, 0.02, 0.06, 0.01
index.js
d3.text("data.csv").then(function(data) {
var rows = d3.csvParseRows(data, d3.autoType);
columnCount = rows[0].length;
x.domain(data.map(function(d) { return ??; }));
y.domain([0, d3.max(data, function(d) { return ??; })]);
for (var col=0; col<columnCount; ++Col) {
g.selectAll(.bar)
.data(data)
.enter().append("rect")
.attr("class", "Bar"+col)
.attr("x", function (d) { return x(??); })
.attr("y", function (d) { return y(??); })
.attr("height", function (d) { return height - y(??); })
}
});
回答1:
You have two different solutions:
The first one is using the indices of each column. In your case, Plan is 0 and totalTime is 1:
const csv = `A,0.08,0.04,0.03,0.01
B,0.09,0.02,0.06,0.01`;
const data = d3.csvParseRows(csv);
const xDomain = data.map(function(d) {
return d[0];
});
const yDomain = [0, d3.max(data, function(d) {
return d[1];
})];
console.log(xDomain)
console.log(yDomain)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Another solution is using a row conversion function to change the data, making it an array of objects, just like in your first snippet:
const csv = `A,0.08,0.04,0.03,0.01
B,0.09,0.02,0.06,0.01`;
const data = d3.csvParseRows(csv, function(d) {
return {
Plan: d[0],
totalTime: d[1]
}
});
console.log(data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Then, you can use your original code. In the row function, return the other columns as needed.
Finally, as a tip: get rid of that for loop. In a D3 code, avoid using loops for appending elements.
来源:https://stackoverflow.com/questions/59721635/bar-chart-set-axis-domain-from-csv-without-header