最近接到一个需求,在满足规则下,实现类似这种展示效果,其实就是用图形反映数据(NK,一种干扰值)
运行后,它其实是不断在动的,每格都可能显示灰色或者彩色
这里一共是10个格子,每格代表一个范围边界,说明如下
规则:颜色条設定,共十格 N = 1 - 10,边界值 max value = 2^(N/2) 并取小数点第一位进行四舍五入,得到一组边界值:1/2/3/4/6/8/11/16/23/32,最后一格沒有上限=24~无限大
即是說,数值等于或大于24,到无限大,属于第十級(格)。另外,达到的格显示彩色,未达到的显示灰色
这里要解决2个问题
1.绘制图形
2.动态更新
技术栈:React+d3 v4
1.绘制图形
print = () =>{
const colors=[‘#eeeeee‘,‘#eeeeee‘,‘#eeeeee‘,‘#eeeeee‘,‘#eeeeee‘,‘#eeeeee‘,‘#eeeeee‘,‘#eeeeee‘,‘#eeeeee‘,‘#eeeeee‘,
]//定义svg图形宽高,以及柱状图间距
const svgWidth = 7 *colors.length
const svgHeight= 20const barPadding= 2
//通过图形计算每个柱状宽度
const barWidth = (svgWidth /colors.length)
const svg= d3.select(‘.barChart1‘)
.attr(‘width‘, svgWidth)
.attr(‘height‘, svgHeight)
const barChart= svg.selectAll(‘rect‘)
.data(colors)//绑定数组
.enter() //指定选择集的enter部分
.append(‘rect‘) //添加足够数量的矩形
.attr(‘y‘, d => 0) //d为数据集每一项的值, 取y坐标
.attr(‘height‘, 20) //设定高度
.attr(‘width‘, barWidth - barPadding) //设定宽度
.attr(‘transform‘, (d, i) =>{
const translate= [barWidth * i, 0];return`translate(${translate})`
})//实际是计算每一项值的x坐标
.style(‘fill‘, (d, i) =>d)
}
2.动态更新
update = nkNum =>{
const colors=[‘#40cc80‘,‘#40cc80‘,‘#40cc80‘,‘#40cc80‘,‘#FFFF00‘,‘#FFFF00‘,‘#FFFF00‘,‘#f64b5d‘,‘#f64b5d‘,‘#f64b5d‘,
]
console.log(nkNum,"nkNum")//NK顏色橫條設定,共十格 N = 1-10,max value = 2^(N/2) round to first digit,1/2/3/4/6/8/11/16/23/32,最後一格沒有上限=24~無限
//即是說,數值等於或大於24,到無限大,屬第十級
//没达到的,用#eeeeee表示,达到的用彩色表示
colors.map((t, i)=>{if (nkNum < Math.round(Math.pow(2, (i + 1) / 2))) {
colors[i]= ‘#eeeeee‘}
})
const svg= d3.select(‘.barChart1‘)
const barChart=svg
.selectAll(‘rect‘)
.data(colors)
.style(‘fill‘, (d, i) =>d)
}
值得注意的是,这里我巧妙的利用了循环的索引来计算那一组数 1/2/3/4/6/8/11/16/23/32
Math.round(Math.pow(2, (i + 1) / 2)
3.调用
componentDidMount() {this.print();
}
componentDidUpdate(prevProps, prevState) {
const {
home: { nkNum },
}= this.props;
const {
home: { nkNum: nkNumOld },
}=prevProps;if (nkNum !==nkNumOld) {this.update(nkNum);
}
}