gpt4 book ai didi

javascript - 使用D3生成SVG饼图如何垂直对齐文本

转载 作者:行者123 更新时间:2023-12-04 10:55:50 27 4
gpt4 key购买 nike

使用 D3 生成 SVG 饼图如何垂直对齐文本,如图所示。

enter image description here

下面的示例代码显示了水平文本,我尝试的一切都不起作用。

        var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var fs = 33;
if(w > h){
w = w / 1.5;
} else {
h = h / 1.5;
}

if(w > h){
fs = h /25;
} else {
fs = w /25;
}
var padding = {top:20, right:40, bottom:0, left:0},
w = w - padding.left - padding.right,
h = h - padding.top - padding.bottom,
r = Math.min(w, h)/2,
rotation = 0,
oldrotation = 0,
picked = 100000,
oldpick = [],
color = d3.scale.category20();//category20c()
var data = [
{"label":"100", "value":1, "question":"What CSS property is used for specifying the area between the content and its border?"}, // padding
{"label":"200", "value":1, "question":"What CSS property is used for changing the font?"}, //font-family
{"label":"300", "value":1, "question":"What CSS property is used for changing the color of text?"}, //color
{"label":"400", "value":1, "question":"What CSS property is used for changing the boldness of text?"}, //font-weight
{"label":"500", "value":1, "question":"What CSS property is used for changing the size of text?"}, //font-size
{"label":"600", "value":1, "question":"What CSS property is used for changing the background color of a box?"}, //background-color
{"label":"700", "value":1, "question":"Which word is used for specifying an HTML tag that is inside another tag?"}, //nesting
{"label":"GRAND", "value":1, "question":"Which side of the box is the third number in: margin:1px 1px 1px 1px; ?"}, //bottom
{"label":"", "value":1, "question":"What are the fonts that don't have serifs at the ends of letters called?"}, //sans-serif
{"label":"100", "value":1, "question":"With CSS selectors, what character prefix should one use to specify a class?"}, //period
{"label":"200", "value":1, "question":"With CSS selectors, what character prefix should one use to specify an ID?"}, //pound sign
{"label":"300", "value":1, "question":"In an HTML document, which tag holds all of the content people see?"}, //<body>
{"label":"400", "value":1, "question":"In an HTML document, which tag indicates an unordered list?"}, //<ul>
{"label":"500", "value":1, "question":"In an HTML document, which tag indicates the most important heading of your document?"}, //<h1>
{"label":"600", "value":1, "question":"What CSS property is used for specifying the area outside a box?"}, //margin
{"label":"700", "value":1, "question":"What type of bracket is used for HTML tags?"}, //< >
{"label":"", "value":1, "question":"What type of bracket is used for CSS rules?"}, // { }
{"label":"100", "value":1, "question":"Which HTML tag is used for specifying a paragraph?"}, //<p>
{"label":"200", "value":1, "question":"What should always be the very first line of code in your HTML?"}, //<!DOCTYPE html>
{"label":"300", "value":1, "question":"What HTML tag holds all of the metadata tags for your page?"}, //<head>
{"label":"400", "value":1, "question":"In CSS, what character separates a property from a value?"}, // colon
{"label":"500", "value":1, "question":"What HTML tag holds all of your CSS code?"}, // <style>
{"label":"600", "value":1, "question":"What file extension should you use for your web pages?"}, // .html
{"label":"700", "value":1, "question":"Which coding language is used for marking up content and structure on a web page?"}, // HTML
{"label":"", "value":1, "question":"Which coding language is used for specifying the design of a web page?"}, // CSS
// {"label":"SAMSUNG NOTE5", "value":1, "question":"Which coding language is used for adding functionality to a web page?"}, // JavaScript
// {"label":"HP DESKTOP", "value":1, "question":"What CSS property is used for making the edges of a box visible?"}, // border
// {"label":"15,000,000$", "value":1, "question":"What character symbol is used at the end of each CSS statement?"},//semi-colon
// {"label":"BUGGATI", "value":1, "question":"By default, how wide is a <div> box?"}, //100%
// {"label":" GOOGLE JOB", "value":1, "question":"What character symbol do I use to specify multiple CSS selectors in one code block?"} //comma
];
var svg = d3.select('#chart')
.append("svg")
.data([data])
//.style("display", "flex")
.attr("width", w + padding.left + padding.right)
.attr("height", h + padding.top + padding.bottom);
var container = svg.append("g")
.attr("class", "chartholder")
.attr("transform", "translate(" + (w/2 + padding.left) + "," + (h/2 + padding.top) + ")");
var vis = container
.append("g");

