我正在使用d3.js创建一个2轴的图形网格。使用其颜色将根据数据值改变的单元格显示数据。一个简单的例子是可见here。该图表创建为svg图像。剪切数据区时遇到问题:缩放和平移时,数据与轴重叠。您可以在提供的示例中看到此信息,方法是单击图表内容并向上或向左拖动。
有人知道如何让数据在轴下消失吗?
以下是我用来创建图表的打字稿代码:
let cellSize = 49;
let borderSize = 5;
let margin = { top: 40, right: 40, bottom: 40, left: 40 };
function createChart() {
// Create test data
let count = 500;
let perLine = 50;
let markers = [];
for (let i = 0; i < count; i++) {
let id = i + 1;
let line = Math.floor(i / perLine) + 1;
let point = i % perLine + 1;
markers.push({id: id, line: line, point: point});
}
//---
let lineMin = d3.min(markers, (item) => item.line);
let lineMax = d3.max(markers, (item) => item.line);
let pointMin = d3.min(markers, (item) => item.point);
let pointMax = d3.max(markers, (item) => item.point);
let chart = document.querySelector('.chart');
let viewWidth = chart.clientWidth - 2;
let viewHeight = 400;
let chartWidth = cellSize * (pointMax - pointMin + 1);
let chartHeight = cellSize * (lineMax - lineMin + 1);
let point = d3.scale.linear()
.domain([pointMin, pointMax])
.range([cellSize / 2, chartWidth - cellSize / 2]);
let line = d3.scale.linear()
.domain([lineMin, lineMax])
.range([cellSize / 2, chartHeight - cellSize / 2]);
let pointAxis = d3.svg.axis()
.scale(point)
.tickSize(0)
.tickValues(d3.range(pointMin, pointMax + 1))
.orient('top');
let lineAxis = d3.svg.axis()
.scale(line)
.tickSize(0)
.tickValues(d3.range(lineMin, lineMax + 1))
.orient('left');
let zoom = d3.behavior.zoom()
.x(point)
.y(line)
.scaleExtent([0.1, 1])
.on('zoom', () => {
let width = Math.min(viewWidth - margin.left - margin.right, chartWidth);
let height = Math.min(viewHeight - margin.top - margin.bottom, chartHeight);
let t = zoom.translate();
let tx = Math.min(t[0], 0);
tx = Math.max(tx, width - chartWidth);
let ty = Math.min(t[1], 0);
ty = Math.max(ty, height - chartHeight);
zoom.translate([tx, ty]);
let scale = zoom.scale();
svg.select('.x.axis').call(pointAxis).selectAll('text')
.attr('x', -3)
.attr('y', 5)
.attr('transform', 'rotate(90)')
.style('text-anchor', 'end');
svg.select('.y.axis').call(lineAxis);
grid.attr('transform', `translate(${[tx, ty]})scale(${scale})`);
});
let svg = d3.select('.chart').append('svg')
.attr('id', 'svg')
.attr('width', viewWidth)
.attr('height', viewHeight)
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.call(zoom);
let grid = svg.append('g')
.attr('id', 'grid');
// Add the grid background
grid.append('rect')
.attr('class', 'grid')
.attr('x', 0)
.attr('y', 0)
.attr('width', chartWidth)
.attr('height', chartHeight);
// Create the cells
let cell = grid.selectAll('.cell')
.data(markers).enter()
.append('g')
.attr('id', (marker) => `cell${marker.line}-${marker.point}`)
.attr('class', 'cell')
.attr('transform', (marker) => `translate(${point(marker.point) - cellSize / 2}, ${line(marker.line) - cellSize / 2})`);
cell.append('rect')
.attr('class', 'border')
.attr('x', 0)
.attr('y', 0)
.attr('width', cellSize)
.attr('height', cellSize);
cell.append('rect')
.attr('class', (marker) => `fill valid`)
.attr('x', borderSize)
.attr('y', borderSize)
.attr('width', cellSize - 2 * borderSize)
.attr('height', cellSize - 2 * borderSize);
cell.append('rect')
.attr('class', 'selection')
.attr('x', 0)
.attr('y', 0)
.attr('width', cellSize)
.attr('height', cellSize);
// Add the axes
svg.append('g')
.attr('class', 'x axis')
.call(pointAxis)
.selectAll('text')
.attr('x', -3)
.attr('y', 5)
.attr('transform', 'rotate(90)')
.style('text-anchor', 'end');
svg.append('g')
.attr('class', 'y axis')
.call(lineAxis);
}
答案 0 :(得分:1)
如果你不需要实际使用clipPath
,你可以在添加轴之前为这样的x轴添加一个简单的bg。
// Add bg for x axis
svg.append('rect')
.attr('height', 30)
.attr('y', -25)
.attr('fill', 'white')
.attr('width', chartWidth);