D3图表Y轴反转后柱状图高度异常问题求助
Hey there, let's fix that bar chart Y-axis and bar rendering issue in your Ember app! The problem comes from mismatched scale settings and bar position calculations when you reverse the Y-axis range. Here's how to adjust your code step by step:
Step 1: Correct the Y Scale Configuration
First, we need to set up the Y scale so that 0 sits at the bottom (standard for bar charts) and the maximum value stays at the top. We'll reverse the range and adjust the domain to match this expected behavior:
// Y scale & axes let yScale = scaleLinear().range([ barsHeight, 0 ]); // Reverse the range here this.set('yScale', yScale); this.set('yAxis', axisLeft(yScale)); this.set('yAxisContainer', svg.append('g') .attr('class', 'axis axis--y') .attr('transform', `translate(${padding.left}, ${padding.top})`) ); // Update the scales on chart render const maxCount = Math.max(...counts); this.get('yScale').domain([ 0, maxCount ]); // Domain now goes from 0 to the maximum value
Step 2: Fix Bar Position and Height Calculations
When we reverse the Y scale range, the way we calculate the bar's y position and height needs to shift to align with the new scale logic. Here's the updated bar rendering code:
// drawing the bars barsEnter .merge(barsUpdate) .transition() .attr('width', `${this.get('xScale').bandwidth()}px`) .attr('height', data => `${this.get('barsHeight') - this.get('yScale')(data.count)}px`) // Height = bottom of bar area minus bar's top position .attr('x', data => `${this.get('xScale')(data.label)}px`) .attr('y', data => `${this.get('yScale')(data.count)}px`) // Use the scale directly to position the bar's top edge .attr('fill', data => this.get('colorScale')(data.count)) .attr('opacity', data => { let selected = this.get('selectedLabel'); return (selected && data.label !== selected) ? '0.5' : '1.0'; });
Why This Works
- Setting
yScale.range([barsHeight, 0])tells D3 that the smallest domain value (0) maps to the bottom of the bar area, while the largest value maps to the top—this fixes the inverted Y-axis problem. - The bar's
yattribute usesyScale(data.count)directly, placing the top of the bar exactly where it should be based on the count value. - The bar's height is calculated as
barsHeight - yScale(data.count), which gives the exact distance from the bar's top edge to the bottom of the bar area, ensuring bars render at the correct size for their values.
This should resolve both the inverted Y-axis and distorted bar rendering in your Ember component!
内容的提问来源于stack exchange,提问作者Sorvah