var pie = d3.layout.pie().sort(null).value(function(d){return 1;});
// declare an arc generator function
var arc = d3.svg.arc().outerRadius(r);
// select paths, use arc generator to draw
var arcs = vis.selectAll("g.slice")
.data(pie)
.enter()
.append("g")
.attr("class", "slice");

arcs.append("path")
.attr("fill", function(d, i){ return color(i); })
.attr("d", function (d) { return arc(d); });
// add the text
arcs.append("text")
.attr("transform", function(d){
d.innerRadius = 0;
d.outerRadius = r;
d.angle = (d.startAngle + d.endAngle)/2;
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")translate(" + (d.outerRadius - 10) +")";
})
.attr("text-anchor", "end")
.style("font-size", fs)
.text( function(d, i) {
return data[i].label;
});

container.on("click", spin);
function spin(d){

container.on("click", null);
//all slices have been seen, all done
console.log("OldPick: " + oldpick.length, "Data length: " + data.length);
if(oldpick.length == data.length){
console.log("done");
container.on("click", null);
return;
}
var ps = 360/data.length,
pieslice = Math.round(1440/data.length),
rng = Math.floor((Math.random() * 1440) + 360);

rotation = (Math.round(rng / ps) * ps);

picked = Math.round(data.length - (rotation % 360)/ps);
picked = picked >= data.length ? (picked % data.length) : picked;
if(oldpick.indexOf(picked) !== -1){
d3.select(this).call(spin);
return;
} else {
oldpick.push(picked);
}
rotation += 90 - Math.round(ps/2);
vis.transition()
.duration(3000)
.attrTween("transform", rotTween)
.each("end", function(){
//mark question as seen
d3.select(".slice:nth-child(" + (picked + 1) + ") path")
.attr("fill", "#111");
//populate question
d3.select("#question h1")
.text(data[picked].question);
oldrotation = rotation;

container.on("click", spin);
});
}
//make arrow
svg.append("g")
.attr("transform", "translate(" + (w + padding.left + padding.right) + "," + ((h/2)+padding.top) + ")")
.append("path")
.attr("d", "M-" + (r*.15) + ",0L0," + (r*.05) + "L0,-" + (r*.05) + "Z")
.style({"fill":"black"});
//draw spin circle
container.append("circle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", 60)
.style({"fill":"white","cursor":"pointer"});
//spin text
container.append("text")
.attr("x", 0)
.attr("y", 15)
.attr("text-anchor", "middle")
.text("SPIN")
.style({"font-weight":"bold", "font-size":"30px"});


function rotTween(to) {
var i = d3.interpolate(oldrotation % 360, rotation);
return function(t) {
return "rotate(" + i(t) + ")";
};
}
    text{
font-family:Helvetica, Arial, sans-serif;
font-size:11px;
pointer-events:none;
}
#chart{
position:absolute;
width:100vw;
height:100vh;
top:0;
left:0;
text-align: center;

display: -webkit-flex; /* Safari */
display: flex;
-webkit-align-items: center; /* Safari 7.0+ */
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
#question{
position: absolute;
width:100vw;
height:100vh;
top:0;
left:0;
pointer-events: none;
}
#question h1{
font-size: 50px;
font-weight: bold;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
position: absolute;
padding: 0;
margin: 0;
top:50%;
-webkit-transform:translate(0,-50%);
transform:translate(0,-50%);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Wheel of Fortune Bingo</title>

</head>
<body>
<div id="chart"></div>
<div id="question"><h1></h1></div>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</body>
</html>

最佳答案

一种可能的解决方案是使用 glyph-orientation-vertical .但是,我相信附加单独的 <tspan>元素更容易控制。

因此,将每个字符串转换为一个字母数组,在您的文本选择中附加为 tspan:

textSelection.selectAll(null)
.data((_,i) => data[i].label)
.enter()
.append("tspan")
.attr("rotate", 90)
//etc...

