Благодаря обоим (@AndrewReid и @GerardoFurtado). Я учусь использовать D3 и иногда блокирую себя и не могу двигаться вперед. Я должен признать, что я многому учусь. Спасибо!
далэтот вопрос Несколько дней назад относительно порядка спарклайнов, когда пользователь решает изменить порядок данных. Ответ решил проблему, но остается правильное расположение красных кружков, которые выделяют место, где пользователь помещает мышь.
Это код:PLUNKER.
Я думал о том, как изменить код, чтобы изменить положение искровых кругов при изменении сортировки данных. Я не понял, где и как изменить код. Ниже я попытаюсь объяснить свои рассуждения, основываясь на пунктах кода, касающихся спарклайнов.
(1) Эти две строки кода определяют домен и диапазон для спарклайнов. Мне кажется, что их не следует менять при изменении порядка данных.
// domain and range for sparkline lines
var xSpark = d3.scaleLinear().domain([0, numYears-1]).range([0, sparkLength]);
var ySpark = d3.scaleLinear().domain([minYvalue, maxYvalue]).range([itemSize-2, 2]);
(2) Этот кусок кода выбирает элемент#data-svg-i
(гдеi
линия спарклайна), он добавляет круг, который помещает его вcx
, cy
которые зависят отxSpark
а такжеySpark
, Если упомянутый в пункте1 верно (то есть чтоxSpark
а такжеySpark
являются «фиксированными» значениями), то даже этот фрагмент кода не должен изменяться при изменении порядка данных.
var cells = svg.selectAll('.cell')
.data(data)
.enter()
.append('g')
.append('rect')
.on('mouseover', function(d, i) { // on mouseover rect
// get row, column and value of this rect
var idr = d3.select(this).attr('data-r'); // row
var idc = d3.select(this).attr('data-c'); // column
var value = d3.select(this).attr('data-value');
// highlight this rect
d3.select(this).style('stroke', 'red');
// add red dot to sparkline
d3.select('#data-svg-' + idr)
.append('circle')
.attr('r', 3) // radius
.style('stroke', 'red')
.style('fill', 'red')
.attr('cx', xSpark(idc))
.attr('cy', ySpark(value));
})
(3) Этот фрагмент кода также не нужно менять при изменении порядка данных.
line = d3.line()
.x(function(d, i) {
return xSpark(i);
})
.y(function(d) {
return ySpark(d);
})
.defined(function(d) { // for missing (0) data
return d !== 0;
});
(4) data
следует обновить, но пока это не так. Перед сортировкой,data
содержит данные в правильном порядке, в котором они отображаются, после заказа,data
пока не изменилось, должно?
pos
Я не думаю, что это должно быть изменено, ниcx
а такжеcy
потому что они зависят отxSpark
/ySpark
а такжеpos
.
var sparkSvg = d3.select('#sparkline')
.append('svg')
.on('mousemove', function() { // on mousemove svg sparkline canvas
var mouse = d3.mouse(this); // mouse position [x, y]
var r = d3.select(this).attr('data-r'); // number of line
var data = d3.select(this).select('path').data(); // array containing all the data values of that line
var element = document.getElementById('data-path-' + r); // get the right path
var pos = get_data_on_line(data, mouse);
d3.selectAll('.data-svg').selectAll('circle').remove(); // remove old circles
// add new circle
d3.select('#data-svg-' + r)
.append('circle')
.attr('r', 3)
.style('stroke', 'red')
.attr('fill', 'red')
.attr('cx', xSpark(pos[1]))
.attr('cy', ySpark(pos[0]));
})
Заключение
Короче говоря, я не понимаю, какой пункт кода должен быть изменен и как. Кто-нибудь знает, как мне помочь?
РЕДАКТИРОВАТЬ 1Ответ Марка решает проблему, когда пользователь наводит курсор на прямоугольник карты файла.
Но когда пользователь наводит курсор на спарклайны, красные круги не располагаются в правильном положении. Я надеюсь, что это изображение может прояснить, в чем проблема.
Я завис над спарклайном, связанным с Италией, и круг отображается не на линии, а над. Кроме того, данные, похоже, перепутаны.
РЕДАКТИРОВАТЬ 2Я проверяю кодВот (Обновленный код Марка). Я изменяю код, добавляя некоторыеconsole.log(d)
когда пользователь нажимает на метку строки и столбца:
var rowLabels = svg.append('g')
.attr('class', 'rowLabels')
.selectAll('.rowLabels')
.data(regionsName)
.enter().append('text')
.text(function(d) {
return d;
})
.attr('x', 0)
.attr('y', function(d, i) {
return i * cellSize;
})
.attr('transform', function(d, i) {
return 'translate(-3, 11)';
})
.attr('class', 'rowLabel mono')
.attr('id', function(d) {
return 'rowLabel_' + regionsName.indexOf(d);
})
.attr('label-r', function(d) {
return regionsName.indexOf(d);
})
.attr('font-weight', 'normal')
.style('text-anchor', 'end')
.on('click', function(d, i) {
console.log(d); // <-- ADDDED
rowSortOrder = !rowSortOrder;
sortByValues('r', i, rowSortOrder);
});
// year labels
var colLabels = svg.append('g')
.attr('class', 'colLabels')
.selectAll('.colLabels')
.data(yearsName)
.enter().append('text')
.text(function(d) {
return d;
})
.attr('transform', function(d, i) {
return 'translate(' + (i * cellSize) + ', 2) rotate(-65)';
})
.attr('class', 'colLabel mono')
.attr('id', function(d) {
return 'colLabel_' + yearsName.indexOf(d);
})
.attr('label-c', function(d) {
return yearsName.indexOf(d);
})
.attr('font-weight', 'normal')
.style('text-anchor', 'left')
.attr('dx', '.8em')
.attr('dy', '.5em')
.on('click', function(d, i) {
console.log(d); // <-- ADDDED
colSortOrder = !colSortOrder;
sortByValues('c', i, colSortOrder);
});
Пример ошибки: когда пользователь нажимает на Германию, затем на 2000, затем на 2002, затем на 2005, затем на 2003 и, наконец, на Италию, это результат:
Как вы можете видеть, спарклайны и тепловая карта не верны, потому что спарклайн связан сItaly
есть недостающие данные, которых на самом деле нет.
Я создал этот GIF-файл, показывающий, в чем проблема:
Первоначально у Германии есть два неизвестных значения (относящиеся к 2000 и 2001 годам). Соответствующий спарклайн правильный.
Когда вы нажимаете наGermany
данные сортируются в порядке убывания, а спарклайн по-прежнему верна.
Затем нажмите на год2002
и данные сортируются в порядке убывания, строки затем перемещаются в правильном порядке. И спарклайны верны.
Затем нажмите на2005
, данные отсортированы и спарклайны верны.
Затем нажмите на2003
и все снова верно.
Наконец нажмите наItaly
и график больше не верен. В Германии два недостающих данных, но из соответствующего спарклайна это не выделено. Вместо этого два недостающих данных находятся на спарклайне Италии.