javascript - D3 : unable to access data within anonymous function

标签 javascript d3.js

我正在尝试根据本教程创建工具提示 http://chimera.labs.oreilly.com/books/1230000000345/ch10.html#_svg_element_tooltips 跳转至:HTML div 工具提示

不过我有一个问题。我无法将数据传递给匿名函数。请参阅在代码中在此处发表评论

<html>
<head>
    <title>Testing warehouse</title>
    <style>
    #tooltip {
        position: absolute;
        width: 200px;
        height: auto;
        padding: 10px;
        background-color: white;
        -webkit-border-radius: 10px;
        -moz-border-radius: 10px;
        border-radius: 10px;
        -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
        -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
        box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
        pointer-events: none;
    }

    #tooltip.hidden {
            display: none;
    }

    #tooltip p {
            margin: 0;
            font-family: sans-serif;
            font-size: 16px;
            line-height: 20px;
    }
    </style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
//NOTE:: x and y co-ordinates needs to be set on excel file.
//      width and height of rect needs to be set within functions returnheight and returnwidth

var width = 1500,
    height = 1500;

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var data    
d3.csv("AisleA.csv", function(d) {
  data = d;

    function returnwidth(bay)
    {
        //if odd bay then LS else Carton Flow. 
        //This fucntion keeps getting updated as we include other aisles and bays
        if(Number(bay) & 1)
        {
            // ODD
            return 40
        }
        else
        {
            // EVEN
            return 60
        }
    }

    function returnheight(bay)
    {
        if(Number(bay) & 1)
        {
            // ODD
            return 40
        }
        else
        {
            // EVEN
            return 60
        }
    }

    for(i = 0; i < data.length; i++)
    {
        svg.append("rect")
          .attr("x", data[i].x) 
          .attr("y", data[i].y)
          .attr("width", returnwidth(data[i].Bay))
          .attr("height", returnheight(data[i].Bay))
          .style("fill","green")    
          .style("stroke","black")
          .on("mouseover", function(d) {
            //Get this bar's x/y values, then augment for the tooltip
            var xPosition = parseFloat(d3.select(this).attr("x"))/2 //+ xScale.rangeBand() / 2;
            var yPosition = parseFloat(d3.select(this).attr("y")) / 2 //+ h / 2;
            console.log(data[i]) // ISSUE HERE. VALUE SHOWN AS UNDEFINED
            //Update the tooltip position and value
            d3.select("#tooltip")
              .style("left", xPosition + "px")
              .style("top", yPosition + "px")
              .select("#value")
              .text(data[i].PickRate); //ISSUE HERE

            //Show the tooltip
            d3.select("#tooltip").classed("hidden", false);

            })
           .on("mouseout", function() {
            //Hide the tooltip
            d3.select("#tooltip").classed("hidden", true);
            });                                                 
    }
});

</script>
<div id="tooltip" class="hidden">
        <p><strong>Important Label Heading</strong></p>
        <p><span id="value">100</span>%</p>
</div>
</body>
</html>

我需要在工具提示中显示的数据位于 data[i] 中。有人可以建议我如何访问这些数据并显示

CSV:

Aisle,Bay,PickRate,ReplenRate,x,y
A,1,medium,low,20,60
A,2,medium,high,20,120
A,3,low,low,80,60
A,4,high,low,100,120
A,5,medium,danger,140,60
A,6,danger,low,180,120

工作代码 - 工具提示调整

<html>
<head>
    <title>Testing warehouse</title>
    <style>
    #tooltip {
        position: absolute;
        width: 200px;
        height: auto;
        padding: 10px;
        background-color: white;
        -webkit-border-radius: 10px;
        -moz-border-radius: 10px;
        border-radius: 10px;
        -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
        -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
        box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
        pointer-events: none;
    }

    #tooltip.hidden {
            display: none;
    }

    #tooltip p {
            margin: 0;
            font-family: sans-serif;
            font-size: 16px;
            line-height: 20px;
    }
    </style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
//NOTE:: x and y co-ordinates needs to be set on excel file.
//      width and height of rect needs to be set within functions returnheight and returnwidth

var width = 1500,
    height = 1500;

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var data    
d3.csv("AisleA.csv", function(d) {
    data = d;
    svg.selectAll("rect")
      .data(data)
      .enter()
      .append("rect")
      .attr("x", function(d){return d.x}) 
      .attr("y", function(d){return d.y})

        //IF ODD BAY THEN LS ELSE CARTON FLOW. 
        //THIS BELOW FUCNTION KEEPS GETTING UPDATED AS WE INCLUDE OTHER AISLES AND BAYS
      .attr("width", function(d){
            if(Number(d.Bay) & 1)
            {
                // ODD
                return 40
            }
            else
            {
                // EVEN
                return 60
            }
      })
      .attr("height", function(d){
            if(Number(d.Bay) & 1)
            {
                // ODD
                return 40
            }
            else
            {
                // EVEN
                return 60
            }
      })
      .style("fill","green")    //SHOULD CHANGE BASED ON THE PICK RATE VALUE
      .style("stroke","black")
      .on("mouseover", function(data) {
        //Get this bar's x/y values, then augment for the tooltip
        var xPosition = parseFloat(d3.select(this).attr("x"))/2 //+ xScale.rangeBand() / 2;
        var yPosition = parseFloat(d3.select(this).attr("y")) / 2 //+ h / 2;

        //UPDATE THE TOOLTIP POSITION AND VALUE
        d3.select("#tooltip")
          .style("left", xPosition + "px")
          .style("top", yPosition + "px")
          .select("#value")
          .text(data.PickRate);

        //Show the tooltip
        d3.select("#tooltip").classed("hidden", false);

        })
       .on("mouseout", function() {
        //Hide the tooltip
        d3.select("#tooltip").classed("hidden", true);
        });                                                 
});

</script>
<div id="tooltip" class="hidden">
        <p><strong>Important Label Heading</strong></p>
        <p><span id="value">100</span></p>
</div>
</body>
</html>

最佳答案

您可以根据您的计算放置工具提示,如下所示:

  var xPosition = parseFloat(d3.select(this).attr("x"));
  var yPosition = parseFloat(d3.select(this).attr("y")) - 55;

工作代码here :

关于javascript - D3 : unable to access data within anonymous function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33449161/

相关文章:

php - 字符串替换和数组的替代方法

javascript - 正则表达式 - 右/左 trim + 将中间多于一个的空格减少到一个 + 删除开头和结尾处的换行符,包括如果在中间且 >2 则减少到两个

javascript - 为什么我的函数使用 DOM 会导致未定义?

javascript - JQuery动画div从右到左平滑

javascript - 如何更改第二次单击时的不透明度?

d3.js - D3 Sankey 最小化链路交叉

javascript - 为什么 element.style.property 不适用于模板字符串?

javascript - selection.enter() 不是函数

javascript - 如何在 D3 v4 力图中仅让一些边对 `mouseover` 使用react

javascript - 根据搜索名称在 D3 旭日派上进行转换