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

如何将小倍数的子组放在页面上?

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

    我有一个数据集,其中有一个列名为 CategoryLevel1 Categorylevel1 并根据密钥生成一系列svg。然后,我创建了表示整个数据集中的项的矩形,并在每个svg中重复这些矩形。我对每个svg都应用了一个过滤器,因此只能看到带有svg键的数据集项。

    我的真实数据集比这里表示的玩具数据集大。以上代码的结果是一个很长的svgs网页-非常混乱。为了使事情更清楚,我希望SVG按照一个名为 CategoryLevel2 . 以下是我想要的效果:

    enter image description here

    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")
      .filter(function(d, i) {
        const x = d3.select(this.parentNode).datum();
        return x.key == d.CategoryLevel1 ? 1 : 0;
      })
      .attr("height", function(d) {
        return 50;
      })
      .attr("width", "5")
      .attr("x", function(d, i) {
        return i * 10;
      })
      .attr("y", 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>

    我试过的:

    .filter(function(d, i) {
        const x = d3.select(this.parentNode).datum();
        return x.key == d.CategoryLevel1 ? 1 : 0;
      })
    

    我还尝试使用“transform,translate”函数来分离基于Categorylevel1的矩形,但拒绝了这一点,因为移动与Categorylevel1相关联的文本会很困难。

    我现在正在尝试使用d3.hierarchy布局之一。问题是,一旦对数据集应用d3.stratify,结果就不能用于生成一系列svg。也就是说,当应用以下代码时,DOM中不会显示任何内容:(FYI还将treeData替换为root.denscents()等-

    var treeData = d3.stratify()
      .id(function(d) { return d.CategoryLevel1; })
      .parentId(function(d) { return d.CategoryLevel2; })
      (data);
    
      var svgs = d3.select("chart")
        .selectAll("svg")
        .data(treeData)
        .enter()
        .append('svg')
        .attr("width", width)
        .attr("height", height + 20);
    
    0 回复  |  直到 6 年前
        1
  •  3
  •   Gerardo Furtado    6 年前

    这里缺少一个重要的信息:你没有告诉我们 怎样 你想分开 CategoryLevel2 小组:在同一排?在同一列?其他模式?

    因此,在我的解决方案中,我将使用一个容器 <div> 具有 display: flex ,每值一个 类别2 Edibles , At Home Walks and outings ).

    类别2 作为嵌套函数中的第一个键:

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

    [{key: "Edibles", values: Array},
     {key: "At home", values: Array},
     {key: "Walks and outings", values: Array}];
    

    在每个 values 价值,你将拥有你原来的巢穴,比如:

    {
        "key": "Edibles",
        "values": [{
            "key": "Average Quantity and Planning",
            "values": [
                //etc...
            ]
        }, {
            "key": "Bowl and Plate Design",
            "values": [
                //etc..
            ]
        }, {
            "key": "Avoiding Neck Strain",
            "values": [
                //etc...
            ]
        }, {
            "key": "Drooling",
            "values": [
                //etc
            ]
        }]
    }
    

    然后使用嵌套数据追加div:

    var divs = d3.select(".container")
      .selectAll(null)
      .data(nest)
      .enter()
      .append("div")
      .attr("class", "innerdiv");
    

    当然,不要忘记对真正的svg使用内部数组:

    var svgs = divs.selectAll(null)
      .data(function(d) {
        return d.values;
      })
      .enter()
      //etc...
    

    下面是这些更改的代码:

    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.CategoryLevel2;
      })
      .key(function(d) {
        return d.CategoryLevel1;
      })
      .entries(data);
    
    var div = d3.select("body").append("div")
      .attr("class", "tooltip")
      .style("opacity", 0)
    
    var height = 80,
      width = 150;
    
    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 divs = d3.select(".container")
      .selectAll(null)
      .data(nest)
      .enter()
      .append("div")
      .attr("class", "innerdiv");
      
    divs.append("p")
      .html(function(d){
      return d.key;
      });
    
    var svgs = divs.selectAll(null)
      .data(function(d) {
        return d.values;
      })
      .enter()
      .append('svg')
      .attr("width", width)
      .attr("height", height + 20);
    
    svgs.append("text")
      .attr('class', 'label')
      .attr('x', width / 2)
      .attr('y', height)
      .style("font-size", "10px")
      .text(function(d) {
        return d.key;
      })
      .attr('text-anchor', 'middle')
    
    svgs.selectAll("rect")
      .data(data)
      .enter().append("rect")
      .attr("class", "bar")
      .filter(function(d, i) {
        const x = d3.select(this.parentNode).datum();
        return x.key == d.CategoryLevel1 ? 1 : 0;
      })
      .attr("height", function(d) {
        return 50;
      })
      .attr("width", "5")
      .attr("x", function(d, i) {
        return i * 10;
      })
      .attr("y", 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);
      });
    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;
    }
    
    .container {
      display: flex;
    }
    
    .innerdiv {
     text-align: center;
     font-size: 21px;
     font-family: "Arial";
     flex: 1 1 0;
    }
    
    .innerdiv + .innerdiv {
     padding-left: 16px;
      border-left: 2px solid lightgray;
      }
    <!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>
    
    <body>
      <div class="container"></div>
    </body>
    
    </html>