最近接到一個需求,在滿足規則下,實現類似這種展示效果,其實就是用圖形反映數據(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
<svg className="barChart1" ></svg>
1.繪制圖形
print = () => { const colors = [ '#eeeeee', '#eeeeee', '#eeeeee', '#eeeeee', '#eeeeee', '#eeeeee', '#eeeeee', '#eeeeee', '#eeeeee', '#eeeeee', ] // 定義svg圖形寬高,以及柱狀圖間距 const svgWidth = 7 * colors.length const svgHeight = 20 const 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); } }
