Настройка размера круга текста и размера SVG - PullRequest
1 голос
/ 21 апреля 2020

Я новый 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
  });
});

enter image description here

Использование .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)
    ;

enter image description here

1 Ответ

0 голосов
/ 21 апреля 2020

Я сделал пять улучшений:

  1. Ширина круга на основе SkillProficiencyId.
  2. Увеличена ширина svg с 600 до 900.
  3. Текст всегда будет появляться в середине круга: text.style("text-anchor", "middle") сделал трюк.
  4. Размер текста пропорционален размеру круга;
  5. Самый умный способ калибровки c Круг dx (w / o с использованием произвольных смещений);

Codepen: 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");
});
...