将数据集中的元素映射到div id

时间:2019-03-14 03:19:22

标签: html d3.js

我想制作一个类似于以下内容的网页:

a infographic titled 'Mapping Dog Care Manuals' with subheadings such as 'Edibles' and 'Bowl and plate design' accompanied by coloured dots representing different manuals.

更具体地说,我希望基于包含四列的数据集来生成我的网页,标题如下:

  • 手册(此类别中有四个唯一元素,它们决定点的颜色)
  • 名称(此类别确定鼠标悬停时出现的词)
  • CategoryLevel1(此类别将具有相同CategoryLevel1的行放置在一起)
  • CategoryLevel2(将CategoryLevel1数据放置在一起)。

更新:制定了一个策略:运行nest函数并基于键创建多个svg。将代表整个数据集的正方形添加到svgs,然后使用不透明度隐藏不相关的正方形。

问题就在这一行:.attr("opacity", function(d, i) {return d.CategoryLevel1 == nest[p].key ? 1 : 0})。尽管nest[p].key在代码的早期阶段工作得很好(请参见第106行的console.log),但是在用于创建矩形的块中,其行为似乎有所不同。有谁知道如何使它表现出来?

var doc = `Manual	Name	CategoryLevel1	CategoryLevel2
DOG	"General Furry, Program and Subject Files"	Average Quantity and Planning	Edibles
TR	Senate Committee on animal Standards	Bowl and Plate Design	Edibles
TR	Published Canine	Bowl and Plate Design	Edibles
TR	Canine case files	Bowl and Plate Design	Edibles
DOG	Canine Files 	Avoiding Neck Strain	Edibles
DOG	Canine Files 	Drooling	Edibles
DOG	Canine Files 	Drooling	Edibles
DG	ADVERTISING	At home	At home
DG	PROMOTIONS	At home	At home
DG3	Publications	At home	At home
TR	Public and Information Services	At home	At home
TR	Petting Services	Getting special treats	At home
TR	Petting Services	Getting special treats	At home
TR	Petting Services	Getting special treats	At home
TR	Petting Services	Getting special treats	At home
TR	Petting Services	Getting special treats	At home
TR	Petting Services	Getting special treats	At home
DG	DEVELOPMENT	Optimal time of day - walking	Walks and outings
DG	INCOME AND REVENUE	Optimal time of day - walking	Walks and outings
TR	Fundraising	Optimal time of day - walking	Walks and outings
TR	Fundraising	Optimal time of day - walking	Walks and outings
DG	DEVELOPMENT	Optimal time of day - walking	Walks and outings
DG	INCOME AND REVENUE	Optimal time of day - walking	Walks and outings
TR	Wishbone	Protective Measures	Walks and outings
TR	Wishbone	Protective Measures	Walks and outings
DG	Wishbone	Observant of Limps Etc	Walks and outings
DOG	Wishbone	Observant of Limps Etc	Walks and outings
TR	Wishbone	Observant of Limps Etc	Walks and outings`;

