외부에 레이블이있는 도넛 형 차트를 만들 때 d3.js를 사용하고 있습니다. 원형의 각 조각의 중심에 기반한 삼각법을 사용하여 레이블을 배치합니다.d3js 원형 차트 주위에 레이블 재배포
g.append("g")
.attr("class", "percentage")
.append("text")
.attr("transform", function(d)
{
var c = arc.centroid(d);
var x = c[0];
var y = c[1];
var h = Math.sqrt(x*x + y*y);
return "translate(" + (x/h * obj.labelRadius) + ',' + (y/h * obj.labelRadius) + ")";
}
)
.attr("dy", ".4em")
.attr("text-anchor", function(d)
{
return (d.endAngle + d.startAngle)/2 > Math.PI ? "end" : "start";
}
)
.text(function(d) { return d.data.percentage+"%"; });
궁극적으로 달성하려는 것은 원형 차트의 가장자리 바깥에있는 레이블을 재정렬하여 중복을 방지하는 것입니다.
나는이 문제를 해결하기 위해 시도하는 방법 중
한
은 보장 레이블이 배치 될 수있다 "앵커 포인트"로 설정 정의하는 것입니다 그들이이 더 겹쳐도. 문제는 도심을 앵커에 매핑하고 조각과 레이블 간의 시각적 인 일치감을 유지하는 것입니다 (조각이 얇을 때 특히 어려움).이미지는 상기 앵커의 가능한 위치를 도시한다 (조각의 무게 중심이 도시 됨). 이러한 위치에서는 겹치는 것이 불가능합니다.
레이블이 수평 인 경우 원형의 상단이나 하단에 가까울수록 원형의 오른쪽이나 왼쪽에있을 때보 다 쉽게 겹치게됩니다 .
이 문제에 접근하는 방법에 대한 아이디어가 있습니까?
.attr("dy", function(d)
{
var c = arc.centroid(d);
var x = c[0];
var y = c[1];
var h = Math.sqrt(x*x + y*y);
var dy = y/h * obj.labelRadius;
dy=dy*fontSizeParam*.14/heightParam);
return (dy)+"em";
})
그것은 약간의 도움, 그리고 라벨에 약간의 공간을 제공, 여전히하지만 모든 경우를 포함하는 솔루션을 찾고 :
는[편집] meetamit의 제안에 따라, 나는 다음과 같은 구현했습니다. ..
jsfiddle에서 지금까지 가지고있는 것의 예를 들어 주시겠습니까? – Jonah
명확성을 위해 이미지를 추가했습니다. 코드에서 "앵커"솔루션을 구현하지 않았습니다. 여러 가지 경우에 실패 할 수있는 여러 가지 사례를 연구했습니다. – Cenobyte321
나는 본다. 사실, 당신은 어려운 문제가 있습니다. 그리고 d3 그 자체와는 거의 관계가없는 것 : 그래프에 레이블을 배치하기위한 일반적인 알고리즘을 찾고 있습니다. 어떤 가정을 할 수 있습니까? 예를 들어 모든 조각이 초록색과 황색 조각만큼 작 으면 모든 레이블을 넣는 좋은 방법이 없을 것입니다. 특정 크기보다 작은 조각에 대해서만 마우스를 올리면 레이블을 표시하는 것은 어떻습니까? – Jonah