结果如下:

var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var fs = 33;
if(w > h){
w = w / 1.5;
} else {
h = h / 1.5;
}

if(w > h){
fs = h /25;
} else {
fs = w /25;
}
var padding = {top:20, right:40, bottom:0, left:0},
w = w - padding.left - padding.right,
h = h - padding.top - padding.bottom,
r = Math.min(w, h)/2,
rotation = 0,
oldrotation = 0,
picked = 100000,
oldpick = [],
color = d3.scale.category20();//category20c()
var data = [
{"label":"100", "value":1, "question":"What CSS property is used for specifying the area between the content and its border?"}, // padding
{"label":"200", "value":1, "question":"What CSS property is used for changing the font?"}, //font-family
{"label":"300", "value":1, "question":"What CSS property is used for changing the color of text?"}, //color
{"label":"400", "value":1, "question":"What CSS property is used for changing the boldness of text?"}, //font-weight
{"label":"500", "value":1, "question":"What CSS property is used for changing the size of text?"}, //font-size
{"label":"600", "value":1, "question":"What CSS property is used for changing the background color of a box?"}, //background-color
{"label":"700", "value":1, "question":"Which word is used for specifying an HTML tag that is inside another tag?"}, //nesting
{"label":"GRAND", "value":1, "question":"Which side of the box is the third number in: margin:1px 1px 1px 1px; ?"}, //bottom
{"label":"", "value":1, "question":"What are the fonts that don't have serifs at the ends of letters called?"}, //sans-serif
{"label":"100", "value":1, "question":"With CSS selectors, what character prefix should one use to specify a class?"}, //period
{"label":"200", "value":1, "question":"With CSS selectors, what character prefix should one use to specify an ID?"}, //pound sign
{"label":"300", "value":1, "question":"In an HTML document, which tag holds all of the content people see?"}, //<body>
{"label":"400", "value":1, "question":"In an HTML document, which tag indicates an unordered list?"}, //<ul>
{"label":"500", "value":1, "question":"In an HTML document, which tag indicates the most important heading of your document?"}, //<h1>
{"label":"600", "value":1, "question":"What CSS property is used for specifying the area outside a box?"}, //margin
{"label":"700", "value":1, "question":"What type of bracket is used for HTML tags?"}, //< >
{"label":"", "value":1, "question":"What type of bracket is used for CSS rules?"}, // { }
{"label":"100", "value":1, "question":"Which HTML tag is used for specifying a paragraph?"}, //<p>
{"label":"200", "value":1, "question":"What should always be the very first line of code in your HTML?"}, //<!DOCTYPE html>
{"label":"300", "value":1, "question":"What HTML tag holds all of the metadata tags for your page?"}, //<head>
{"label":"400", "value":1, "question":"In CSS, what character separates a property from a value?"}, // colon
{"label":"500", "value":1, "question":"What HTML tag holds all of your CSS code?"}, // <style>
{"label":"600", "value":1, "question":"What file extension should you use for your web pages?"}, // .html
{"label":"700", "value":1, "question":"Which coding language is used for marking up content and structure on a web page?"}, // HTML
{"label":"", "value":1, "question":"Which coding language is used for specifying the design of a web page?"}, // CSS
// {"label":"SAMSUNG NOTE5", "value":1, "question":"Which coding language is used for adding functionality to a web page?"}, // JavaScript
// {"label":"HP DESKTOP", "value":1, "question":"What CSS property is used for making the edges of a box visible?"}, // border
// {"label":"15,000,000$", "value":1, "question":"What character symbol is used at the end of each CSS statement?"},//semi-colon
// {"label":"BUGGATI", "value":1, "question":"By default, how wide is a <div> box?"}, //100%
// {"label":" GOOGLE JOB", "value":1, "question":"What character symbol do I use to specify multiple CSS selectors in one code block?"} //comma
];
var svg = d3.select('#chart')
.append("svg")
.data([data])
//.style("display", "flex")
.attr("width", w + padding.left + padding.right)
.attr("height", h + padding.top + padding.bottom);
var container = svg.append("g")
.attr("class", "chartholder")
.attr("transform", "translate(" + (w/2 + padding.left) + "," + (h/2 + padding.top) + ")");
var vis = container
.append("g");

