[英]d3 bar chart- How do I automatically change font-size of value so that it fits within bar
I've created a d3 bar chart that shows the values within the bar.我创建了一个 d3 条形图,显示条形内的值。
When a user hovers over a bar it shows the values change to show how all other countries compare to that country.当用户将鼠标悬停在条上时,它会显示值的变化,以显示所有其他国家与该国家的比较情况。
However, sometimes the comparison is too large - when it is over 100% or over 1000%.但是,有时比较太大 - 当它超过 100% 或超过 1000% 时。
I would like to dynamically change the font size so that the value fits the bar width.我想动态更改字体大小,以使该值适合条形宽度。
Ideally, I would like to do this calculation before the value is rendered to prevent re-rendering.理想情况下,我想在渲染值之前进行此计算以防止重新渲染。
The bar width isn't constant.条形宽度不是恒定的。 It depends on the number of countries the user has selected and the user's screen size.
这取决于用户选择的国家数量和用户的屏幕大小。
How can I know the width of the value before it is rendered (based on the number of characters it contains) and reduce the font-size so it never takes up more than 95% of the bar width?如何在渲染之前知道值的宽度(基于它包含的字符数)并减小字体大小,使其永远不会占用超过条宽的 95%?
This is my code for rendering the bar:这是我渲染栏的代码:
function renderVerticalBars(data, measurements, metric, countryID) {
let selectDataForBarCharts = d3.select("svg")
.selectAll("rect")
.data(data, d => d[countryID])
selectDataForBarCharts
.enter()
.append("rect")
.attr('width', measurements.xScale.bandwidth())
.attr("height", 0)
.attr('y', d => measurements.yScale(0))
.merge(selectDataForBarCharts)
.on('mouseover', (event, barData) => { displayComparisons(event, barData, data, metric, countryID, measurements); displayToolTip(barData) })
.on("mousemove", (event) => tooltip.style("top", (event.pageY - 10) + "px").style("left", (event.pageX + 10) + "px"))
.on('mouseout', () => { removeComparisons(data, metric, countryID, measurements); tooltip.style("visibility", "hidden") })
.transition().delay(500)
.attr("transform", `translate(0, ${measurements.margin.top})`)
.attr('width', measurements.xScale.bandwidth())
.attr('x', (d) => measurements.xScale(d[countryID]))
.transition()
.ease(d3.easeLinear)
.duration(setSpeed())
.attr("height", d => measurements.innerHeight - measurements.yScale(d[metric]))
.attr("y", (d) => measurements.yScale(d[metric]))
.attr("fill", d => setBarColor(d))
.on("end", () => renderValuesInBars(data, metric, countryID, measurements, [], countriesDownloaded))
selectDataForBarCharts.exit()
.transition().duration(500).attr("height", 0).attr("y", d => measurements.yScale(0)).remove()
}
and this is the code for rendering the values in the bar:这是在栏中呈现值的代码:
function renderValuesInBars(data, metric, countryID, measurements, barData, countriesDownloaded) {
function calculateFontSize(data) {
return ((.25 / data.length) * Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)).toString()
}
let values = d3.select("svg")
.selectAll(".casesPerCapita")
.data(data, d => d[countryID])
values
.enter()
.append("text")
.attr("y", 0)
.style("opacity", "1")
.merge(values)
.attr("class", metric)
.attr('text-anchor', setTextAnchor())
.attr('alignment-baseline', setAlignmentBaseline())
.attr('data-countryCode', d => d.countryCode)
.attr("x", countryData => setXValue(countryData, measurements, countryID))
.attr("y", countryData => setYValue(countryData, measurements, metric))
.style("fill", countryData => setColor(countryData, barData))
.style("font-size", calculateFontSize(data))
.text(countryData => decideTextToReturn(countryData))
.on('mouseover', (event) => makeBarHover(event))
.on('mouseout', (event) => { stopBarHover(event); tooltip.style("visibility", "hidden") })
.on("mousemove", (event) => tooltip.style("top", (event.pageY - 10) + "px").style("left", (event.pageX + 10) + "px"))
.on("end", () => checkValueSize)
values.exit().remove()
} }
Try changing your font-size to:尝试将您的字体大小更改为:
.style("font-size", measurements.xScale.bandwidth()+'%')
This will scale your font size to match your bar width.这将缩放您的字体大小以匹配您的条形宽度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.