[英]Adjust text font size based on rect size in d3.js
我正在尝试根据rect的大小来调整栏内文本的字体大小。 矩形的宽度(在小提琴中可以看到)根据数据而变化。
我尝试的是根据rect的宽度调整字体大小:
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
的字体大小,它根据视口调整字体,但是我对rects的大小而不是整个屏幕感兴趣,因此这也是一个糟糕的选择。
有没有一种方法可以根据其大小来调整条中文本的font-size
大小? (其高度/宽度)
您可以使用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>
使用ksav方法,但使用rect的高度(此处为常数70,但使用基于d
设置height
的表达式)和rect中的文本进行了调整
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 );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.