问题:我试图创建一个可平移/可zoom 的线性X轴,每个整数上的刻度从0到预定义的大数字(比如1000,但可能更高).很明显,这些内容不能全部显示在屏幕上,也不能完全可读,所以我需要将其移出屏幕并可平移.从0到10开始是可以接受的.到目前为止,我的解决方案有很多问题,但第一个问题是,如果我放大,D3会自动在小数点处的整数之间添加刻度,以继续在屏幕上显示10个刻度.第二个是当我缩小时,显示范围将超过1000.
请注意:将显示的数据与此无关.轴必须从0到1000,无论1000上是否有数据点,因此我无法根据数据集确定域.
我try 过的解决方案:
- .ticks().这让我可以指定所需的刻度数.然而,这似乎将所有刻度置于指定的初始范围内.如果我将范围的宽度增加到svg大小之外,它会分散刻度,但不是以任何可控的方式(据我所知).此外,我还遇到了性能问题,其中平移和zoom .我觉得这种行为很奇怪,因为如果我不指定滴答声,它会产生一个无限数,我可以毫无延迟地平移.我assume延迟发生,因为它试图立即呈现所有assume0个滴答声和默认的d3.js功能在滚动时动态呈现它们.这似乎是一个潜在的解决方案,但我不确定如何执行它.
- .tickValues().我可以提供一个从0到1000的数组,这是可行的,但表现出与之完全相同的滞后行为.滴答声().当我缩小时,这也不会动态地将刻度组合成10或100.
- .tickFormat().我可以通过运行一个函数,将任何非整数转换为空字符串.然而,这仍然留下了刻度线.
下面是我使用最新版本D3的代码的相关部分.js(7.3):
const height = 500
const width = 1200
const margin = {
top: 20,
right: 20,
bottom: 20,
left: 35
}
const innerWidth = width - margin.left - margin.right
const innerHeight = height - margin.top - margin.bottom
const xScale = d3.scaleLinear()
.domain([0, 10])
.range([0, innerWidth])
const svg = d3.select('svg')
.attr("width", width)
.attr("height", height)
svg.append('defs').append('clipPath')
.attr('id', 'clip')
.append('rect')
.attr('width', innerWidth)
.attr('height', innerHeight)
const zoom = d3.zoom()
.scaleExtent([1, 8])
.translateExtent([
[0, 0],
[xScale(upperBound), 0]
])
.on('zoom', zoomed)
const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
const xAxis = d3.axisBottom()
.scale(xScale)
const xAxisG = g.append('g')
.style('clip-path', 'url(#clip)')
.attr("class", "x-axis")
.call(xAxis)
.attr('transform', `translate(0, ${innerHeight})`)
svg.call(zoom)
function zoomed(event) {
const updateX = event.transform.rescaleX(xScale)
const zx = xAxis.scale(updateX)
xAxisG.call(zx)
}