Отрегулируйте размер шрифта текста на основе размера прямоугольника в d3.js

1

Я пытаюсь настроить размер шрифта текста внутри панели в зависимости от размера прямоугольников. Ширина прямоугольников (как можно видеть на скрипке) изменяется в зависимости от данных.

Я попытался настроить размер шрифта в зависимости от ширины прямоугольников:

 var bar = svg.selectAll('g')
  .data(tasks)
  .enter()
  .append('g')
  .attr('transform', rectTransform)

  bar.append("rect")
  .attr("rx", 5)
  .attr("ry", 5)
  .attr("y", 0)
  .attr("fill", function(d){return d.color})
  .attr("height", function(d) { return 70; })
  .attr("width", function(d) { 
    return (x(d.endDate) - x(d.startDate)); 
  });

  bar.append("text")
  .attr('y', 10)
  .attr('dy', '.35em')
  .style("font-size", function(){
        return d3.select(this.previousSibling).attr("width") * 0.006 + 'px'
        })
  .text(function(d){return d.taskName})

Это в конечном итоге плохо работает, так как это работало для некоторых баров, а для других текст был действительно большим или маленьким.

Я также столкнулся с метрикой vw вместо px для размера шрифта, который корректирует шрифт на основе порта представления, но меня интересует размер прямоугольников вместо всего экрана, поэтому также будет плохой выбор.

Есть ли способ отрегулировать font-size текста в барах в зависимости от их размера? (их высота/ширина)

Теги:
d3.js

2 ответа

0

Используя метод ksav, но с настройкой использования высоты прямоугольника (здесь константа 70, но используйте выражение, используемое для установки height на основе d), и текст в прямоугольнике

  bar.append("text")
    .attr('y', 10)
    .attr('dy', '.7em')
    .attr("font-size", d => '${Math.min( (x(d.endDate) - x(d.startDate))/d.taskName.length, 70)}px')
    .text(d => d.taskName );
0

Вы можете использовать свой xscale для создания размера шрифта.

.attr("font-size", d => '${(x(d.endDate) - x(d.startDate))/5}px')

d3.gantt = function() {
  var FIT_TIME_DOMAIN_MODE = "fit";

  var margin = {
    top: 20,
    right: 40,
    bottom: 20,
    left: 150
  };
  var timeDomainStart = d3.timeDay.offset(new Date(), -3);
  var timeDomainEnd = d3.timeHour.offset(new Date(), +3);
  var timeDomainMode = FIT_TIME_DOMAIN_MODE; // fixed or fit
  var taskTypes = ["D Job", "P Job", "E Job", "A Job", "N Job"];
  var height = document.body.clientHeight - margin.top - margin.bottom - 5;
  var width = document.body.clientWidth - margin.right - margin.left - 5;

  var tickFormat = "%y %b";

  var rectTransform = function(d) {
    return "translate(" + x(d.startDate) + "," + y(d.taskName) + ")";
  };

  var x, y, xAxis, yAxis;

  initAxis();

  var initTimeDomain = function() {
    if (timeDomainMode === FIT_TIME_DOMAIN_MODE) {
      if (tasks === undefined || tasks.length < 1) {
        timeDomainStart = d3.time.day.offset(new Date(), -3);
        timeDomainEnd = d3.time.hour.offset(new Date(), +3);
        return;
      }
      tasks.sort(function(a, b) {
        return a.endDate - b.endDate;
      });
      timeDomainEnd = tasks[tasks.length - 1].endDate;
      tasks.sort(function(a, b) {
        return a.startDate - b.startDate;
      });
      timeDomainStart = tasks[0].startDate;
    }
  };

  function initAxis() {
    x = d3.scaleTime().domain([timeDomainStart, timeDomainEnd]).range([0, width]).clamp(true);

    y = d3.scaleBand().domain(taskTypes).rangeRound([0, height - margin.top - margin.bottom], 0.1);

    xAxis = d3.axisBottom().scale(x).tickFormat(d3.timeFormat(tickFormat))
      .tickSize(8).tickPadding(8);

    yAxis = d3.axisLeft().scale(y).tickSize(0);
  }

  function gantt(tasks) {

    initTimeDomain();
    initAxis();

    var svg = d3.select("body")
      .append("svg")
      .attr("class", "chart")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("class", "gantt-chart")
      .attr("transform", "translate(" + margin.left + ", " + margin.top + ")");

    var bar = svg.selectAll('g')
      .data(tasks)
      .enter()
      .append('g')
      .attr('transform', rectTransform)

    bar.append("rect")
      .attr("rx", 5)
      .attr("ry", 5)
      .attr("y", 0)
      .attr("fill", function(d) {
        return d.color
      })
      .attr("height", function(d) {
        return 70;
      })
      .attr("width", function(d) {
        return (x(d.endDate) - x(d.startDate));
      });

    bar.append("text")
      .attr('y', 10)
      .attr('dy', '.35em')
      .attr("font-size", d => '${(x(d.endDate) - x(d.startDate))/5}px')
      .text(function(d) {
        return d.taskName
      })

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0, " + (height - margin.top - margin.bottom) + ")")
      .transition()
      .call(xAxis);

    var legend = svg.selectAll(".legend")
      .data(tasks)
      .enter()
      .append("g")

    legend.append("rect")
      .attr("fill", function(d) {
        return d.color
      })
      .attr("width", 10)
      .attr("height", 15)
      .attr("x", -100)
      .attr("y", function(d, i) {
        return 20 + 20 * i
      })

    legend.append("text")
      .attr("y", function(d, i) {
        return 32 + 20 * i
      })
      .attr("x", -90)
      .text(function(d) {
        return d.taskName
      });

    svg.append("g").attr("class", "y axis").transition().call(yAxis);

    return gantt;

  };


  return gantt;
};

