【发布时间】:2021-01-09 23:14:04
【问题描述】:
我已经解决这个问题好几天了,但未能找到解决方案。我正在尝试为每一天制作新的 covid 病例图表,但是根据一年多的数据,我无法每天都有一个刻度线。不幸的是,到目前为止我尝试过的所有方法都不会限制 x 轴上的刻度数,结果非常难看。
就目前而言,这是我的 x 轴和刻度代码,我试图将刻度设置为每两个月一次。
const xAxis = d3.axisBottom(x)
.tickFormat(d3.timeFormat("%b"))
.ticks(d3.timeMonth.every(2))
但是,我也尝试通过执行以下操作将硬计数添加到滴答数:
const xAxis = d3.axisBottom(x)
.tickFormat(d3.timeFormat("%b"))
.ticks(5)
不幸的是,将人数添加到滴答数对我也不起作用。我还尝试移动我的代码以将刻度数限制在我调用 x 轴组的位置,如下所示:
yAxisGroup.call(yAxis)
.ticks(5)
谁能告诉我我在这里做错了什么?
我不确定它是否需要,但这里是整个组件的代码。整个项目都在做出反应。
import React, { Component } from 'react'
import * as d3 from 'd3'
export default class NewCasesGraph extends Component {
componentDidUpdate = () => {
let covidArray = Object.entries(this.props.data.cases);
for(let i = covidArray.length - 1; i > 1; i--){
let currentDay =parseInt(covidArray[i][1])
let previousDay =parseInt((covidArray[(i-1)][1]) || 0)
covidArray[i][1] = currentDay - previousDay
}
for(let j = 0; j <covidArray.length; j++){
covidArray[j][0] = new Date(covidArray[j][0])
}
// console.log(covidArray)
this.updateGraph(covidArray)
}
updateGraph(data){
// console.log('data: ', data)
// tweem
const widthTween = (d) => {
let i = d3.interpolate(0, x.bandwidth());
return function (t){
return i(t)
}
}
// dimensions
const dimensions = {
height: 500,
width: 1000
}
const margin = {top: 20, right: 20, bottom: 100, left: 100}
const svg = d3.select('.canvas')
.append('svg')
.attr('width', dimensions.width)
.attr('height',dimensions.height)
const graphWidth = dimensions.width -margin.left - margin.right
const graphHeight = dimensions.height - margin.top - margin.bottom
// create graph
const graph = svg.append('g')
.attr('width', graphWidth)
.attr('height', graphHeight)
.attr('transform', `translate(${margin.left}, ${margin.top})`)
const xAxisGroup = graph.append('g')
.attr('transform', `translate(0, ${graphHeight})`);
// set x axis text
xAxisGroup.selectAll('text')
.attr('transform', 'rotate(-40)')
.attr('text-anchor', 'end')
.attr('fill','grey')
const yAxisGroup = graph.append('g');
// create y scale
const y = d3.scaleLinear()
.range([ graphHeight, 0])
// cretae a band scale
const x = d3.scaleBand()
.range([0, graphWidth])
.paddingInner(0.2)
.paddingOuter(0.2)
// create the axae
const xAxis = d3.axisBottom(x)
.tickFormat(d3.timeFormat("%b"))
.ticks(d3.timeMonth.every(2))
const yAxis = d3.axisLeft(y)
.ticks(4)
.tickFormat(d => `${d.toLocaleString()} cases`);
const t = d3.transition().duration(750)
// join data to rects
const rects = graph.selectAll('rect')
.data(data)
// remove exit selection
rects.exit().remove();
// update any scales (domains)
y.domain([0,d3.max(data, d => d[1])]);
x.domain(data.map(item => item[0]));
// update current shapes in the dom
rects.attr('width', x.bandwidth)
.attr('fill', 'orange')
.attr('x', (d) => x(d[0]))
//handle enter selection
// append the enter section to the DOM
rects.enter()
.append('rect')
.attr('width', 0)
.attr('height',0)
.attr('y', graphHeight)
.attr('fill', '#5FA19E')
.attr('x', (d) => x(d[0]))
.merge(rects)
.transition(t)
.attrTween('width', widthTween)
.attr('y', (d) => {
return y(d[1])
})
.attr('height', d => graphHeight - y(d[1]));
// add mouseOver
// graph.selectAll('rect')
// .on('mouseover',(event, d) =>{
// })
// call axae
xAxisGroup.call(xAxis);
yAxisGroup.call(yAxis);
console.log(svg)
}
render() {
return (
<div>
<h2>New Cases Graph</h2>
<div className="canvas">
</div>
</div>
)
}
}
【问题讨论】:
标签: d3.js