我想制作一个在大屏幕上将x timescale(tick?)划分为一个月(31天)或在小屏幕上划分为1周(7天)的时间轴。 我希望它集中在视图中心的月末。
这种运球设计是我想以某种方式实现的。
我从这里https://github.com/d3/d3-zoom/issues/57#issuecomment-246434951
复制一些代码但仍然无法使刻度线平均适应屏幕大小
这是我到目前为止所得到的。
import d3 from 'd3'
import moment from 'moment'
window.d3 = d3
export default (container, dataset, options) => {
const containerWidth = container.getBoundingClientRect().width
const containerHeight = container.getBoundingClientRect().height
const timelineHeight = 4
const {
startAt,
endAt,
} = options
const svg = d3.select(container)
.style('position', 'relative')
.append('svg')
.style('width', '100%')
.style('height', containerHeight)
.style('position', 'absolute')
.append('g')
const svgContainer = d3.select(svg.node().parentNode)
const timeScale = d3.scaleTime()
.domain([startAt, endAt])
.range([0, containerWidth])
// .rangeRound([20, containerWidth - 20])
.nice(d3.timeDay)
const guideline = d3
.axisBottom(timeScale)
// .ticks(d3.timeDay)
// .tickSize(containerHeight)
const xAxis = d3
.axisBottom(timeScale)
.ticks(d3.timeDay)
.tickSize(0)
.tickFormat(d3.timeFormat('%Y.%_m.%_d'))
const xScaleGroup = svg
.append('g')
.attr('class', 'xscale-group')
// const guidelineGroup = xScaleGroup
// .append('g')
// .attr('class', 'guideline-group')
// .call(guideline)
const xAxisGroup = xScaleGroup
.append('g')
.attr('class', 'xaxis-group')
.call(xAxis)
const timelineGroup = xScaleGroup
.append('g')
.attr('class', 'timeline-group')
.style('transform', 'translateY(32px)')
const timelineBgGroup = timelineGroup
.append('g')
.attr('class', 'timeline-bg-group')
const timelineBgRect = timelineBgGroup
.append('rect')
.attr('width', containerWidth)
.attr('height', timelineHeight)
.attr('fill', 'red')
const eventGroup = timelineGroup
.selectAll('.event-group')
.data(dataset)
.enter()
.append('g')
.attr('id', (d, i) => 'event-group-' + i)
.attr('class', 'event-group')
.style('transform', d => `translate(${timeScale(d.startAt)}px, 0px)`)
const eventCircle = eventGroup
.append('circle')
.attr('r', 16)
.attr('fill', ({ color }) => color)
.attr('stroke', 'white')
.attr('stroke-width', 2)
// .attr('filter', 'url(#circle-shadow)')
.attr('id', (d, i) => 'circle-' + i)
.each(function (d) {
d.circle = this
})
const zoom = d3.zoom()
// .scaleExtent([1, 32])
// .translateExtent([[0, 0], [containerWidth, containerHeight]])
// .extent([[0, 0], [containerWidth, containerHeight]])
.on('zoom', onZoom)
svgContainer
.call(zoom)
.on('dblclick.zoom', null)
const now = new Date()
const startOf = moment().startOf('month').toDate()
const endOf = moment().endOf('month').toDate()
var k = containerWidth / (timeScale(endOf) - timeScale(startOf))
var tx = containerWidth / 2 - k * timeScale(now)
// var tx = -timeScale(startOf)
var t = d3.zoomIdentity.translate(tx, 0).scale(k)
svgContainer.call(zoom.transform, t)
function onZoom() {
const t = d3.event.transform, xt = t.rescaleX(timeScale)
xAxisGroup.call(xAxis.scale(xt))
// guidelineGroup.call(guideline.scale(xt))
eventGroup.style('transform', ({ startAt }) => `translateX(${xt(startAt)}px)`)
}
}
我想从2019.4.1开始