首页 > 解决方案 > 调整圆圈大小文本和 svg 大小

问题描述

我是一个新的 javascript 程序员。我正在尝试根据窗口的大小调整圆圈的大小和 svg 大小。此外,代码现在创建了不同大小的圆圈,但无法同时调整到文本大小。

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", props.SkillProficiencyId * 20)
  .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
  });
});

在此处输入图像描述

到目前为止使用.attr("viewBox", "0 0 680 490")不起作用。只是让所有的圆圈变大,但与窗口不成比例


    // Make SVG container  
    var svgContainer = d3.select("body")
    .append("svg")
    .attr("viewBox", "0 0 680 490")
    .attr("presserveAspectRatio", "xMinYMin meet")
    //.attr("height", height)
    ;

在此处输入图像描述

标签: javascripthtmld3.jssvg

解决方案


我做了五项改进:

  1. 圆的宽度基于SkillProficiencyId.
  2. 将 svg 宽度从600增加到900.
  3. 文本将始终出现在圆圈的中间:text.style("text-anchor", "middle")成功了。
  4. 文字大小与圆圈大小成正比;
  5. 计算圆 dx 的最聪明方法(不使用任意偏移);

代码笔: https ://codepen.io/mayconmesquita/pen/RwWoZbv

JS代码:

var width = 900;
var height = 400;

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

function getCircleSize(SkillProficiencyId) {
  var minSize = 60;

  return minSize + (minSize * (SkillProficiencyId * .2));
}

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

// This function will iterate your data
data.map(function(props, index) {
  /*
    The new CX calc:
    ('circleSize' * 2) will be multiplied by element's index.
    So for 3 elements, cx = 70, 140, 210 ...
    All these values changeable by this vars.
  */
  var circleSize = getCircleSize(props.SkillProficiencyId);
  var cx = (circleSize * 2) * (index); // Here CX is calculated

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

  var elemEnter = elem
    .enter()
    .append("g")
    .attr("transform", "translate(100, 0)"); // prevent svg crops first circle

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

  elemEnter
    .append("text")
    .style("fill", "white")
    .attr("dy", 165)
    .attr("dx", cx)
    .text(props.CategoryName)
    .style("font-size", ((circleSize * .2) + index) + "px")
    .style("text-anchor", "middle");
});

推荐阅读