Нарисуйте текст SVG с размером и длиной. Отрегулируйте в зависимости от конкретного пути.

Это очень особенное. У меня есть несколько маршрутов (представьте их как реки на карте), и я хочу, чтобы им дали название.

Этот код работает правильно. Он создает пути и после этого пишет текст в этих строках:

function draw_rivertext(){
    var featureCollection = topojson.feature(currentMap, currentMap.objects.text);
    svgmap.append("g")
          .selectAll("path")
          .data(featureCollection.features)
          .enter().append("path")
          .attr("d", path)
          .attr("class", "helperline")
          .attr("id", function(d) {return "path"+d.properties.id});
    svgmap.append("text")
          .selectAll("text")
          .data(featureCollection.features)
          .enter()
          .append("textPath")
          .attr("class", "helperline-text")
          .attr("xlink:href", function(d) {return "#path"+d.properties.id})
          .text(function(d) {return d.properties.name});
}

Но проблема в том, что у текста всего один размер шрифта. Итак, допустим, у меня длинный ривер и короткий. Таким образом, шорт-ривер должен быть очень маленьким, а не такого же огромного размера.

Итак, моя идея заключалась в том, чтобы установить текст:

.attr("font-size", "10")

и здесь значение 10 должно соответствовать текущему размеру из идентификатора пути. Я действительно не знаю, как это сделать.

Вот несколько ссылок по этой теме:

Я также нашел некоторые, которые передискретизируют размер шрифта и так далее после создания его с помощью jQuery. Что ж, это наверняка решение. Получение размеров пути; повторная выборка текстовых атрибутов для этих значений. Но я не думаю, что это правильное решение.

Еще одна идея - указать размер шрифта в topojson как собственный параметр. Но, о боже, это было бы попыткой и ошибкой, поскольку в QGIS нет реальных измерений для этого.