var pie = d3.layout.pie().sort(null).value(function(d){return 1;});
// declare an arc generator function
var arc = d3.svg.arc().outerRadius(r);
// select paths, use arc generator to draw
var arcs = vis.selectAll("g.slice")
.data(pie)
.enter()
.append("g")
.attr("class", "slice");

arcs.append("path")
.attr("fill", function(d, i){ return color(i); })
.attr("d", function (d) { return arc(d); });
// add the text
arcs.append("text")
.attr("transform", function(d){
d.innerRadius = 0;
d.outerRadius = r;
d.angle = (d.startAngle + d.endAngle)/2;
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")translate(" + (d.outerRadius - 10) +")";
})
.attr("text-anchor", "end")
.style("font-size", fs)
.selectAll(null)
.data((_,i)=>data[i].label)
.enter()
.append("tspan")
.attr("rotate", "90")
.attr("dx", (_,i)=> i ? "-1.5em" : null)
.attr("y", 0)
.text( function(d) {
return d
});

container.on("click", spin);
function spin(d){

container.on("click", null);
//all slices have been seen, all done
console.log("OldPick: " + oldpick.length, "Data length: " + data.length);
if(oldpick.length == data.length){
console.log("done");
container.on("click", null);
return;
}
var ps = 360/data.length,
pieslice = Math.round(1440/data.length),
rng = Math.floor((Math.random() * 1440) + 360);

rotation = (Math.round(rng / ps) * ps);

picked = Math.round(data.length - (rotation % 360)/ps);
picked = picked >= data.length ? (picked % data.length) : picked;
if(oldpick.indexOf(picked) !== -1){
d3.select(this).call(spin);
return;
} else {
oldpick.push(picked);
}
rotation += 90 - Math.round(ps/2);
vis.transition()
.duration(3000)
.attrTween("transform", rotTween)
.each("end", function(){
//mark question as seen
d3.select(".slice:nth-child(" + (picked + 1) + ") path")
.attr("fill", "#111");
//populate question
d3.select("#question h1")
.text(data[picked].question);
oldrotation = rotation;

container.on("click", spin);
});
}
//make arrow
svg.append("g")
.attr("transform", "translate(" + (w + padding.left + padding.right) + "," + ((h/2)+padding.top) + ")")
.append("path")
.attr("d", "M-" + (r*.15) + ",0L0," + (r*.05) + "L0,-" + (r*.05) + "Z")
.style({"fill":"black"});
//draw spin circle
container.append("circle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", 60)
.style({"fill":"white","cursor":"pointer"});
//spin text
container.append("text")
.attr("x", 0)
.attr("y", 15)
.attr("text-anchor", "middle")
.text("SPIN")
.style({"font-weight":"bold", "font-size":"30px"});


function rotTween(to) {
var i = d3.interpolate(oldrotation % 360, rotation);
return function(t) {
return "rotate(" + i(t) + ")";
};
}
text{
font-family:Helvetica, Arial, sans-serif;
font-size:11px;
pointer-events:none;
}
#chart{
position:absolute;
width:100vw;
height:100vh;
top:0;
left:0;
text-align: center;

display: -webkit-flex; /* Safari */
display: flex;
-webkit-align-items: center; /* Safari 7.0+ */
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
#question{
position: absolute;
width:100vw;
height:100vh;
top:0;
left:0;
pointer-events: none;
}
#question h1{
font-size: 50px;
font-weight: bold;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
position: absolute;
padding: 0;
margin: 0;
top:50%;
-webkit-transform:translate(0,-50%);
transform:translate(0,-50%);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Wheel of Fortune Bingo</title>

</head>
<body>
<div id="chart"></div>
<div id="question"><h1></h1></div>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</body>
</html>


两个观察:第一,避免使用数据数组的索引来获取正确的字符串;取而代之的是,将字符串本身绑定(bind)为数据。其次,我将一个字符串传递给 data() ,这会将其转换为数组。但是,这种行为随时可能改变;因此,为了提高可靠性,请自行将字符串转换为数组,例如使用 String.prototype.split() .

关于javascript - 使用D3生成SVG饼图如何垂直对齐文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59204677/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com