代码之家  ›  专栏  ›  技术社区  ›  oymonk

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

  •  0
  • oymonk  · 技术社区  · 6 年前

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

    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的行放在一起)
    • 类别级别2(将类别级别1数据放在一起)。

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

    问题在于这一行: .attr("opacity", function(d, i) {return d.CategoryLevel1 == nest[p].key ? 1 : 0}) . 虽然 nest[p].key 在前面的代码中工作得非常好(参见console.log的第106行),在创建矩形的块中,它的行为似乎有所不同。有人知道怎么让它表现吗?

    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>
    0 回复  |  直到 6 年前
        1
  •  2
  •   Gerardo Furtado    6 年前

    不要乱搞索引、模运算符或类似的东西,如 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>
        2
  •  1
  •   Jason    6 年前

    我猜这就是你所期望的。

    因为在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/