我正在嘗試根據之前創建的 a 動態生成一條text線BBox。但是,該行放置不準確。我希望代碼將該行放在文本的開頭,并且離text.
我不確定這里出了什么問題。BBox回傳元素周圍可能的最小矩形svg,但是為什么在基于相同BBox尺寸的情況下將線放置得很遠。
const body = d3.select('body');
//global specs
const width = 1536;
const height = 720;
const svgns = 'http://www.w3.org/2000/svg';
//generate svg
const svg = body.append('svg')
.attr('xmlns', svgns)
.attr('viewBox', `0 0 ${width} ${height}`);
//background rect
svg.append('rect')
.attr('class', 'vBoxRect')
.attr('width', `${width}`)
.attr('height', `${height}`)
.attr('fill', '#EFEFEF');
//text data
const data = [{ "cat": "This is a test of text using Javascript" }];
//create grp
const grp = svg
.append('g')
.attr('class', 'test')
//create text
const svgText1 = grp
.append('g')
.classed('svgText', true)
.selectAll('text')
.data(data)
.join('text')
.attr('class', (d, i) => { return `textSvgOne` `${i}` })
.each(
function(d, i) {
const element = svg.node();
const vBox = element.viewBox.baseVal;
const width = vBox.width / 2;
const height = vBox.height / 2;
d3.select(this)
.attr('x', `${width}`)
.attr('y', `${height}`)
}
)
.text((d, i) => { return d.cat })
.attr('text-anchor', 'middle')
.attr('dominant-baseline', 'middle')
.attr('alignment-baseline', 'middle')
.style('font-size', 'xx-large')
.style('font-family', "'Oswald', sans-serif");
//create line
const border1 = d3.select('g.svgText')
.selectAll('line')
.data(data)
.join('line')
.each(
function(d, i) {
const current = d3.select(this);
const target = current.node().parentNode.childNodes[0];
const box = target.getBBox();
const x = box.x;
const y = box.y;
const height = box.height;
current
.attr('class', (d, i) => { return `textSvgBorder` `${i}` })
.attr('x1', x)
.attr('x2', x)
.attr('y1', y)
.attr('y2', `${y height}`)
.attr('stroke', 'black')
}
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<body>
<style>
@import url('https://fonts.googleapis.com/css2?family=DM Sans&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@200&display=swap');
</style>
<script type="text/javascript" src="prod.js">
</script>
</body>
</html>
uj5u.com熱心網友回復:
@enxaneta感謝您的提示。以下改編自此答案的內容在 chrome/firefox/brave/edge 中完美運行。
計算BBox包含在以下承諾document.fonts.ready.then(()=>)中,字體現在具有以下宣告
<link rel="preconnect" href="https://fonts.gstatic.com/" />
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin />
<link href='https://fonts.googleapis.com/css2?family=Oswald:wght@200&display=block' rel='stylesheet' type='text/css'>
const body = d3.select('body');
//global specs
const width = 1536;
const height = 720;
const svgns = 'http://www.w3.org/2000/svg';
//text data
const data = [{
"cat": "This is a test of text using Javascript"
}];
//generate svg
const svg = body.append('svg')
.attr('xmlns', svgns)
.attr('viewBox', `0 0 ${width} ${height}`);
//background rect
svg.append('rect')
.attr('class', 'vBoxRect')
.attr('width', `${width}`)
.attr('height', `${height}`)
.attr('fill', '#EFEFEF');
//create grp
const grp = svg
.append('g')
.attr('class', 'test')
//create text
const svgText1 = grp
.append('g')
.classed('svgText', true)
.selectAll('text')
.data(data)
.join('text')
.attr('class', (d, i) => {
return `textSvgOne` `${i}`
})
.each(
function(d, i) {
const element = svg.node();
const vBox = element.viewBox.baseVal;
const width = vBox.width / 2;
const height = vBox.height / 2;
d3.select(this)
.attr('x', `${width}`)
.attr('y', `${height}`)
}
)
.text((d, i) => {
return d.cat
})
.attr('text-anchor', 'middle')
.attr('dominant-baseline', 'middle')
.attr('alignment-baseline', 'middle')
.attr('font-size', 'xx-large')
.style('font-family', "'Oswald', sans-serif");
//create line dynamically based on text BBox upon promise fulfillment
document.fonts.ready.then(() => {
d3.select('g.svgText')
.selectAll('line')
.data(data)
.join('line')
.each(
function(d, i) {
const current = d3.select(this);
const target = d3.select(`.textSvgOne` `${i}`).node();
//console.log(target);
const box = target.getBBox();
const x = box.x;
const y = box.y;
const height = box.height;
current
.attr('class', (d, i) => {
return `textSvgBorder` `${i}`
})
.attr('x1', x)
.attr('x2', x)
.attr('y1', y)
.attr('y2', `${y height}`)
.attr('stroke', 'black')
}
)
}
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="preconnect" href="https://fonts.gstatic.com/" />
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin />
<link href='https://fonts.googleapis.com/css2?family=Oswald:wght@200&display=block' rel='stylesheet' type='text/css'>
</head>
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<body>
<!--
<style>
@import url('https://fonts.googleapis.com/css2?family=DM Sans&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@200&display=block');
</style>
-->
<script type="text/javascript" src="prod.js">
</script>
</body>
</html>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/504320.html
標籤:javascript svg d3.js
上一篇:在JS中合并不相交的物件陣列
