Поиск…


Система координат

В нормальной математической системе координат точка x = 0, y = 0 находится в нижнем левом углу графика. Но в системе координат SVG эта точка (0,0) находится в верхнем левом углу «холста», она похожа на CSS, когда вы указываете позицию абсолютной / фиксированной и используете верхнюю и левую кнопки для управления точную точку элемента.

Важно иметь в виду, что по мере увеличения y в SVG формы перемещаются вниз.

Предположим, мы собираемся создать диаграмму рассеяния с каждой точкой, соответствующей значению оси и значению y. Чтобы масштабировать значение, нам нужно установить домен и диапазон следующим образом:

d3.svg.scale()
  .range([0, height])
  .domain([0,max])

Однако, если вы просто сохраните такие настройки, точки будут основываться на верхнем горизонтальном краю, а не на нижней горизонтальной линии, как и ожидалось.

Хорошая вещь о d3 заключается в том, что вы можете легко изменить это путем простой настройки в настройке домена:

d3.scale.linear()
  .range([height, 0])
  .domain([0, max])

С приведенным выше кодом нулевая точка домена соответствует высоте SVG, которая является нижней строкой диаграммы в глазах зрителя, между тем максимальное значение исходных данных будет соответствовать нулевой точке SVG система координат, максимальное значение для зрителей.

Элемент

<rect> представляет прямоугольник, помимо эстетических свойств, таких как штрих и заполнение, прямоугольник должен определяться по местоположению и размеру.

Что касается местоположения, он определяется атрибутами x и y. Местоположение расположено относительно родителя прямоугольника. И если вы не укажете атрибут x или y, по умолчанию будет 0 относительно родительского элемента.

После того, как вы укажете местоположение или, вернее, «начальную точку» прямоугольника, следующая вещь должна указать размер, который необходим, если вы хотите нарисовать sth на холсте, то есть, если вы не укажите атрибуты размера или значение установлено как 0, вы не увидите ничего на холсте.

Случай: диаграмма стержня

Продолжайте с первым сценарием оси y, но на этот раз попробуем нарисовать гистограмму.

Предполагая, что настройка масштаба y одинакова, ось y также правильно настроена, единственная разница между диаграммой рассеяния и этой гистограммой заключается в том, что нам нужно указать ширину и высоту, в частности, высоту. Чтобы быть более конкретным, мы уже получили «отправную точку», остальное - использовать такие вещи, как для высоты:

.attr("height", function(d){
  return (height - yScale(d.value))
})

Элемент

Элемент <svg> является корневым элементом или холстом, когда мы рисуем на нем графики.

Элементы SVG могут быть вложены друг в друга, и таким образом формы SVG могут быть сгруппированы вместе, между тем все формы, вложенные внутри элемента, будут расположены относительно его охватывающего элемента.

Одно может потребоваться упоминание о том, что мы не можем гнездиться внутри другого, это не сработает.

Случай: несколько диаграмм

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

Следует иметь в виду, что мы не можем использовать атрибут transform, но мы можем использовать x, y для позиции.

Элемент

SVG в настоящее время не поддерживает автоматические разрывы строк или перенос слов, вот когда приходит на помощь. элемент позиционирует новые строки текста по отношению к предыдущей строке текста. И используя dx или dy в каждом из этих промежутков, мы можем поместить слово относительно слова перед ним.

Случай: аннотация по осям

Например, когда мы хотим добавить аннотацию к y Ax:

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
.append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", 6)
  .attr("dy", ".71em")
  .style("text-anchor", "end")
  .text("Temperature (ºF)");

Правильное добавление элемента SVG

Это довольно распространенная ошибка. Например, вы создали элемент rect , например, на гистограмме, и вы хотите добавить текстовую метку (скажем, значение этого бара). Таким образом, используя ту же переменную, которую вы использовали для добавления rect и определения его позиции x и y , вы добавляете свой text элемент. Очень логично, вы можете подумать. Но это не сработает.

Как происходит эта ошибка?

Давайте посмотрим конкретный пример, очень простой код для создания гистограммы ( скрипка здесь ):

var data = [210, 36, 322, 59, 123, 350, 290];

var width = 400, height = 300;

