я отметил потенциальный барьер с использованием координат для определения видимости метки в моем комментарии выше. Тем не менее, существует еще один способ определить, должна ли надпись быть видимой: определение того, имеет ли путь svg страны атрибут 'd', который не является нулевым.
Во-первых, идентификаторы должны быть установлены надлежащим образом, в настоящее время d.properties.name содержит пробелы, поэтому установка идентификаторами с:
.attr("id", function(d) { return d.properties.name.split(' ').join('_'); })
позволит более четко идентифицировать такие места, как Соединенное Королевство и Соединенные Штаты ,
Выбрав каждый путь на основе id, мы можем увидеть, есть ли у него какие-либо данные, определяющие его форму. Если это не показано, свойство 'd' пути будет null.
if (d3.select("#"+d.properties.name.split(' ').join('_')).attr('d') != null) {
return 'inline';
}
else {
return 'none';
}
Обновлено скрипку: here
Использование другого текста якорь может центрировать текст лучше, как хорошо:
.style("text-anchor","middle");
Fiddle с текстом якорь посередине: here
--- Обновление --- Хотя приведенный выше код скроет ярлыки для стран, не привлеченных (полностью позади земного шара), если любая часть страны будет нарисована, тогда будет создан ярлык. Множество проблем вокруг этого можно решить, не нарисовав метки, которые находятся на некотором расстоянии от центра: fiddle, as mentioned in comment below.
Однако, для некоторых крупных стран, таких как Россия, географический центр (и, следовательно, расположение этикеток) может находиться в пределах указанного радиуса и будет нарисован, если будет отображена крошечная лента страны. Когда это произойдет, географический центроид, а не центроид svg, будет использоваться для обозначения страны. В этих случаях географический центроид находится на дальнем конце Земли, но выглядит так, как если бы он был на видимой стороне.
Кроме того, в случае Франции, SVG медианы и географический центр тяжести будут проблематичны:
А методов паров может быть использована для оказания помощи в переключени этикеток, такие как вычисления и записи географических центроиды в географические данные и использование углового расстояния от центра проекции карты, чтобы показать/скрыть метки. В случае с Францией расщепление Гвианы было бы полезно.
Без изменения данных другой критерий может быть использован для выбора того, какие метки должны быть видимыми: видя, находится ли центр ограничивающей рамки страны, как рисованный, рядом с краем карты. Это добавляет дополнительный уровень вычислений, но если каждый критерий проверяется только при необходимости, оно должно быть в порядке: http://jsfiddle.net/0ptcy7f3/1/
var country = d3.select("#"+d.properties.name.split(' ').join('_'));
// Exclude labels this far from center:
var r = 350;
// Check to see if the country has a path visible as before
if (country.attr('d') != null) {
// Then check to see if the bounding box
// for the country as drawn is far from center
var BB = country.node().getBBox();
var x = (BB.x + (BB.x + BB.width))/2;
var y = (BB.y + (BB.y + BB.height))/2;
if (((width-x)*(width-x) + (height-y)*(height-y)) < (r * r)) {
// And ensure the geographic centroid is also not on the edge:
center = path.centroid(d);
x = center[0];
y = center[1];
if (((width-x)*(width-x) + (height-y)*(height-y)) < (r * r)) {
return 'inline';
}
else {
return 'none';
}
}
else { return 'none'; }
else { return 'none'; }
Случай Франции не рассматриваются, так как это географический путь включает в Гвиану. В код может быть встроен особый случай, чтобы заставить ярлык в определенном месте и оценить это местоположение как допустимое местоположение. В противном случае данные необходимо отредактировать. Это обновление должно заботиться о России или других крупных/длинных странах.
Настройка, которая может быть выполнена, изменяет радиус исключения, поскольку карта увеличена (или вообще не выполняет эту проверку, если карта заполняет весь кадр).
В скрипке вы используете path.centroid(), которая возвращает координаты в координатном пространстве svg. Это работает для размещения меток, однако вам нужны географические координаты центроида, чтобы определить, должна ли надпись быть видимой. Проблема, как мне представляется, заключается в том, что projection.invert (path.centroid (d)) при использовании этого подхода вернет видимую географическую координату при заданной координате svg, что означает, что все метки будут считаться видимыми. Кроме того, вы измеряете расстояние от [190,190] на svg, а не на [400,400], так как ваша ширина и высота составляют 800 пикселей на основе скрипки. –