const data = d3.tsvParse(doc, function(d) {
    return {
      Manual: d.Manual,
      Name: d.Name,
      CategoryLevel1: d.CategoryLevel1,
      CategoryLevel2: d.CategoryLevel2
    };
  });


    var nest = d3.nest()
      .key(function(d) {
        return d.CategoryLevel1;
      })
      .entries(data);



    var div = d3.select("body").append("div")
      .attr("class", "tooltip")
      .style("opacity", 0)

    var height = 100,
      width = 200;

    var color = d3.scaleOrdinal(["#edf8fb", "#b3cde3", "#8c96c6", "#88419d"]);

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

    var g = d3.select("svg").attr("height", "100%").attr("width", "100%");



    var svgs = d3.select("body")
      .selectAll("svg")
      .data(nest)
      .enter()
      .append('svg')
      .attr("width", width)
      .attr("height", height + 20);

    svgs.append("text")
      .attr('class', 'label')
      .data(nest)
      .attr('x', width / 2)
      .attr('y', height)
      .text(function(d) {
        return d.key;
      })
      .attr('text-anchor', 'middle')

    for (var p = 0; p < 9; p++) {

      nest.forEach(function(element) {

        console.log(nest[p].key);


        svgs.selectAll("rect")
          .data(data)
          .enter().append("rect")
          .attr("class", "bar")
          .attr("height", function(d) {
            return 50;
          })
          .attr("width", "5")
          .attr("x", function(d, i) {
            return i * 10;
          })
          .attr("y", 0)
          .attr("opacity", function(d, i) {
            return d.CategoryLevel1 == nest[p].key ? 1 : 0
          })
          .attr("fill", function(d) {
            return color(d.Manual)
          })

          .on("mouseover", function(d, i) {
            div.transition()
              .duration(200)
              .style("opacity", .9);
            div.html(d.Name)
              .style("left", (d3.event.pageX) + "px")
              .style("top", (d3.event.pageY - 50) + "px");
          })
          .on("mouseout", function(d) {
            div.transition()
              .duration(500)
              .style("opacity", 0);
          });


      });

    }
.page {
  width: 90%;
  margin: auto;
}

.menu {
  height: 100px;
  background-color: #B2D6FF;
  /* Medium blue */
}

.sidebar {
  height: 50px;
  width: 15%;
  background-color: #F09A9D;
  float: inline-start;
  display: block;
  margin: 0.1%;
  /* Red */
}

.title {
  width: 100%;
  background-color: none;
  display: inline-block;
  float: inline-start;
  /* Yellow */
}

