2016-02-26 5 views
5

Я пытаюсь получить легенду о моем графике за пределами области диаграмм.d3.js Получить легенду Вне диаграммы

Вот поля:

var margin = {top: 50, right: 200, bottom: 50, left: 40}; 
     var width = 960 - margin.left - margin.right, 
      height = 500 - margin.top - margin.bottom; 

Сначала я создаю SVG:

var svg = d3.select("body").append("svg") 
      .attr("width", width + margin.left + margin.right) 
      .attr("height", height + margin.top + margin.bottom) 
      .append("g") 
       .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

Таким образом, от моего понимания, я теперь есть элемент SVG холст и AG внутри него, который держит диаграмма. Я пытаюсь добавить больше к правильному краю, поэтому я могу получить некоторое пространство между холстом svg и g, добавленным к нему, которое содержит диаграмму. Затем я хочу поставить свою легенду в этом пустом месте.

Вот где я добавить свою легенду:

//add legend 
      var legend = svg.append("g") 
       .attr("class", "legend") 
       .attr("height", 300) 
       .attr("width", 200) 
       .attr("transform", "translate(-1000,50"); 

Хотя я и добавления к элементу SVG, то добавление к г в элементе SVG. Поэтому, независимо от того, насколько я переводил его или пытаюсь заставить его двигаться дальше по экрану, он никогда не проходит ширину внутреннего g.

При обнаружении неисправностей я вижу, что внешний элемент SVG имеет высоту 960 и ширину 500. Приложенная к ней g имеет преобразование/перевод 40,50. Ширина заканчивается 839px на 433.223px (не уверен, что я это понимаю). Внешний svg имеет кучу пространства прямо сейчас из-за встроенного поля.

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

Я не могу ни работать, ни знать, какой путь лучше.

+0

g элементы не имеют атрибутов ширины и высоты, они всегда должны содержать своих детей. –

+0

Ваш первый оператор не возвращает «svg», а вместо этого возвращает добавленный «g». Вот почему ваше заявление о легенде гнездится в следующем g под первым. d3 использует цепочку методов, поэтому вызов .append() возвращает новый выбор. Исправьте, разбив свой оператор создания svg на два отдельных оператора, один из которых создает «svg», а затем другой создает «g» для вашей диаграммы. –

ответ

2

Обратите внимание, что переменная svg в настоящее время отнесены к <g> вложен внутри <svg>

svg = d3.select("body").append("svg") 
     .attr("width", width + margin.left + margin.right) 
     .attr("height", height + margin.top + margin.bottom) 
     .append("g") // <-- This is what svg is currently being assigned to 
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

И так, когда вы позже выполнить var legend = svg.append("g"), вы на самом деле добавление легенды как ребенок вышеупомянутого <g>. Вот что вы описали в инструментах dev.

Одним из следствий является то, что вы translate() преобразование применяется к внешнему <g> влияет на внутреннюю <g> (то есть перевод innter <g> из legend добавляется к наружной <g>).

Скорее всего, вы хотите разделить вещи так:

var svg = d3.select("body").append("svg") 
      .attr("width", width + margin.left + margin.right) 
      .attr("height", height + margin.top + margin.bottom); 

var inner = svg.append("g") 
       .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

Затем измените свой код, чтобы сделать существующую таблицу в inner, а не svg.

В результате var legend = svg.append("g") будет добавлять легенду как родственный inner, и любой перевод вы подаете заявку на legend будет относительно верхнего левого в формате SVG (как в отличие от верхнего левого inner «s, которое переводится на margin)

И вероятно, что вы хотите перевести legend так:

var legend = svg.append("g") 
       .attr("transform", "translate(" + width - margin.right + "," + margin.top + ")"); 

Это перемещает легенду в правой части графика, мИНУС margin.right. Таким образом, вы можете настроить margin.right, чтобы создать достаточно места для legend.

Наконец, следует отметить, что вызов

legend 
    .attr("height", 300) 
    .attr("width", 200) 

ничего не делает, потому что для SVG <g>, не существует способ явно установить ширину и высоту. В любом случае, это не означает многого, потому что у svg нет «потокового» поведения макетов html. Ширина и высота, показанные в инструментах dev, - это неявные границы, связанные с границами дочерних элементов <g>. (Если необходимо, есть способ получить эти вычисленные оценки в javascript, используя функцию getBBox()).

-1

, глядя на код, который вы указали, вы на самом деле прикрепление легенда вар к вашей группе «г», вместо «SVG»,
var legend = svg.append("g")

в этой линии вы говорите d3, чтобы получить переменную легенды к «г», которая добавляет к SVG, если я правильно понимаю, вы должны попробовать что-то вроде этого:

var legend = svg.selectAll(".legend") 
.enter().append("g") 

создать еще одну группу «г» для ваших легенд. Прошу прощения за мой плохой английский.

Смежные вопросы