var svg = d3.select("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height);

var bars = svg.selectAll(".myBars")
    .data(data)
    .enter()
    .append("rect");

bars.attr("x", 10)
    .attr("y", function(d,i){ return 10 + i*40})
    .attr("width", function(d){ return d})
    .attr("height", 30);

Что дает нам этот результат:

введите описание изображения здесь

Но вы хотите добавить некоторые текстовые элементы, возможно, простое значение для каждого бара. Итак, вы делаете это:

bars.append("text")
   .attr("x", 10)
   .attr("y", function(d,i){ return 10 + i*40})
   .text(function(d){ return d});

И, вуаля: ничего не происходит! Если вы сомневаетесь в этом, вот скрипка .

«Но я вижу бирку!»

Если вы проверите SVG, созданный этим последним кодом, вы увидите следующее:

введите описание изображения здесь

И в этот момент многие говорят: «Но я вижу текстовый тег, он добавлен!». Да, но это не значит, что это сработает. Вы можете добавить что угодно ! См. Это, например:

svg.append("crazyTag");

Это даст вам следующий результат:

<svg>
    <crazyTag></crazyTag>
</svg>

Но вы не ожидаете результата только потому, что там есть тэг, не так ли?

Приложите элементы SVG правильно

Узнайте, какие элементы SVG могут содержать детей, читая спецификации . В нашем последнем примере код не работает, потому что элементы rect не могут содержать text элементы. Итак, как отображать наши тексты?

Создайте другую переменную и добавьте text в SVG:

var texts = svg.selectAll(".myTexts")
    .data(data)
    .enter()
    .append("text");

texts.attr("x", function(d){ return d + 16})
    .attr("y", function(d,i){ return 30 + i*40})
    .text(function(d){ return d});

И это результат:

введите описание изображения здесь

И вот скрипка .

SVG: порядок рисования

Это может быть неприятно: вы делаете визуализацию с помощью D3.js, но прямоугольник, который вы хотите сверху, спрятан за другим прямоугольником, или линия, которую вы планировали находиться за некоторым кругом, на самом деле находится над ней. Вы пытаетесь решить это, используя z-index в своем CSS, но он не работает (в SVG 1.1).

Объяснение простое: в SVG порядок элементов определяет порядок «живописи», а порядок рисунка определяет, кто идет сверху.

Элементы в фрагменте документа SVG имеют неявный порядок рисования, причем первые элементы в фрагменте документа SVG получаются «раскрашенными» первыми. Последующие элементы окрашиваются поверх ранее окрашенных элементов.

Итак, предположим, что у нас есть этот SVG:

<svg width="400" height=200>
    <circle cy="100" cx="80" r="60" fill="blue"></circle>
    <circle cy="100" cx="160" r="60" fill="yellow"></circle>
    <circle cy="100" cx="240" r="60" fill="red"></circle>
    <circle cy="100" cx="320" r="60" fill="green" z-index="-1"></circle>
</svg>

У него четыре круга. Синий круг является первым, «расписанным», поэтому он будет резать все остальные. Тогда у нас есть желтый, затем красный, и, наконец, зеленый. Зеленый - последний, и он будет на вершине.

Вот как это выглядит:

введите описание изображения здесь

Изменение порядка элементов SVG с D3

Итак, можно ли изменить порядок элементов? Могу ли я сделать красный круг перед зеленым кружком?

Да. Первый подход, который вам нужно иметь в виду, - это порядок строк в вашем коде: сначала нарисуйте элементы фона, а затем в коде элементы переднего плана.

Но мы можем динамически изменять порядок элементов, даже после того, как они были нарисованы. Есть несколько простых функций JavaScript, которые вы можете написать, чтобы сделать это, но у D3 уже есть две приятные функции, selection.raise() и selection.lower() .

Согласно API:

selection.raise (): Вставляет каждый выбранный элемент в порядке, как последний дочерний элемент его родителя. selection.lower (): Повторно вставляет каждый выбранный элемент в порядке, в качестве первого дочернего элемента его родителя.

Итак, чтобы показать, как манипулировать порядком элементов в нашем предыдущем SVG, вот очень маленький код:

d3.selectAll("circle").on("mouseover", function(){
    d3.select(this).raise(); 
});

Что оно делает? Он выбирает все круги и, когда пользователь наводится на один круг, он выбирает этот конкретный круг и выводит его на передний план. Очень просто!

И вот JSFiddle с живым кодом.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow