Javascript 使用d3.js绘制包含文本的多个圆

Javascript 使用d3.js绘制包含文本的多个圆,javascript,d3.js,circle-pack,Javascript,D3.js,Circle Pack,我是一名新的javascript程序员。我正在尝试制作一个基于类别绘制圆圈的可视化(“基本上,每个圆圈上只有一个类别”)。我的问题是,我的代码只打印一个圆圈,所有类别都在彼此的顶部 <script> var width = 600; var height = 600; var data = d3.json("/data", function(error, data){ console.log

我是一名新的javascript程序员。我正在尝试制作一个基于类别绘制圆圈的可视化(“基本上,每个圆圈上只有一个类别”)。我的问题是,我的代码只打印一个圆圈,所有类别都在彼此的顶部

 <script> 
        var width = 600;
        var height = 600;

        var data = d3.json("/data", function(error, data){
                    console.log(data)
        // Make SVG container 
        var svgContainer = d3.select("body")
                             .append("svg")
                             .attr("width", width)
                             .attr("height", height);

        var elem = svgContainer.selectAll("div")
                               .data(data);

        var elemEnter = elem.enter()
                            .append("g")

        var circles = elemEnter.append("circle")
                              .attr("cx", 100)
                              .attr("cy", 100)
                              .attr("r",80)
                              .style("fill", "blue")

        elemEnter.append("text")
                 .attr("dy", function(d){
            return d.SkillProficiencyId +80;
            }).attr("dx",function(d){ return d.SkillProficiencyId-1;})
                    .text(function(d){return d.CategoryName});
        });


    </script>

我创建了一个动态创建圆圈的示例,其中文本居中

演示:

JS代码:[已编辑*]

var width = 600;
var height = 600;

// Place your JSON here.
var data = [
  { CategoryName: 'Adaptive Security', SkillProficiencyId: 1 },
  { CategoryName: 'Programmer', SkillProficiencyId: 2 },
  { CategoryName: 'Coffee Drinker', SkillProficiencyId: 3 }
];

/*
  This 'cxBase' will be multiplied by element's index, and sum with offset.
  So for 3 elements, cx = 0, 200, 400 ...
  All these values changeable by this vars.
*/
const cxBase = 200;
const cxOffset = 100;

console.log(data);

// Make SVG container  
var svgContainer = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);

// This function will iterate your data
data.map(function(props, index) {
  var cx = cxBase * (index) + cxOffset; // Here CX is calculated

  var elem = svgContainer.selectAll("div").data(data);

  var elemEnter = elem.enter()
  .append("g")

  var circles = elemEnter.append("circle")
  .attr("cx", cx)
  .attr("cy", 100)
  .attr("r", 80)
  .style("fill", "blue");

  elemEnter
  .append("text")
  .style("fill", "white")
  .attr("dy", function(d){
    return 105;
  })
  .attr("dx",function(d){
    return cx - (props.CategoryName.length * 3.5);
  })
  .text(function (d) {
    return props.CategoryName
  });
});
编辑:

  • 按照作者的要求,我确实改进了代码。现在,圆的cx坐标是根据数组元素的索引动态计算的

  • 我创建了一个动态创建圆圈的示例,其中文本居中

    演示:

    JS代码:[已编辑*]

    var width = 600;
    var height = 600;
    
    // Place your JSON here.
    var data = [
      { CategoryName: 'Adaptive Security', SkillProficiencyId: 1 },
      { CategoryName: 'Programmer', SkillProficiencyId: 2 },
      { CategoryName: 'Coffee Drinker', SkillProficiencyId: 3 }
    ];
    
    /*
      This 'cxBase' will be multiplied by element's index, and sum with offset.
      So for 3 elements, cx = 0, 200, 400 ...
      All these values changeable by this vars.
    */
    const cxBase = 200;
    const cxOffset = 100;
    
    console.log(data);
    
    // Make SVG container  
    var svgContainer = d3.select("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height);
    
    // This function will iterate your data
    data.map(function(props, index) {
      var cx = cxBase * (index) + cxOffset; // Here CX is calculated
    
      var elem = svgContainer.selectAll("div").data(data);
    
      var elemEnter = elem.enter()
      .append("g")
    
      var circles = elemEnter.append("circle")
      .attr("cx", cx)
      .attr("cy", 100)
      .attr("r", 80)
      .style("fill", "blue");
    
      elemEnter
      .append("text")
      .style("fill", "white")
      .attr("dy", function(d){
        return 105;
      })
      .attr("dx",function(d){
        return cx - (props.CategoryName.length * 3.5);
      })
      .text(function (d) {
        return props.CategoryName
      });
    });
    
    编辑:

  • 按照作者的要求,我确实改进了代码。现在,圆的cx坐标是根据数组元素的索引动态计算的

  • 非常好,谢谢!两个简单的问题,我的json数据不包括cx值。因此,我创建了
    var=props.SkillProficiencyId*100
    ,我仍然可以打印单个圆圈/文本,但现在它们重叠了,我注意到一些圆圈将具有相同的cx(因为SkillProficiency可能会重复)。如何确保每个圆都打印且不重叠?我还注意到,文本可能太长,而且不完全可见@Maycon MesquitaHi@jessgtrz!不客气!我编辑了答案和密码。我添加了一种基于元素索引动态计算cx的方法,这样,您就不再需要在json中包含cx了。:)检查那里!令人惊叹的!我正在研究d3plus的包装方法来调整文本,但您的函数也会处理它。这真是太棒了!另一个问题,我提出了一个新问题,如果它对你更有效,因为我最初的问题已经在技术上解决了。让我知道!为了使窗口的大小与显示的圆圈的大小保持一致,我研究了
    var svg=d3.select(“div#container”).append(“svg”).attr(“preserveSpectratio”,“xMinYMin meet”).attr(“viewBox”,“0 300”).classed(“svg content”,true)
    @Maycon Mesquitamy在圆圈大小值内使用SkillProficiencyId的原因是,圆圈的大小需要根据SkillProficiencyId(等于1,2,3,4或5)的不同而有所不同。我想让圆圈再次成为不同大小的@Maycon Mesquitathanks!新问题是[这里]()非常有效,谢谢!两个简单的问题,我的json数据不包括cx值。因此,我创建了
    var=props.SkillProficiencyId*100
    ,我仍然可以打印单个圆圈/文本,但现在它们重叠了,我注意到一些圆圈将具有相同的cx(因为SkillProficiency可能会重复)。如何确保每个圆都打印且不重叠?我还注意到,文本可能太长,而且不完全可见@Maycon MesquitaHi@jessgtrz!不客气!我编辑了答案和密码。我添加了一种基于元素索引动态计算cx的方法,这样,您就不再需要在json中包含cx了。:)检查那里!令人惊叹的!我正在研究d3plus的包装方法来调整文本,但您的函数也会处理它。这真是太棒了!另一个问题,我提出了一个新问题,如果它对你更有效,因为我最初的问题已经在技术上解决了。让我知道!为了使窗口的大小与显示的圆圈的大小保持一致,我研究了
    var svg=d3.select(“div#container”).append(“svg”).attr(“preserveSpectratio”,“xMinYMin meet”).attr(“viewBox”,“0 300”).classed(“svg content”,true)
    @Maycon Mesquitamy在圆圈大小值内使用SkillProficiencyId的原因是,圆圈的大小需要根据SkillProficiencyId(等于1,2,3,4或5)的不同而有所不同。我想让圆圈再次成为不同大小的@Maycon Mesquitathanks!新问题是[这里]()
    /*
      This 'cxBase' will be multiplied by element's index, and sum with offset
      So for 3 elements, cx = 0, 200, 400 ...
      All these values changeable by this vars.
    */
    const cxBase = 200;
    const cxOffset = 100;