person kwoxer    schedule 27.01.2015    source источник
comment
Получите длину нарисованного пути и преобразуйте ее в размер шрифта, возможно, с одной из шкал D3.   -  person Lars Kotthoff    schedule 27.01.2015
comment
Ларс, не могли бы вы описать это немного подробнее?   -  person kwoxer    schedule 27.01.2015
comment
Что ж, используйте .getTotalLength() на узле path, чтобы получить его длину (или используйте ограничивающую рамку, если это более подходит), а затем преобразуйте это значение в размер шрифта.   -  person Lars Kotthoff    schedule 27.01.2015
comment
Другая проблема в том, что у меня кривые пути. Так что я думаю, что коробка не так уж хороша. Я пробую кое-что и возвращаюсь.   -  person kwoxer    schedule 27.01.2015
comment
Я как-то не могу заставить его работать. Он всегда говорит TypeError: path.getTotalLength не является функцией   -  person kwoxer    schedule 27.01.2015
comment
Если path - ваш выбор, содержащий один путь, используйте path.node().getTotalLength(). Это не D3, а простая функция Javascript.   -  person Lars Kotthoff    schedule 27.01.2015
comment
Действительно, таким образом это работает. Но проблема в том, что существует более одного пути. Вы также знаете, как я могу преобразовать это в законное выражение: .text (d3.select (function (d) {return # path + d.properties.id}). Node (). GetTotalLength ());   -  person kwoxer    schedule 27.01.2015
comment
Я имею в виду var onepath = d3.select (# path1); а затем ... .text (onepath.node (). getTotalLength ()); работает.   -  person kwoxer    schedule 27.01.2015
comment
Другой способ - создать x / y / viewbox, когда я создаю пути. Но также понятия не имею, как это сделать. Таким образом, я мог просто уловить размер оттуда.   -  person kwoxer    schedule 27.01.2015
comment
Теперь попробовал var onepath = d3.select (#helperpath); onepath.selectAll (путь) .attr (x, self.node (). getTotalLength ()); но я не знаю, как заменить себя так, чтобы это был текущий путь.   -  person kwoxer    schedule 28.01.2015
comment
Используйте .each(): selection.each(function() { this.getTotalLength(); })   -  person Lars Kotthoff    schedule 28.01.2015
comment
var allpathes = d3.select (#helperpath); allpathes.selectAll (путь) .attr (x, allpathes.each (функция () {this.getTotalLength ();})); ... но затем я получаю TypeError: this.getTotalLength не является функцией. Не могли бы вы мне сказать, что это за выбор?   -  person kwoxer    schedule 28.01.2015
comment
Например. d3.selectAll("path"). Вы не можете использовать это внутри определения атрибута.   -  person Lars Kotthoff    schedule 28.01.2015
comment
Но на самом деле это не помогает. У меня есть один идентификатор для информации о пути. И еще один для текста. Мне нужно выделить весь текст, а затем взять информацию из путей. Так что мне нужно объединить это, не так ли?   -  person kwoxer    schedule 28.01.2015
comment
Сначала добавьте пути, затем пройдите по ним с помощью .each() и добавьте длину к привязанным к ним данным. Затем добавьте текст (который будет распространять данные) и используйте длину, которую вы добавили к данным ранее, чтобы определить размер шрифта.   -  person Lars Kotthoff    schedule 28.01.2015
comment
Я создал пример с несколькими строками и текстом. Не могли бы показать мне на этом примере, как вы используете функцию each (). Спасибо заранее. jsfiddle.net/2a5syp0j/2   -  person kwoxer    schedule 28.01.2015
comment
Что ж, я думаю, что я уже получил от вас достаточно помощи, но я действительно не знаю, где ее разместить, не могли бы вы создать новую версию на моей скрипке, пожалуйста? Был бы очень признателен Ларс =) Спасибо   -  person kwoxer    schedule 28.01.2015
comment
Ну, скрипка ничего не делает, поэтому я не уверен, насколько полезным будет добавление дополнительного кода к неработающему коду :) Не могли бы вы поставить рабочую версию того, чего вы пытаетесь достичь, пожалуйста?   -  person Lars Kotthoff    schedule 28.01.2015
comment
Ох, я не знал, что это не работает, извините. Но все равно здесь работаю. Использование Firefox в jsfiddle.net/kwoxer/2a5syp0j/2 Также проверено в Chrome, работает, слишком.   -  person kwoxer    schedule 28.01.2015
comment
Хорошо, теперь он работает. См. jsfiddle.net/2a5syp0j/3.   -  person Lars Kotthoff    schedule 28.01.2015
comment
Ошибка 500 ВАУ! Ошибка сервера. Письмо было отправлено администратору. знак равно   -  person kwoxer    schedule 28.01.2015
comment
Да, у меня раньше было что-то подобное с твоей скрипкой. У меня все еще работает, может, если вы дадите ему несколько минут ...   -  person Lars Kotthoff    schedule 28.01.2015
comment
Хорошо работает сейчас. Спасибо =)   -  person kwoxer    schedule 28.01.2015
comment
Хорошо, сделаю несколько замечаний по этому поводу. Работаю в Firefox, показываю текст в Chrome, но теперь у меня есть некоторый побочный эффект, такой как подкладка в неактивном состоянии, а в IE показаны 3 текста, и самое безумное то, что в 3. только что написано первые 3 символа слова. Могу ли я помочь мне еще в этом? Вам нужен jsfiddle?   -  person kwoxer    schedule 29.01.2015
comment
Я думаю, что это выходит за рамки вопроса :) Я готов проконсультироваться, так что не стесняйтесь писать мне электронное письмо.   -  person Lars Kotthoff    schedule 29.01.2015
comment
Можем ли мы также использовать Skype или ICQ? знак равно   -  person kwoxer    schedule 29.01.2015
comment
Опять же, лучше обсудить по электронной почте :)   -  person Lars Kotthoff    schedule 29.01.2015


Ответы (1)


Благодаря Ларсу Коттоффу это рабочее решение:

svgmap.append("g")
          .selectAll("path")
          .data(featureCollection.features)
          .enter().append("path")
          .attr("d", path)
          .attr("class", "helperline")
          .attr("id", function(d) {return "path"+d.properties.id})
          .each(function() { this.__data__.totalLength = this.getTotalLength(); });
    svgmap.append("text")
          .selectAll("text")
          .data(featureCollection.features)
          .enter()
          .append("textPath")
          .attr("class", "helperline-text")
          .attr("xlink:href", function(d) {return "#path"+d.properties.id})
          .attr("font-size", function(d) { return (d.totalLength/8); })
          .text(function(d) {return d.properties.name});

Деление на 8 работает неплохо. Единственная проблема сейчас в том, что какой-то текст не умещается, но 90% выглядят отлично, а рассчитанный размер отлично работает.

В своих случаях я решил самостоятельно рассчитать размер a для каждого элемента. Это намного проще, но, возможно, не является идеальным решением.

person kwoxer    schedule 03.02.2015