var tasks = [{
    "startDate": new Date(2018, 8),
    "endDate": new Date(2018, 10),
    "taskName": "E Job",
    "color": "blue"
  },
  {
    "startDate": new Date(2018, 4),
    "endDate": new Date(2018, 11),
    "taskName": "D Job",
    "color": "red"
  },
  {
    "startDate": new Date(2018, 7),
    "endDate": new Date(2018, 9),
    "taskName": "N Job",
    "color": "green"
  },
  {
    "startDate": new Date(2018, 1),
    "endDate": new Date(2018, 9),
    "taskName": "A Job",
    "color": "brown"
  },
  {
    "startDate": new Date(2018, 2),
    "endDate": new Date(2018, 4),
    "taskName": "E Job",
    "color": "purple"
  },
];
var gantt = d3.gantt();
gantt(tasks);
html,
body,
#wrapper {
  width: 100%;
  height: 100%;
  margin: 0px;
}

.chart {
  font-family: Arial, sans-serif;
  font-size: 12px;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.bar {
  fill: #33b5e5;
}

.bar-failed {
  fill: #CC0000;
}

.bar-running {
  fill: #CC0000;
}

.bar-succeeded {
  fill: #33b5e5;
}

.bar-killed {
  fill: #ffbb33;
}

#forkme_banner {
  display: block;
  position: absolute;
  top: 0;
  right: 10px;
  z-index: 10;
  padding: 10px 50px 10px 10px;
  color: #fff;
  background: url('http://dk8996.github.io/Gantt-Chart/images/blacktocat.png') #0090ff no-repeat 95% 50%;
  font-weight: 700;
  box-shadow: 0 0 10px rgba(0, 0, 0, .5);
  border-bottom-left-radius: 2px;
  border-bottom-right-radius: 2px;
  text-decoration: none;
}
<script type="text/javascript" src="http://d3js.org/d3.v4.min.js"></script>

скрипка

  • 0
    Что происходит, когда «X job» заменяется реальными текстовыми строками различной длины? Или с очень долгой работой? Если используется этот метод, следует добавить подходящее смещение по y чтобы текст не выходил за пределы rect объектов.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню