D3.js 当用户更改数据的顺序时,将圆圈放置在迷你图上

D3.js 当用户更改数据的顺序时,将圆圈放置在迷你图上,d3.js,data-visualization,D3.js,Data Visualization,几天前,当用户选择更改数据的顺序时,我创建了一个关于小火花排序的程序。答案解决了问题,但仍然是红色圆圈的正确位置,该圆圈突出显示用户放置鼠标的位置 这是代码: 我考虑了如何更改代码,以便在数据排序更改时重新定位小圆圈。 我不知道在哪里以及如何更改代码。 下面我试图解释我的推理基于代码中关于火花线的要点 (1)这两行代码定义了火花线的域和范围。在我看来,当数据的顺序发生变化时,它们不应该被改变 // domain and range for sparkline lines var xSpark =

几天前,当用户选择更改数据的顺序时,我创建了一个关于小火花排序的程序。答案解决了问题,但仍然是红色圆圈的正确位置,该圆圈突出显示用户放置鼠标的位置

这是代码:

我考虑了如何更改代码,以便在数据排序更改时重新定位小圆圈。 我不知道在哪里以及如何更改代码。 下面我试图解释我的推理基于代码中关于火花线的要点

(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));
    })
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;
    });
(3)当数据顺序更改时,此代码也不需要更改

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));
    })
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)
数据应更新,但尚未更新。排序前,
数据
按正确的显示顺序包含数据,排序后,
数据
尚未更改,是否

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 Mark的回答解决了用户将鼠标悬停在filemap矩形上的问题

但是,当用户将鼠标悬停在闪烁线上时,红色圆圈的位置不正确。 我希望这张图片能澄清问题所在

我将鼠标悬停在与意大利有关的迷你图上,圆圈不显示在线条上,而是显示在上方。 此外,数据似乎混淆了

编辑2 我测试代码(Mark的更新代码)。 我修改了代码,在用户单击行和列标签时添加了一些
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);
    });
var rowLabels=svg.append('g'))
.attr('class','rowLabels')
.selectAll(“.rowLabels”)
.数据(区域名称)
.enter().append('text')
.文本(功能(d){
返回d;
})
.attr('x',0)
.attr('y',函数(d,i){
返回i*单元大小;
})
.attr('transform',函数(d,i){
返回“translate(-3,11)”;
})
.attr('class','rowLabel mono')
.attr('id',函数(d){
返回'rowLabel\'+regionsName.indexOf(d);
})
.attr('label-r',函数(d){
返回区域名称indexOf(d);
})
.attr('font-weight','normal')
.style('text-anchor','end')
.on('click',函数(d,i){

console.log(d);//这是一个新颖而简洁的可视化概念。如果我理解正确,无论排序如何,我们都需要在矩形和闪线、鼠标盖和工具提示之间完全对齐。对于我的答案,我将使用您首先链接到的plunkr(不是Mark的版本).如果我理解正确,那么有五个问题需要解决:

  • 垂直排序会删除鼠标上方使用的数据
  • 首先,在垂直排序svg小图标时,您正在分配新的基准-这些基准将覆盖路径的子基准,这就是为什么垂直排序后,鼠标悬停在小图标上时,鼠标悬停器不起作用(圆圈环绕每个svg的顶部)。请参阅此简化示例,例如:

    var div=d3.选择(“主体”).追加(“div”);
    div.append(“p”).datum(“hello”).text(函数(d){return d;});
    div.datum(“新数据”)。选择(“p”).text(函数(d){return d;});

    我看不到您的错误,或者我只是不明白?在您的“编辑1”问题上,我可以修复它,但我看不到与示例错误上的图片类似的未匹配错误,即使我单击了基于您的coordination@KEKUATAN谢谢Kekuatan的帮助。我用gif修改了主消息,希望能更好地澄清问题。哈哈,猜猜看什么!我在修同样的东西。不管怎样,很好+1@Shashank哈,上一次你确实赢了我,下一次我肯定你会赢的。但是,我今晚没空了,所以如果我打了一点什么也不用担心——尽管看看是否有其他答案被打出来会很好,但我已经打了十几次了@Andrewerid这是一个非常好的答案。我是回答OP之前关于垂直/水平排序的问题的人,我承认我没有为惯用的D3版本重构他们的代码……问题是,我在这里有一个个人规则:我通常只在不到5分钟的情况下写一个答案(除此之外,还应该支付咨询费!)这就是为什么我按照代码的思路回答了前面的问题,也就是说,没有为惯用D3进行重构,但已经知道将来会出现问题。这正是为什么你的答案如此好的原因。这都要感谢(@AndrewReid和@GerardoFurtado).我正在学习使用D3,有时我会阻碍自己前进。我必须承认我学到了很多。谢谢!