I’m using d3.js to draw a Gantt chart, and I encountered an exception that puzzled me. The following is a function for drawing a Gantt chart (code not relevant to the problem is omitted). gantt-y-axis is an element that is fixed on the left and used to display the Y-axis information, while gantt-chart is an element that stores the specific information of the Gantt chart. yAxisG is an element of type g, and translate(0,0) is executed to make its left border equal to the left border of the parent element yAxisSvg, but the result is that the left border of yAxisG is to the left of the left border of yAxisSvg. Why is this?
ganttG also executes translate(0,0), but its left border is equal to the left border of the parent element ganttSvg, which is normal.
function drawGanttChart(entries) {
d3.select('#gantt-chart').selectAll('*').remove();
d3.select('#gantt-y-axis').selectAll('*').remove();
const yAxisSvg = d3.select('#gantt-y-axis').append('svg')
.attr('width', margin.left)
.attr('height', height);
const ganttSvg = d3.select('#gantt-chart').append('svg')
.attr('width', svgWidth)
.attr('height', height);
const yAxisG = yAxisSvg.append('g').attr('transform', `translate(0,0)`);
const ganttG = ganttSvg.append('g').attr('transform', `translate(0,0)`);
const x = d3.scaleTime()
.domain([startTimeExtent[0], endTimeExtent[1]])
.range([0, width]);
const y = d3.scaleBand()
.domain(uniqueResources)
.range([0, height - margin.top - margin.bottom])
.padding(0.2);
yAxisG.append('g')
.attr('class', 'axis axis--y')
.call(d3.axisLeft(y));
ganttG.append('g')
.attr('class', 'axis axis--x')
.attr('transform', `translate(0,0)`)
.call(d3.axisBottom(x)
.ticks(d3.timeMillisecond.every(100))
.tickFormat(customTimeFormat));
ganttG.selectAll('.bar')
.data(entries)
.enter().append('rect')
.attr('class', 'bar')
.attr('x', d => x(new Date(d['StartTime'])))
.attr('y', d => y(d['ResourceName']))
.attr('width', d => x(new Date(d['EndTime'])) - x(new Date(d['StartTime'])))
.attr('height', y.bandwidth())
}
#gantt-y-axis {
position: sticky;
left: 0;
background: white; /* 确保背景色与图表一致 */
z-index: 1;
font-family:sans-serif;
font-size: 10px;
}
#gantt-chart {
flex: 1 0 auto;
overflow-x: auto;
overflow-y: auto;
white-space: nowrap;
}
I had to set an offset to move yAxisG to the right so that yAxisG appears inside yAxisSvg. translate(offset,0),but this offset is hard to control.
D3.js Version:https://d3js.org/d3.v7.min.js
huang yuxuan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.