我對d3很陌生。請您幫幫我,為什么在按下按鈕時生成新資料后我的圖表不重繪?它繪制一次,但在我按下按鈕后,它只會將新的資料陣列記錄到控制臺。我是否錯誤地洗掉了舊資料?
以防萬一我單獨匯入 d3 函式,這就是為什么寫它select而不是d3.select. 除了更新圖表外,一切正常。
先感謝您。這里有一個類似的問題,我嘗試以類似的方式做到這一點,但我不明白我做錯了什么。
const randomValue = randomInt(0, 100);
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sen', 'Oct', 'Nov', 'Dec'];
let data = months.map(m => ({
label: m,
value: randomValue()
}))
let values = data.map(m => m.value)
const yScale = scaleLinear().domain([0, 100]).range([0, height]);
const colorScale = scaleLinear().domain([0, 100]).range(['#d22626', '#086cdc']);
const $chartContainer = $root.append('g')
.classed('.mz-chart__container', true)
.attr('transform', `translate(${padding}, ${100})`);
const xScale = scaleBand().domain(months).range([0, width]).paddingInner(0.2);
const hAxis = axisBottom().scale(xScale);
$root.append("g")
.attr('transform', `translate(${padding}, ${height 100})`)
.call(hAxis);
const vAxisScale = scaleLinear().domain([0, 100]).range([height, 0]);
const vAxis = axisLeft()
.scale(vAxisScale)
.tickSize(-width, 0, 0)
.tickFormat((y, x) => y);
$root.append("g")
.attr("transform", "translate(40, 100)")
.call(vAxis);
function updateChart() {
data = months.map(m => ({
label: m,
value: randomValue()
}))
console.log(data);
let chartbars = $chartContainer.selectAll('.mz-chart__bar').data(data)
chartbars
.exit()
.remove()
chartbars
.enter()
.append('g')
.classed('mz-chart__bar', true)
.append('rect')
.attr('x', (d, i) => xScale(d.label))
.attr('y', (d, i) => height - yScale(d.value))
.attr('height', (d, i) => yScale(d.value))
.attr('width', (d, i) => xScale.bandwidth())
.attr('fill', d => colorScale(d.value));
}
select(".mz-button").on("click", updateChart)
updateChart()
uj5u.com熱心網友回復:
您有一個進入選擇和一個退出選擇,但您沒有使用 udpate 選擇。
selection.enter() 僅在所選元素少于資料陣列中的專案時創建元素:它用于創建所有元素以開始,因為不存在。輸入選擇不包含預先存在的元素,但它們位于更新選擇 ( chartbars) 中。
我們可以通過合并它們然后給它們設定樣式來強制現有的和新的條具有適當的屬性:
let newbars = chartbars
.enter()
.append('g')
.classed('mz-chart__bar', true)
.append('rect');
chartbars.select('rect').merge(newbars)
.attr('x', (d, i) => xScale(d.label))
.attr('y', (d, i) => height - yScale(d.value))
.attr('height', (d, i) => yScale(d.value))
.attr('width', (d, i) => xScale.bandwidth())
.attr('fill', d => colorScale(d.value));
例如:
顯示代碼片段
const randomValue = Math.random;
const height = 300;
const width = 500;
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sen', 'Oct', 'Nov', 'Dec'];
const $root = d3.select("body").append("svg").attr("width",width).attr("height",height);
const padding = {left: 50, right: 10, top: 40, bottom: 40}
let data = months.map(m => ({
label: m,
value: randomValue()
}))
let values = data.map(m => m.value)
const $chartContainer = $root.append("g")
.attr("transform", `translate(${padding.left},${padding.top} )`)
.classed('.mz-chart__container', true)
const plotWidth = width - padding.left - padding.right;
const plotHeight = height - padding.top - padding.bottom;
const yScale = d3.scaleLinear().domain([0, 100]).range([plotHeight,0]);
const xScale = d3.scaleBand().domain(months).range([0,plotWidth]).paddingInner(0.2);
const colorScale = d3.scaleLinear().domain([0, 100]).range(['#d22626', '#086cdc']);
const hAxis = d3.axisBottom().scale(xScale);
const vAxis = d3.axisLeft()
.scale(yScale)
.tickSize(-plotWidth, 0, 0)
.tickFormat((y, x) => y);
$chartContainer.append("g")
.attr('transform', `translate(0, ${plotHeight})`)
.call(hAxis);
$chartContainer.append("g")
.call(vAxis);
function updateChart() {
data = months.map(m => ({
label: m,
value: randomValue() * 100
}))
// console.log(data);
let chartbars = $chartContainer.selectAll('.mz-chart__bar').data(data)
chartbars
.exit()
.remove()
let newbars = chartbars
.enter()
.append('g')
.classed('mz-chart__bar', true)
.append('rect');
chartbars.select('rect').merge(newbars) // merge the update and enter selections
.attr('x', (d, i) => xScale(d.label))
.attr('y', (d, i) => plotHeight - yScale(d.value))
.attr('height', (d, i) => yScale(d.value))
.attr('width', (d, i) => xScale.bandwidth())
.attr('fill', d => colorScale(d.value));
}
d3.select("body").on("click", updateChart)
updateChart()
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
因為我們使用 enter().append() 添加了一個嵌套元素,但是我們選擇的是父g元素,所以我們需要使用 chartbars.select('rect') 為更新選擇中的每個元素選擇一個子矩形,然后將其合并使用 newbars(這是新添加的矩形的選擇)。
我已經在間距和大小方面重新撰寫了您的代碼 - 我也不確定,但我相信您希望紅色條更大(這需要在 y 比例范圍內切換值)。最后,我洗掉了多余的 y 刻度。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/480122.html
標籤:javascript d3.js 图形 数据科学
下一篇:物件陣列的d3.max
