我曾尝试在D3中实现条形图,但我的轴上的映射存在问题。我有一个x和y的数据集,但似乎我的值没有正确映射。
这是代码:
var data = [
{x: 2, y: 4},
{x: 5, y: 8},
{x: 8, y: 10},
{x: 2, y: 4},
{x: 5, y: 8},
{x: 8, y: 19},
{x: 2, y: 4},
{x: 5, y: 8},
{x: 8, y: 10},
{x: 2, y: 4},
{x: 5, y: 8},
{x: 8, y: 10},
{x: 2, y: 4},
{x: 5, y: 8},
{x: 8, y: 10},
{x: 2, y: 4},
{x: 3, y: 8},
{x: 8, y: 10},
{x: 24, y: 4},
{x: 15, y: 8},
{x: 18, y: 10}
];
var margin = {top: 20, right: 30, bottom: 30, left: 40},
w = 1000 - margin.left - margin.right,
h = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, w]);
var y = d3.scale.linear()
.range([h, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
//.tickFormat(d3.format("%Y/%m"));
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var zoom = d3.behavior.zoom()
.scaleExtent([1, 1])
.x(x)
.on("zoom", zoomed);
var chart = d3.select("#testChart").append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(zoom);
var rect = chart.append("rect")
.attr("width", w)
.attr("height", h)
.style("fill", "none")
.style("pointer-events", "all");
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis)
chart.append("g")
.attr("class", "y axis")
.call(yAxis);
//data.forEach(function (d) {
//d.date = new Date("20" + d.yy + "/" + d.mm);
// coerce to number
//d.ppm_value = +d.ppm_value;
// d.date = format.parse(d.date);
//console.log(d.ppm_value);
// console.log(d.date);
//});
x.domain(data.map(function (d) {
console.log("HEelllppp!!!!",d.date);
return d.x;
}));
y.domain([0, d3.max(data, function (d) {
return d.y;
})]);
var bars = chart.append("g")
.attr("class", "chartobjects");
bars.selectAll(".rect")
.data(data)
.enter().append("rect")
.attr("class", "rectBar")
.on("click", hello)
.attr('x', function (d) {
console.log("Blaaannaaaaa!!!!!!",d.x);
return x(d.x);
})
.attr("y", function (d) {
return y(d.y);
})
.attr("height", function(d) { return h - y(d.y); })
.attr("width", 45)
.attr("fill", function(d){
return d.y > 6 ? "blue" : "red"});
function hello(){
alert("Hello world!!")
}
function zoomed() {
var tx = Math.max(0, d3.event.translate[0]);
//ty = Math.min(0, d3.event.translate[1]);
zoom.translate([tx]);
bars.attr("transform", "translate(" + [tx] + ")scale(" + d3.event.scale + ")");
chart.select(".x.axis")
.call(xAxis);
//chart.select(".y.axis")
// .call(yAxis);
}
也许你有一些想法为什么。我也会张贴一张图片:
答案 0 :(得分:1)
这里的解释必须使用dataviz原则而不是使用D3代码。
条形图与直方图不同,主要区别在于:在条形图中,每个条形代表定性变量(或分类变量) 。话虽这么说,你不应该为x轴使用线性刻度,而是使用序数刻度:
var x = d3.scale.ordinal()
.rangeBands([0, w]);
这是一个带有序数比例的演示:
var data = [{
x: 2,
y: 4
}, {
x: 5,
y: 8
}, {
x: 8,
y: 10
}, {
x: 2,
y: 4
}, {
x: 5,
y: 8
}, {
x: 8,
y: 19
}, {
x: 2,
y: 4
}, {
x: 5,
y: 8
}, {
x: 8,
y: 10
}, {
x: 2,
y: 4
}, {
x: 5,
y: 8
}, {
x: 8,
y: 10
}, {
x: 2,
y: 4
}, {
x: 5,
y: 8
}, {
x: 8,
y: 10
}, {
x: 2,
y: 4
}, {
x: 3,
y: 8
}, {
x: 8,
y: 10
}, {
x: 24,
y: 4
}, {
x: 15,
y: 8
}, {
x: 18,
y: 10
}];
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
w = 1000 - margin.left - margin.right,
h = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeBands([0, w], 0.6);
var y = d3.scale.linear()
.range([h, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
//.tickFormat(d3.format("%Y/%m"));
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var chart = d3.select("body").append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var rect = chart.append("rect")
.attr("width", w)
.attr("height", h)
.style("fill", "none")
.style("pointer-events", "all");
//data.forEach(function (d) {
//d.date = new Date("20" + d.yy + "/" + d.mm);
// coerce to number
//d.ppm_value = +d.ppm_value;
// d.date = format.parse(d.date);
//console.log(d.ppm_value);
// console.log(d.date);
//});
x.domain(data.map(function(d) {
return d.x;
}));
y.domain([0, d3.max(data, function(d) {
return d.y;
})]);
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis)
chart.append("g")
.attr("class", "y axis")
.call(yAxis);
var bars = chart.append("g")
.attr("class", "chartobjects");
bars.selectAll(".rect")
.data(data)
.enter().append("rect")
.attr("class", "rectBar")
.on("click", hello)
.attr('x', function(d) {
return x(d.x);
})
.attr("y", function(d) {
return y(d.y);
})
.attr("height", function(d) {
return h - y(d.y);
})
.attr("width", x.rangeBand())
.attr("fill", function(d) {
return d.y > 6 ? "blue" : "red"
});
function hello() {
alert("Hello world!!")
}
function zoomed() {
var tx = Math.max(0, d3.event.translate[0]);
//ty = Math.min(0, d3.event.translate[1]);
zoom.translate([tx]);
bars.attr("transform", "translate(" + [tx] + ")scale(" + d3.event.scale + ")");
chart.select(".x.axis")
.call(xAxis);
//chart.select(".y.axis")
// .call(yAxis);
}
.axis path,.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
但是,如果您想保持线性比例并根据数据集中的x
值定位条形,请不要使用map
,它会返回一个包含所有x
值的数组:只需将域设置为[minValue, maxValue]
,无论这些值是什么。