D3 Метки на круговой диаграмме обрезаются - PullRequest
0 голосов
/ 29 августа 2018

У меня проблема с круговой диаграммой D3, где метки обрезаются при их появлении. Вот картинка:

pie chart as-is

Я новичок в D3 и не уверен, где именно должно быть исправление. Логика для построения круговой диаграммы - 400 строк, поэтому я сделал пастинный блок: https://pastebin.com/32CxpeDM

Может, проблема в этой функции?

function showDetails(layer, data) {
    active.inner = !active.inner
    active.outer = false
    let lines = guideContainer.selectAll('polyline.guide-line-inner')
        .data(pie(data.inner))
    let text = guideContainer.selectAll('.inner-text')
        .data(pie(data.inner))

    if (active.inner) {
        // LINES
        lines.enter()
            .append('polyline')
            .attr('points', calcPoints)
            .attr('class', 'guide-line-inner')
            .style('opacity', 0)
            .transition().duration(300)
            .style('opacity', d => { return d.data.value <= 0 ? 0 : 1 })

        lines.attr('points', calcPoints).attr('class', 'guide-line-inner')

        // TEXT
        text.enter()
            .append('text')
            .html(labelText)
            .attr('class', 'inner-text label label-circle')
            .attr('transform', labelTransform)
            .attr('dy', '1.1em')
            .attr('x', d => { return (midAngle(d) < Math.PI ? 15 : -15) })
            .style('text-anchor', d => { return (midAngle(d)) < Math.PI ? 'start' : 'end' })
            .style('opacity', 0)
            .call(wrap, 300)
            .on('click', d => { vm.$emit('details', d) })
            .transition().duration(300)
            .style('opacity', d => { return d.data.value <= 0 ? 0 : 1 })
    } else {
        lines.transition().duration(300)
            .style('opacity', 0)
            .remove()
        text.transition().duration(300)
            .style('opacity', 0)
            .remove()
    }
    guideContainer.selectAll('polyline.guide-line-outer').transition().duration(300)
        .style('opacity', 0)
        .remove()
    guideContainer.selectAll('.outer-text').transition().duration(300)
        .style('opacity', 0)
        .remove()
}

Как я уже сказал, я не знаю D3, поэтому я не уверен, какие у меня есть варианты, чтобы это исправить. Уменьшите диаграмму, исправьте проблему с ее контейнером div, отправьте ее на передний план или отредактируйте приведенный выше код. В идеале это было бы чистым исправлением, а не взломом, что я и пытался.

Какое самое простое и чистое решение этой проблемы? Спасибо!

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Один из подходов, который позволил бы сэкономить место, заключался бы в использовании подсказок d3 вместо меток с фиксированным положением, как в этой fiddle (созданной другим пользователем jsfiddle, я только что добавил margin)

Javascript:

//Width/height
var w = 300;
var h = 300;

var dataset = [5, 10, 20, 45, 6, 25];

var outerRadius = w / 2;
var innerRadius = w / 3;
var arc = d3.svg.arc()
  .innerRadius(innerRadius)
  .outerRadius(outerRadius);

var pie = d3.layout.pie();

var color = d3.scale.category10();

//Create SVG element
var svg = d3.select("#vis")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

//Set up groups
var arcs = svg.selectAll("g.arc")
  .data(pie(dataset))
  .enter()
  .append("g")
  .attr("class", "arc")
  .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");

//Draw arc paths
arcs.append("path")
  .attr("fill", function(d, i) {
    return color(i);
  })
  .attr("d", arc);

//Labels
arcs.append("text")
  .attr("transform", function(d) {
    return "translate(" + arc.centroid(d) + ")";
  })
  .attr("text-anchor", "middle")
  .text(function(d) {
    return d.value;
  });

//
var tip = d3.tip()
  .attr("class", "d3-tip")
  .html(function(d, i) {
    return d.value
  })

svg.call(tip)

arcs
  .on("mouseover", tip.show)
  .on("mouseout", tip.hide)

Используется библиотека подсказок d3 Джастина Палмера, которую можно найти на Github.

Кроме того, вы могли бы подумать об уменьшении круга?

Надеюсь, это поможет

0 голосов
/ 29 августа 2018

Похоже, что ваши ярлыки трансформируются за пределы вашей границы SVG.

Я бы попытался перевести элементы метки дальше влево в этой функции:

function labelTransform (d) {
  var pos = guideArc.centroid(d)

  pos[0] = (radius + 100) * (midAngle(d) < Math.PI ? 1 : -1)
  return 'translate(' + pos + ')'
}

Вам придется искать, где генерируется строка метки, и сокращать ее.

Вы также можете попробовать разбить текст метки на несколько строк в этой функции:

  function labelText (d) {
    if ((radius + 100) * (midAngle(d) < Math.PI ? 1 : 0)) {
      return '<tspan>' + d.data.display_name + ' </tspan><tspan x="15">' + d3.format('($,.0f')(d.data.value) + '</tspan>'
    } else {
      return '<tspan>' + d.data.display_name + ' </tspan><tspan x="-15" text-anchor="end">' + d3.format('($,.0f')(d.data.value) + '</tspan>'
    }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...