javascript - 将大纲添加到 mapbox donutSegment cluster svg
问题描述
我基于 mapbox 中的代码创建了一个集群 svg,该集群 svg 被分段为https://docs.mapbox.com/mapbox-gl-js/example/cluster-html/
我希望集群有一个宽度为 STROKE_WIDTH 的白色轮廓。我试图通过在群集下方添加另一个稍大的白色圆圈来做到这一点。但是,要做到这一点,我必须调整该圆的 cx 和 cy ,使其在 svg 中正确居中。但是我不知道如何调整 donutSegments 的 cx 和 cy,因为我不完全理解 mapbox 的代码。如果您知道如何转换该 svg 或对如何添加白色轮廓有其他建议,我将不胜感激。
这是我现在得到的结果:off_center_cluster
这是我的简化代码:
export function createDonutChart(props: Record<string, number>) {
// code for creating an SVG donut chart from feature properties
const offsets: number[] = [];
const counts = Object.entries(props);
let total = 0;
for (const [, count] of counts) {
offsets.push(total);
if (count) {
total += count;
}
}
const fontSize = 16;
const r = 18;
const stroke_r = r + STROKE_WIDTH;
const r0 = Math.round(r * 0.6);
const w = stroke_r * 2;
return (
<div>
<svg
width={w}
height={w}
viewBox={`0 0 ${w} ${w} `}
textAnchor="middle"
style={{ font: `${fontSize}px sans-serif`, display: 'block' }}
>
<circle cx={stroke_r} cy={stroke_r} r={stroke_r} fill="white" />
{counts.map(([color, count], i) =>
donutSegment(offsets[i] / total, (offsets[i] + (count ?? 0)) / total, r, r0, color),
)}
<text dominantBaseline="central" transform={`translate(${stroke_r}, ${stroke_r})`}>
{total.toLocaleString()}
</text>
</svg>
</div>
);
}
function donutSegment(start: number, end: number, r: number, r0: number, color: string) {
if (end - start === 1) end -= 0.00001;
const a0 = 2 * Math.PI * (start - 0.25);
const a1 = 2 * Math.PI * (end - 0.25);
const x0 = Math.cos(a0),
y0 = Math.sin(a0);
const x1 = Math.cos(a1),
y1 = Math.sin(a1);
const largeArc = end - start > 0.5 ? 1 : 0;
return (
<path
d={`M ${r + r0 * x0} ${r + r0 * y0} L ${r + r * x0} ${r + r * y0} A ${r} ${r} 0 ${largeArc} 1 ${r + r * x1} ${
r + r * y1
} L ${r + r0 * x1} ${r + r0 * y1} A ${r0} ${r0} 0 ${largeArc} 0 ${r + r0 * x0} ${r + r0 * y0}`}
fill={`${color}`}
/>
);
}
解决方案
想通了!最好的方法是不要用 来重新定位较大圆圈的 cx 和 cy stroke_r
,而是在“r”处保持中心相同,只使用宽度stroke_r
并将 viewBox 位置移动到:
viewBox={`${-STROKE_WIDTH} ${-STROKE_WIDTH} ${w} ${w} `}
推荐阅读
- kdb - 在并行执行时——哪一方报告错误?
- azure - 资源提供者 Microsfot.Storage 注册
- javascript - React 和 Firebase 身份验证系统
- java - java中真的存在“else if”吗?
- javascript - 从网站图标资源获取更高分辨率的 png
- amazon-web-services - AWS CloudFormation VPC CIDR 分配给安全组
- java - eclipse milo opcua客户端连接到prosys服务器问题
- sql - 来自两个单独查询的内部联接结果
- facebook - 我如何知道 Facebook 用户 ID 是全局 uid 还是应用范围内的用户 ID (ASID)?
- reactjs - 使用 gatsby-plugin-mailchimp 将地址信息发送到 mailchimp