D3.js 序数刻度轴未对齐
D3.js Ordinal Scale Axis mis alignment
我有一个简单的 d3
条形图(参见 fiddle)。它说明了分数的计数。本质上是一个正态分布图。 x 轴是从 0 到 2 的分数的有序尺度。
我的 x 轴与相应的条不对齐。
如果您在创建画笔范围并单击条形图时查看 JS 控制台,则所选条形图与轴标签不匹配。
标签似乎与条形负偏移。
我做错了什么?
function drawChart (data) {
// Setup Crossfilter dimensions and groups
var nation = crossfilter(data),
byScr = nation.dimension(function(d){ return d.score; }),
byScrGrp = byScr.group().reduceCount(),
byHosp = nation.dimension(function(d){ return d.FIPS; });
// Histogram X-Axis ordinal scale
var x = d3.scale.ordinal()
.domain(d3.range(0,2,0.1))
.rangeBands([0, width, 0.5, 0.5 ]);
var brushScale = d3.scale.linear()
.domain([0,2])
.range([0, width]);
// Histogram Y-Axis linear scale
var y = d3.scale.linear()
.domain([0, d3.max(byScrGrp.all(), function(d){ return d.value; })])
.range([height/2, 0]);
// SVG Brush control object
var brush = d3.svg.brush()
.x(brushScale)
.on("brushstart", brushstart)
.on("brush", brushmove)
.on("brushend", brushend)
// Histogram SVG containiner
var svg = d3.select("#histogram").append("svg:svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height/2 + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Histogram bars
svg.selectAll("rect")
.data(byScrGrp.all())
.enter().append("rect")
.attr("x", function(d,i){ return i * (width / byScrGrp.size() ); })
.attr("width", width / byScrGrp.size() - barPadding )
.attr("y", function(d){ return y(d.value) ; })
.attr("height", function(d){ return ((height/2) -y(d.value)); })
.attr("fill", function(d){ return color(d.key); }) .on("mouseover", function(d){ d3.select(this).attr("fill", "teal"); console.log(d.key); })
.on("mouseout", function(d) { d3.select(this).attr("fill", function(d){return color(d.key);}) } );
// Histogram X Axis Object
var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(10);
// X Axis
svg.append("g")
.attr("class", "axis")
.call(xAxis)
.attr("transform", "translate(0, " + height/2 + ")") ;
// X Axis Label
svg.append("text")
.attr("transform", "translate(" + (width/2) + " ," + (height/2 + margin.bottom) + ")")
.attr("text-anchor", "middle")
.text("MSPB Score");
// Histogram Y Axis Object
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(10);
// Add Y Axis
svg.append("g")
.attr("class", "axis")
.call(yAxis)
.attr("transform", "translate(" + margin.left + ",0)");
// Add Y Axis Label
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - 10)
.attr("x", 0 - (height/4))
.attr("text-anchor", "middle")
.text("Number of Hospitals");
var brushg = svg.append("g")
.attr("class", "brush")
.call(brush)
brushg.select('.background')
.attr('width', width);
brushg.selectAll("rect")
.attr("height", height/2);
function brushstart() {
svg.classed("selecting", true);
}
function brushmove() {
var s = brush.extent();
brushg.classed("selected", function(d) { return s[0] <= (d = x(d)) && d <= s[1]; });
}
function brushend() {
if (!d3.event.sourceEvent) return;
d3.select(this).transition()
.call(brush.extent(brush.extent().map(function(d){return d3.round(d,2); })));
var extent = brush.extent(); console.log(extent);
}
}
我从来没有弄清楚这里到底发生了什么,但丑陋的技巧是手动将轴向左移动 35 像素。
.attr("transform", "translate(-35" + height + ")");
从视觉上看,这是可以接受的,但感觉并不是对问题的解释。
我有一个简单的 d3
条形图(参见 fiddle)。它说明了分数的计数。本质上是一个正态分布图。 x 轴是从 0 到 2 的分数的有序尺度。
我的 x 轴与相应的条不对齐。
如果您在创建画笔范围并单击条形图时查看 JS 控制台,则所选条形图与轴标签不匹配。
标签似乎与条形负偏移。
我做错了什么?
function drawChart (data) {
// Setup Crossfilter dimensions and groups
var nation = crossfilter(data),
byScr = nation.dimension(function(d){ return d.score; }),
byScrGrp = byScr.group().reduceCount(),
byHosp = nation.dimension(function(d){ return d.FIPS; });
// Histogram X-Axis ordinal scale
var x = d3.scale.ordinal()
.domain(d3.range(0,2,0.1))
.rangeBands([0, width, 0.5, 0.5 ]);
var brushScale = d3.scale.linear()
.domain([0,2])
.range([0, width]);
// Histogram Y-Axis linear scale
var y = d3.scale.linear()
.domain([0, d3.max(byScrGrp.all(), function(d){ return d.value; })])
.range([height/2, 0]);
// SVG Brush control object
var brush = d3.svg.brush()
.x(brushScale)
.on("brushstart", brushstart)
.on("brush", brushmove)
.on("brushend", brushend)
// Histogram SVG containiner
var svg = d3.select("#histogram").append("svg:svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height/2 + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Histogram bars
svg.selectAll("rect")
.data(byScrGrp.all())
.enter().append("rect")
.attr("x", function(d,i){ return i * (width / byScrGrp.size() ); })
.attr("width", width / byScrGrp.size() - barPadding )
.attr("y", function(d){ return y(d.value) ; })
.attr("height", function(d){ return ((height/2) -y(d.value)); })
.attr("fill", function(d){ return color(d.key); }) .on("mouseover", function(d){ d3.select(this).attr("fill", "teal"); console.log(d.key); })
.on("mouseout", function(d) { d3.select(this).attr("fill", function(d){return color(d.key);}) } );
// Histogram X Axis Object
var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(10);
// X Axis
svg.append("g")
.attr("class", "axis")
.call(xAxis)
.attr("transform", "translate(0, " + height/2 + ")") ;
// X Axis Label
svg.append("text")
.attr("transform", "translate(" + (width/2) + " ," + (height/2 + margin.bottom) + ")")
.attr("text-anchor", "middle")
.text("MSPB Score");
// Histogram Y Axis Object
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(10);
// Add Y Axis
svg.append("g")
.attr("class", "axis")
.call(yAxis)
.attr("transform", "translate(" + margin.left + ",0)");
// Add Y Axis Label
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - 10)
.attr("x", 0 - (height/4))
.attr("text-anchor", "middle")
.text("Number of Hospitals");
var brushg = svg.append("g")
.attr("class", "brush")
.call(brush)
brushg.select('.background')
.attr('width', width);
brushg.selectAll("rect")
.attr("height", height/2);
function brushstart() {
svg.classed("selecting", true);
}
function brushmove() {
var s = brush.extent();
brushg.classed("selected", function(d) { return s[0] <= (d = x(d)) && d <= s[1]; });
}
function brushend() {
if (!d3.event.sourceEvent) return;
d3.select(this).transition()
.call(brush.extent(brush.extent().map(function(d){return d3.round(d,2); })));
var extent = brush.extent(); console.log(extent);
}
}
我从来没有弄清楚这里到底发生了什么,但丑陋的技巧是手动将轴向左移动 35 像素。
.attr("transform", "translate(-35" + height + ")");
从视觉上看,这是可以接受的,但感觉并不是对问题的解释。