将文本环绕成一个圆圈
Wrapping text in a circle
您好,刚接触编码,但已经做到了这一点。我想做的就是理解/学习如何包装我的文本,使其适合一个圆圈,例如文本变成两行而不是一行,因此它位于圆的边界内。任何帮助将非常感激。下面的代码可以通过 google 驱动器 link 找到 - 最好用 SUBLIME TEXT 打开。
HTML file. code can be opened with Sublime text
超出圆圈的文字图片以及它在圆圈中的外观
一行中的文字图像以及我希望它看起来像的文字被换行了
运行 全屏页面
var json = {
"name": "Career to date",
"children": [{
"name": "Consumer",
"children": [{
"name": "Pet care",
"children": [{
"name": "Pet vitamins",
"size": 3000,
}]
},
{
"name": "Sports & Activity",
"children": [{
"name": "Kinneir Dufort | Daily gathering & clustering of wearbal tech",
"size": 3000
},
{
"name": "RYA | Sailing evaluation",
"size": 3000
},
{
"name": "Sony | Wearable technology",
"size": 3000
},
{
"name": "UEFA | International football tournament",
"size": 3000
},
]
},
{
"name": "Food",
"children": [{
"name": "Cargill | The future of poultry",
"size": 3000
}, ]
},
{
"name": "Transport",
"children": [{
"name": "Shell | Engine maintenance",
"size": 3000
},
{
"name": "HS2 | High speed intercity train travel",
"size": 3000
},
]
},
{
"name": "Screen based technology",
"children": [{
"name": "Google | Advertisement attention",
"size": 3000
},
{
"name": "BBC Iplayer | On demand & catch up video services",
"size": 3000
},
{
"name": "Cbeebies | Children's AR & VR apps",
"size": 3000
},
]
},
{
"name": "FMCG packaging",
"children": [{
"name": "Cooper Vision | Contact lenses",
"size": 3000
},
{
"name": "Beiersdorf | Sensorial shower",
"size": 3000
},
{
"name": "Tetrapak | Ambient still drinks",
"size": 3000
},
{
"name": "Coca Cola | USA childrens drink packaging",
"size": 3000
},
]
},
{
"name": "Family",
"children": [{
"name": "Healthy food goals",
"size": 3000
},
{
"name": "Me time",
"size": 3000
},
{
"name": "First aid & safety",
"size": 3000
},
]
},
{
"name": "Interiors",
"children": [{
"name": "Unilever | Household cleaning",
"size": 3000
},
{
"name": "Canary WHARF Group | Luxury rental appartments",
"size": 3000
},
{
"name": "HS2 | Staff break areas in train stations",
"size": 3000
},
]
},
{
"name": "Finance",
"children": [{
"name": "Newham Council | Emergency loans",
"size": 3000
},
{
"name": "Money Advice Service | Debt advice",
"size": 3000
},
]
},
{
"name": "Construction",
"children": [{
"name": "CITB | Onsite digital technology",
"size": 3000
},
{
"name": "CITB | Current and future workforce skilling",
"size": 3000
},
{
"name": "CITB | VR & AR for learning & training",
"size": 3000
},
]
},
{
"name": "Energy",
"children": [{
"name": "Ofgem | Smart meter data",
"size": 3000
},
{
"name": "Ofgem | Energy price caps",
"size": 3000
},
{
"name": "Ofgem | The future energy market",
"size": 3000
},
{
"name": "Ofgem | Energy bill information, design & layout",
"size": 3000
},
{
"name": "Ofgem | Price control process & DNO's",
"size": 3000
}
]
},
{
"name": "360 video",
"size": 3000
}
]
},
{
"name": "Medical",
"children": [{
"name": "Respiratory drug delivery",
"children": [{
"name": "ACTIVIS | Dry powder inhalers",
"size": 3000
}, ]
},
{
"name": "Diabetes Management",
"children": [{
"name": "Roche | CGM data management with AGP",
"size": 3000
},
{
"name": "Roche | Insulin pump configuration",
"size": 3000
},
{
"name": "Roche | Infusion set inserters",
"size": 3000
},
{
"name": "Roche | Continuous glucose monitoring (CGM)",
"size": 3000
},
{
"name": "Roche | Blood glucose meters",
"size": 3000
},
{
"name": "Roche | Insulin pumps & injections",
"size": 3000
},
]
},
{
"name": "Advanced Wound Care",
"children": [{
"name": "Smith & nephew | Silicone gel dressings for highly exeduing wounds",
"size": 3000
},
{
"name": "Smith & Nephew | Biosynthetic dressings for burns",
"size": 3000
},
{
"name": "Smith & Nephew | Abdominal cavity closure",
"size": 3000
},
{
"name": "Negative pressure wound therapy (NPWT)",
"size": 3000
},
]
},
{
"name": "Musculoskeletal Disorders",
"children": [{
"name": "HSE | MSDs in & out of the workplace",
"size": 3000
}, ]
},
{
"name": "Stoma Care",
"children": [{
"name": "Eakin | Colostomies, illeostomies & urostomies",
"size": 3000
}]
}
]
},
{}
]
}
var svg = d3.select("svg"),
margin = 20,
diameter = +svg.attr("width"),
g = svg.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
var color = d3.scaleLinear()
.domain([-1, 5])
// CHANGE COLOUR HERE
.range(["rgb(0,0,0)", "rgb(255,255,255)"])
.interpolate(d3.interpolateHcl);
//CHANGES HOW CLOSE THE CIRLCES ARE
var pack = d3.pack()
.size([diameter - margin, diameter - margin])
.padding(5);
d3.json('flare.json', function(error, root) {
// if (error) throw error;
root = d3.hierarchy(json)
.sum(function(d) {
return d.size;
})
.sort(function(a, b) {
return b.value - a.value;
});
var focus = root,
nodes = pack(root).descendants(),
view;
var circle = g.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("class", function(d) {
return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root";
})
.style("fill", function(d) {
return color(d.depth);
})
.on("click", function(d) {
if (focus !== d) zoom(d),
d3.event.stopPropagation();
});
var text = g.selectAll("text")
.data(nodes)
.enter().append("text")
.attr("class", "label")
.style("fill-opacity", function(d) {
return d.parent === root ? 1 : 0;
})
.style("display", function(d) {
return d.parent === root ? "inline" : "none";
})
// ITEMS FONT SIZE HERE
.style("font-size", function(d) {
if (d.parent) {
// console.log(d.depth, d.r);
var size = (d.r * d.depth * 0.175)
}
return size + "px";
})
.text(function(d) {
return d.data.name;
});
var node = g.selectAll("circle,text");
svg
.style("background", color(-1))
.on("click", function() {
zoom(root);
});
zoomTo([root.x, root.y, root.r * 2 + margin]);
function zoom(d) {
var focus0 = focus;
focus = d;
var transition = d3.transition()
.duration(d3.event.altKey ? 7500 : 750)
.tween("zoom", function(d) {
var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
return function(t) {
zoomTo(i(t));
};
});
transition.selectAll("text")
.filter(function(d) {
return d.parent === focus || this.style.display === "inline";
})
.style("fill-opacity", function(d) {
return d.parent === focus ? 1 : 0;
})
.on("start", function(d) {
if (d.parent === focus) this.style.display = "inline";
})
.on("end", function(d) {
if (d.parent !== focus) this.style.display = "none";
});
}
function zoomTo(v) {
var k = diameter / v[2];
view = v;
node.attr("transform", function(d) {
return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")";
});
circle.attr("r", function(d) {
return d.r * k;
});
}
});
.node {
cursor: pointer;
}
.node:hover {
stroke: rgb(255, 255, 255);
stroke-width: 1px;
}
.node--leaf {
fill: white;
}
.label {
font: 10px "din", Helvetica, Arial, sans-serif;
text-anchor: middle;
fill: rgb(0, 0, 0);
/* text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff; */
}
.label,
.node--root,
.node--leaf {
pointer-events: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="960"></svg>
SVG 不提供文本换行,但使用 foreignObject
可以实现类似的效果。为什么不尝试使用 foreignObjects
。您可以在此处阅读更多相关信息 https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject,通过使用它,我能够根据您的要求包装文本,请查看下面的工作代码段。
svg {
width: 700px;
height: 200px;
background-color: #000;
padding: 50px;
}
.circle {
background-color: rgb(119, 119, 119);
height: 100%;
border-radius: 100%;
text-align: center;
line-height: 200px;
font-size: 30px;
}
.circle span {
color: black;
line-height: normal;
display: inline-block;
vertical-align: middle;
font-family: sans-serif;
font-size: 18px;
padding: 20px;
}
<svg xmlns="http://www.w3.org/2000/svg">
<foreignObject width="200" height="200" x="0" y="0">
<div class="circle">
<span>paragraph</span>
</div>
</foreignObject>
<foreignObject width="200" height="200" x="250" y="0">
<div class="circle">
<span>Here is a paragraph</span>
</div>
</foreignObject>
<foreignObject width="200" height="200" x="500" y="0">
<div class="circle">
<span>Here is a paragraph that requires word wrap</span>
</div>
</foreignObject>
</svg>
您好,刚接触编码,但已经做到了这一点。我想做的就是理解/学习如何包装我的文本,使其适合一个圆圈,例如文本变成两行而不是一行,因此它位于圆的边界内。任何帮助将非常感激。下面的代码可以通过 google 驱动器 link 找到 - 最好用 SUBLIME TEXT 打开。
HTML file. code can be opened with Sublime text
超出圆圈的文字图片以及它在圆圈中的外观
一行中的文字图像以及我希望它看起来像的文字被换行了
运行 全屏页面
var json = {
"name": "Career to date",
"children": [{
"name": "Consumer",
"children": [{
"name": "Pet care",
"children": [{
"name": "Pet vitamins",
"size": 3000,
}]
},
{
"name": "Sports & Activity",
"children": [{
"name": "Kinneir Dufort | Daily gathering & clustering of wearbal tech",
"size": 3000
},
{
"name": "RYA | Sailing evaluation",
"size": 3000
},
{
"name": "Sony | Wearable technology",
"size": 3000
},
{
"name": "UEFA | International football tournament",
"size": 3000
},
]
},
{
"name": "Food",
"children": [{
"name": "Cargill | The future of poultry",
"size": 3000
}, ]
},
{
"name": "Transport",
"children": [{
"name": "Shell | Engine maintenance",
"size": 3000
},
{
"name": "HS2 | High speed intercity train travel",
"size": 3000
},
]
},
{
"name": "Screen based technology",
"children": [{
"name": "Google | Advertisement attention",
"size": 3000
},
{
"name": "BBC Iplayer | On demand & catch up video services",
"size": 3000
},
{
"name": "Cbeebies | Children's AR & VR apps",
"size": 3000
},
]
},
{
"name": "FMCG packaging",
"children": [{
"name": "Cooper Vision | Contact lenses",
"size": 3000
},
{
"name": "Beiersdorf | Sensorial shower",
"size": 3000
},
{
"name": "Tetrapak | Ambient still drinks",
"size": 3000
},
{
"name": "Coca Cola | USA childrens drink packaging",
"size": 3000
},
]
},
{
"name": "Family",
"children": [{
"name": "Healthy food goals",
"size": 3000
},
{
"name": "Me time",
"size": 3000
},
{
"name": "First aid & safety",
"size": 3000
},
]
},
{
"name": "Interiors",
"children": [{
"name": "Unilever | Household cleaning",
"size": 3000
},
{
"name": "Canary WHARF Group | Luxury rental appartments",
"size": 3000
},
{
"name": "HS2 | Staff break areas in train stations",
"size": 3000
},
]
},
{
"name": "Finance",
"children": [{
"name": "Newham Council | Emergency loans",
"size": 3000
},
{
"name": "Money Advice Service | Debt advice",
"size": 3000
},
]
},
{
"name": "Construction",
"children": [{
"name": "CITB | Onsite digital technology",
"size": 3000
},
{
"name": "CITB | Current and future workforce skilling",
"size": 3000
},
{
"name": "CITB | VR & AR for learning & training",
"size": 3000
},
]
},
{
"name": "Energy",
"children": [{
"name": "Ofgem | Smart meter data",
"size": 3000
},
{
"name": "Ofgem | Energy price caps",
"size": 3000
},
{
"name": "Ofgem | The future energy market",
"size": 3000
},
{
"name": "Ofgem | Energy bill information, design & layout",
"size": 3000
},
{
"name": "Ofgem | Price control process & DNO's",
"size": 3000
}
]
},
{
"name": "360 video",
"size": 3000
}
]
},
{
"name": "Medical",
"children": [{
"name": "Respiratory drug delivery",
"children": [{
"name": "ACTIVIS | Dry powder inhalers",
"size": 3000
}, ]
},
{
"name": "Diabetes Management",
"children": [{
"name": "Roche | CGM data management with AGP",
"size": 3000
},
{
"name": "Roche | Insulin pump configuration",
"size": 3000
},
{
"name": "Roche | Infusion set inserters",
"size": 3000
},
{
"name": "Roche | Continuous glucose monitoring (CGM)",
"size": 3000
},
{
"name": "Roche | Blood glucose meters",
"size": 3000
},
{
"name": "Roche | Insulin pumps & injections",
"size": 3000
},
]
},
{
"name": "Advanced Wound Care",
"children": [{
"name": "Smith & nephew | Silicone gel dressings for highly exeduing wounds",
"size": 3000
},
{
"name": "Smith & Nephew | Biosynthetic dressings for burns",
"size": 3000
},
{
"name": "Smith & Nephew | Abdominal cavity closure",
"size": 3000
},
{
"name": "Negative pressure wound therapy (NPWT)",
"size": 3000
},
]
},
{
"name": "Musculoskeletal Disorders",
"children": [{
"name": "HSE | MSDs in & out of the workplace",
"size": 3000
}, ]
},
{
"name": "Stoma Care",
"children": [{
"name": "Eakin | Colostomies, illeostomies & urostomies",
"size": 3000
}]
}
]
},
{}
]
}
var svg = d3.select("svg"),
margin = 20,
diameter = +svg.attr("width"),
g = svg.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
var color = d3.scaleLinear()
.domain([-1, 5])
// CHANGE COLOUR HERE
.range(["rgb(0,0,0)", "rgb(255,255,255)"])
.interpolate(d3.interpolateHcl);
//CHANGES HOW CLOSE THE CIRLCES ARE
var pack = d3.pack()
.size([diameter - margin, diameter - margin])
.padding(5);
d3.json('flare.json', function(error, root) {
// if (error) throw error;
root = d3.hierarchy(json)
.sum(function(d) {
return d.size;
})
.sort(function(a, b) {
return b.value - a.value;
});
var focus = root,
nodes = pack(root).descendants(),
view;
var circle = g.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("class", function(d) {
return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root";
})
.style("fill", function(d) {
return color(d.depth);
})
.on("click", function(d) {
if (focus !== d) zoom(d),
d3.event.stopPropagation();
});
var text = g.selectAll("text")
.data(nodes)
.enter().append("text")
.attr("class", "label")
.style("fill-opacity", function(d) {
return d.parent === root ? 1 : 0;
})
.style("display", function(d) {
return d.parent === root ? "inline" : "none";
})
// ITEMS FONT SIZE HERE
.style("font-size", function(d) {
if (d.parent) {
// console.log(d.depth, d.r);
var size = (d.r * d.depth * 0.175)
}
return size + "px";
})
.text(function(d) {
return d.data.name;
});
var node = g.selectAll("circle,text");
svg
.style("background", color(-1))
.on("click", function() {
zoom(root);
});
zoomTo([root.x, root.y, root.r * 2 + margin]);
function zoom(d) {
var focus0 = focus;
focus = d;
var transition = d3.transition()
.duration(d3.event.altKey ? 7500 : 750)
.tween("zoom", function(d) {
var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
return function(t) {
zoomTo(i(t));
};
});
transition.selectAll("text")
.filter(function(d) {
return d.parent === focus || this.style.display === "inline";
})
.style("fill-opacity", function(d) {
return d.parent === focus ? 1 : 0;
})
.on("start", function(d) {
if (d.parent === focus) this.style.display = "inline";
})
.on("end", function(d) {
if (d.parent !== focus) this.style.display = "none";
});
}
function zoomTo(v) {
var k = diameter / v[2];
view = v;
node.attr("transform", function(d) {
return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")";
});
circle.attr("r", function(d) {
return d.r * k;
});
}
});
.node {
cursor: pointer;
}
.node:hover {
stroke: rgb(255, 255, 255);
stroke-width: 1px;
}
.node--leaf {
fill: white;
}
.label {
font: 10px "din", Helvetica, Arial, sans-serif;
text-anchor: middle;
fill: rgb(0, 0, 0);
/* text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff; */
}
.label,
.node--root,
.node--leaf {
pointer-events: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="960"></svg>
SVG 不提供文本换行,但使用 foreignObject
可以实现类似的效果。为什么不尝试使用 foreignObjects
。您可以在此处阅读更多相关信息 https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject,通过使用它,我能够根据您的要求包装文本,请查看下面的工作代码段。
svg {
width: 700px;
height: 200px;
background-color: #000;
padding: 50px;
}
.circle {
background-color: rgb(119, 119, 119);
height: 100%;
border-radius: 100%;
text-align: center;
line-height: 200px;
font-size: 30px;
}
.circle span {
color: black;
line-height: normal;
display: inline-block;
vertical-align: middle;
font-family: sans-serif;
font-size: 18px;
padding: 20px;
}
<svg xmlns="http://www.w3.org/2000/svg">
<foreignObject width="200" height="200" x="0" y="0">
<div class="circle">
<span>paragraph</span>
</div>
</foreignObject>
<foreignObject width="200" height="200" x="250" y="0">
<div class="circle">
<span>Here is a paragraph</span>
</div>
</foreignObject>
<foreignObject width="200" height="200" x="500" y="0">
<div class="circle">
<span>Here is a paragraph that requires word wrap</span>
</div>
</foreignObject>
</svg>