div.tooltip {
  position: absolute;
  text-align: center;
  width: auto;
  height: auto;
  padding: 3px;
  font: 12px sans-serif;
  border: 0px;
  border-radius: 3px;
  pointer-events: none;
  background: lightgrey;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Mapping Dog Care Manuals</title>
  <script src="https://d3js.org/d3.v4.min.js"></script>
</head>


</html>

2 个答案:

答案 0 :(得分:2)

不要弄乱索引,取模运算符之类的东西,如accepted other answer中所建议的那样(回答者坦率地说,这是一个骇人听闻的解决方案)。

要获取父级SVG的数据,只需执行以下操作:

const x = d3.select(this.parentNode).datum();

这是您所做的更改的代码:

var doc = `Manual	Name	CategoryLevel1	CategoryLevel2
DOG	"General Furry, Program and Subject Files"	Average Quantity and Planning	Edibles
TR	Senate Committee on animal Standards	Bowl and Plate Design	Edibles
TR	Published Canine	Bowl and Plate Design	Edibles
TR	Canine case files	Bowl and Plate Design	Edibles
DOG	Canine Files 	Avoiding Neck Strain	Edibles
DOG	Canine Files 	Drooling	Edibles
DOG	Canine Files 	Drooling	Edibles
DG	ADVERTISING	At home	At home
DG	PROMOTIONS	At home	At home
DG3	Publications	At home	At home
TR	Public and Information Services	At home	At home
TR	Petting Services	Getting special treats	At home
TR	Petting Services	Getting special treats	At home
TR	Petting Services	Getting special treats	At home
TR	Petting Services	Getting special treats	At home
TR	Petting Services	Getting special treats	At home
TR	Petting Services	Getting special treats	At home
DG	DEVELOPMENT	Optimal time of day - walking	Walks and outings
DG	INCOME AND REVENUE	Optimal time of day - walking	Walks and outings
TR	Fundraising	Optimal time of day - walking	Walks and outings
TR	Fundraising	Optimal time of day - walking	Walks and outings
DG	DEVELOPMENT	Optimal time of day - walking	Walks and outings
DG	INCOME AND REVENUE	Optimal time of day - walking	Walks and outings
TR	Wishbone	Protective Measures	Walks and outings
TR	Wishbone	Protective Measures	Walks and outings
DG	Wishbone	Observant of Limps Etc	Walks and outings
DOG	Wishbone	Observant of Limps Etc	Walks and outings
TR	Wishbone	Observant of Limps Etc	Walks and outings`;

const data = d3.tsvParse(doc, function(d) {
  return {
    Manual: d.Manual,
    Name: d.Name,
    CategoryLevel1: d.CategoryLevel1,
    CategoryLevel2: d.CategoryLevel2
  };
});


var nest = d3.nest()
  .key(function(d) {
    return d.CategoryLevel1;
  })
  .entries(data);

var div = d3.select("body").append("div")
  .attr("class", "tooltip")
  .style("opacity", 0)

var height = 100,
  width = 300;

var color = d3.scaleOrdinal(["#edf8fb", "#b3cde3", "#8c96c6", "#88419d"]);

/* var svg = d3.select("body").append("svg").attr("height", "100%").attr("width", "100%");
    
var g = d3.select("svg").attr("height", "100%").attr("width", "100%"); */



var svgs = d3.select("body")
  .selectAll("svg")
  .data(nest)
  .enter()
  .append('svg')
  .attr("width", width)
  .attr("height", height + 20);

svgs.append("text")
  .attr('class', 'label')
  .data(nest)
  .attr('x', width / 2)
  .attr('y', height)
  .text(function(d) {
    return d.key;
  })
  .attr('text-anchor', 'middle')

svgs.selectAll("rect")
  .data(data)
  .enter().append("rect")
  .attr("class", "bar")
  .attr("height", function(d) {
    return 50;
  })
  .attr("width", "5")
  .attr("x", function(d, i) {
    return i * 10;
  })
  .attr("y", 0)
  .attr("opacity", function(d, i) {
    const x = d3.select(this.parentNode).datum();
    return x.key == d.CategoryLevel1 ? 1 : 0;
  })
  .attr("fill", function(d) {
    return color(d.Manual)
  })

  .on("mouseover", function(d, i) {
    div.transition()
      .duration(200)
      .style("opacity", .9);
    div.html(`${d.Name}`)
      .style("left", (d3.event.pageX) + "px")
      .style("top", (d3.event.pageY - 50) + "px");
  })
  .on("mouseout", function(d) {
    div.transition()
      .duration(500)
      .style("opacity", 0);
  });
.page {
  width: 90%;
  margin: auto;
}

.menu {
  height: 100px;
  background-color: #B2D6FF;
  /* Medium blue */
}

.sidebar {
  height: 50px;
  width: 15%;
  background-color: #F09A9D;
  float: inline-start;
  display: block;
  margin: 0.1%;
  /* Red */
}

.title {
  width: 100%;
  background-color: none;
  display: inline-block;
  float: inline-start;
  /* Yellow */
}

div.tooltip {
  position: absolute;
  text-align: center;
  width: auto;
  height: auto;
  padding: 3px;
  font: 12px sans-serif;
  border: 0px;
  border-radius: 3px;
  pointer-events: none;
  background: lightgrey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

答案 1 :(得分:1)

好吧,我猜这就是您所期望的行为。

由于在svgs.selectAll()。data(data)部分中,您正在遍历每个svg和数据元素。 因此,您正在循环(data.length * svgs.length)次。

对于您的问题,我没有一个明确的解决方案。但是我确实想出了一种解决方案。

我使用全局变量“ index”来跟踪它遍历数据的次数,并将其与当前有问题的svg元素进行比较。我使用index推断出当前正在循环的svg元素。

.attr("opacity", function(d, i) {
        console.log(index)
        const x = nest[(index - i) % nest.length]
        index++;
        console.log(x.key, d.CategoryLevel1)
        return x.key == d.CategoryLevel1 ? 1:0;
})

这是完整的小提琴-https://jsfiddle.net/q0b8u63L/4/

编辑 嗯,我想我努力地尝试过以致于不能聪明地推论。我看到剩下的是什么问题。相反,如果循环已达到data.length-1,则可以仅增加索引。基本上,当内部循环遍历nest中的所有元素时,将每一行与data中的下一个元素进行比较

const x = nest[index]
index = (i == data.length - 1) ? ++index : index; 

https://jsfiddle.net/q7ocjw89/