Мне искренне не хочется задавать этот вопрос, тем более что я знаю, что его задавали десятки раз - и я прочитал посты.Но моя проблема остается - я просто не понимаю, как работает этот механизм.Я новичок в d3js и использую v3.x в метеоре;Я прошел учебные курсы и получил что-то работающее, но не могу обновить его новыми данными.Опять же, мои извинения за перефразировку этого, но ни один из других постов, которые я прочитал, не решил проблему.
Вот фрагмент кода, я убрал все вещи, которые не должны иметь никакого значениясосредоточиться на основной функциональности:
var w = 800;
var h = 800;
var intensity = 25;
var margin = {
top: 75,
right: 100,
bottom: 75,
left: 60
};
var svg = d3.select('#heatmap')
.append('svg')
.attr('width', w + margin.left + margin.right)
.attr('height', h + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// get csv data, x & y coords, etc...
createHeatmap = function(csv, x, y) {
var data = d3.csv.parseRows(csv).map(function(row) {
return row.map(function(d) {
return +d;
});
});
// set some values
var min = 0;
var max = d3.max(data, function(d, i) {
return i + 1;
});
var rectSize = 4;
// set the scales for both axes
...
// set up the axes
...
// define colorScale
...
// create heatmap
svg.selectAll('g')
.data(data)
.enter()
.append('g')
.selectAll('rect')
.data(function(d, i, j) {
return d;
})
.enter() // start drawing rects
.append('rect')
.attr('x', function(d, i, j) {
return (i * rectSize);
})
.attr('y', function(d, i, j) {
return (j * rectSize);
})
.attr('width', w / max)
.attr('height', h / max)
.style('fill', function(d, i, j) {
return colorScale(d * intensity);
});
// append axes, scales, labels, etc.
}
// create heatmap
createHeatmap(csv, x, y);
Моя проблема в том, что я не понимаю, почему диаграмма не обновляет тепловую карту, когда я передаю новые данные в createHeatmap ().
Iпошагово прошел в отладчике, и все работает так, как я ожидал во время первоначального создания тепловой карты, которая правильно отображает.Когда я отправляю новые данные, это когда начинается загадка.Отладчик показывает, что глубоко внутри самого d3js (не в моем коде), что enter () имеет массив с нулевыми значениями вместо данных, которые я передаю. Данные существуют до этой точки.Таким образом, поскольку d3js обрабатывает нулевые данные, он, естественно, возвращает пустой объект, поэтому обновление не происходит.
Очевидно, что я не делаю обновление правильно, но не знаю, что мне нужно сделать, чтобы исправить его.
Любой совет с благодарностью.
Спасибо!
Обновление: Андрей, спасибо за ответ.Я попробовал ваше первое предложение, изменив ваш пример, чтобы он соответствовал моим данным, но он не обновляется новыми данными.
Мои изменения:
var w = 800;
var h = 800;
var intensity = 25;
var margin = {
top: 75,
right: 100,
bottom: 75,
left: 60
};
var svg = d3.select('#heatmap')
.append('svg')
.attr('width', w + margin.left + margin.right)
.attr('height', h + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// get csv data, x & y coords, etc...
createHeatmap = function(csv, x, y) {
var data = d3.csv.parseRows(csv).map(function(row) {
return row.map(function(d) {
return +d;
});
});
// set some values
var min = 0;
var max = d3.max(data, function(d, i) {
return i + 1;
});
var rectSize = 4;
// set the scales for both axes
...
// set up the axes
...
// define colorScale
...
// append group of svg elements bound to data
var rows = svg.selectAll('g')
.data(data);
// enter new rows where needed
rows.enter().append('g');
// select all rects
var rects = rows.selectAll('rect')
.data(function(d, i, j) {
return d;
});
// enter new rects:
rects.enter().append('rect')
.attr('x', function(d, i, j) {
return (i * rectSize);
})
.attr('y', function(d, i, j) {
return (j * rectSize);
})
.attr('width', w / max)
.attr('height', h / max)
.style('fill', function(d, i, j) {
return colorScale(d * intensity);
});
Добавлен фрагмент:
var csv = "'3, 6, 0, 8'\n'1, 9, 0, 4'\n'3, 0, 1, 8'\n'4, 0, 2, 7";
csv = csv.replace(/'/g,'');
var button = d3.select('button')
.on('click', function() {
createHeatmap(update());
});
var w = 120;
var h = 120;
var intensity = 10;
var margin = {
top: 25,
right: 25,
bottom: 25,
left: 25
};
var svg = d3.select('#heatmap')
.append('svg')
.attr('width', w + margin.left + margin.right)
.attr('height', h + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
createHeatmap(csv);
function createHeatmap(csv) {
console.log(csv);
var data = d3.csv.parseRows(csv).map(function(row) {
return row.map(function(d) {
return +d;
});
});
var min = 0;
var max = d3.max(data, function(d, i) {
return i + 1;
});
var rectSize = 30;
// define a colorScale with domain and color range
var colorScale = d3.scale.linear()
.domain([0,0.5,1])
.range(['red', 'green', 'blue']);
// append group of svg elements bound to data
var rows = svg.selectAll('g')
.data(data);
// enter new rows where needed
rows.enter().append('g');
// select all rects
var rects = rows.selectAll('rect')
.data(function(d, i, j) {
return d;
});
// enter new rects:
rects.enter().append('rect')
.attr('x', function(d, i, j) {
return (i * rectSize);
})
.attr('y', function(d, i, j) {
return (j * rectSize);
})
.attr('width', w / max)
.attr('height', h / max)
.style('fill', function(d, i, j) {
return colorScale(d * intensity);
});
}
function update() {
var data = "'0, 1, 9, 5'\n'4, 0, 7, 2'\n'6, 3, 0, 8'\n'5, 3, 7, 0";
data = data.replace(/'/g,'');
return data;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<button>Update</button>
<div id="heatmap"></div>