d3 перетащите несколько текстовых элементов в группу SVG - PullRequest
1 голос
/ 07 марта 2019

Я новичок в использовании d3.js.Я пытаюсь добавить несколько текстовых элементов в группу SVG.С этим я хочу иметь возможность перетаскивать группу из нескольких текстов.
Так, например:

    export function testNode (config = {}) {
    let { svg, rectX, rectY, text1, text2 } = config
    var data = [{ x: rectX, y:rectY, label: text1, label2: text2, labelX: rectX + 100, labelY: rectY + 200, labelX2: rectX + 300, labelY2: rectY + 300 }]
        var group = svg.append("g")
                .selectAll("g")
        .data(data)
        .enter()
                .append("g")
                .attr("transform",
                    "translate(" + 0 + "," + 0 + ")")
                .call(d3.drag()
                    .on("start", dragstarted)
                    .on("drag", dragged)
                    .on("end", dragended));

        group.append("text")
                .data(data)
                .attr("x", (d) => { return d.labelX })
                .attr("y", (d) => { return d.labelY })
                .attr("font-size", "1em")
                .attr("color", "black")
                .text((d) => { return d.label });

            group.append("text")
                .data(data)
                .attr("x", (d) => { return d.labelX2 })
                .attr("y", (d) => { return d.labelY2 })
                .attr("font-size", ".75em")
                .attr("color", "black")
                .attr("class", "label")
                .text((d) => { return d.metricValue_01 });

function dragStarted() { 
 d3.select(this).raise().classed("active", true);
}

function dragged(d) {
d3.select(this).select("text")
 .attr("x", d.labelX = d3.event.x + 10)
 .attr("y", d.labelY = d3.event.y + 20);

d3.select(this).select("text")
 .attr("x", d.labelX2 = d3.event.x + 10)
 .attr("y", d.labelY2 = d3.event.y + 20);

function dragended() {
    d3.select(this).classed("active", false);
}

Если я использую метод selectAll, текст объединяется вместе.Поэтому мне было интересно, могу ли я перетащить текстовую группу в правильное положение на основе заданной мной координаты (при перетаскивании).В любом случае, пожалуйста, дайте мне знать, если мне нужно предоставить дополнительную информацию.Спасибо

1 Ответ

0 голосов
/ 07 марта 2019

Если вы хотите выбрать вторую метку, но не хотите использовать selectAll, поскольку она выбирает обе, вы можете задать классы меток при добавлении и выбрать их при перетаскивании:

d3.select(this).select(".bigLabel")
 .attr("x", d.labelX = d3.event.x + 10)
 .attr("y", d.labelY = d3.event.y + 20);

d3.select(this).select(".smallLabel")
 .attr("x", d.labelX2 = d3.event.x + 10)
 .attr("y", d.labelY2 = d3.event.y + 20);

Хотя, конечно, это установит одинаковые координаты для обеих меток, если вы не укажете смещение, как показано ниже:

var data = [
 { x: 100, x2: 100, y: 100, y2: 120, label: "label1", value: "17%" },
 { x: 300, x2: 300, y: 200, y2: 220, label: "label2", value: "83%" },
 { x: 100, x2: 100, y: 200, y2: 220, label: "label3", value: "11%" },
 { x: 300, x2: 300, y: 100, y2: 120, label: "label4", value: "96%" }
];

var svg = d3.select("svg");

var labels = svg.selectAll("g")
  .data(data)
  .enter()
  .append("g")
  .call(d3.drag()
  .on("drag",drag));
    
labels.append("text")
  .attr("font-size", "1em")
  .attr("x", function(d) { return d.x;})
  .attr("y", function(d) { return d.y;})
  .text(function(d) { return d.label; })
  .attr("class","label1");
     
labels.append("text")
  .attr("font-size", ".75em")
  .attr("x", function(d) { return d.x2;})
  .attr("y", function(d) { return d.y2;})  
  .text(function(d) { return d.value; })
  .attr("class","label2");

function drag(d) {
  var x = d3.event.x;
  var y = d3.event.y;
  d3.select(this)
    .select(".label1")
    .attr("x", function(d) { return d.x = x; })
    .attr("y", function(d) { return d.y = y; })
  d3.select(this)
    .select(".label2")
    .attr("x", function(d) { return d.x2 = x; })
    .attr("y", function(d) { return d.y2 = y + 20; })    
    
}
text {
  text-anchor:middle;
  cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="400"></svg>

Я не буду слишком углубляться в альтернативу, но она применяет перетаскивание к g, располагая обе текстовые метки нав то же время.Это может справиться с неравномерным интервалом между метками братьев и сестер проще, чем указано выше:

var data = [
 { x: 100, y: 100, label: "label1", value: "17%" },
 { x: 300, y: 200, label: "label2", value: "83%" },
 { x: 100, y: 200, label: "label3", value: "11%" },
 { x: 300, y: 100, label: "label4", value: "96%" }
];

var svg = d3.select("svg");

var labels = svg.selectAll("g")
  .data(data)
  .enter()
  .append("g")
  .attr("transform",function(d) { 
    return "translate("+[d.x,d.y]+")"; 
  })
  .call(d3.drag().on("drag", drag));
    
labels.append("text")
  .attr("font-size", "1em")
  .text(function(d) { return d.label; });
     
labels.append("text")
  .attr("font-size", ".75em")
  .text(function(d) { return d.value; })
  .attr("dy", "1em")
  
function drag(d) {
  d3.select(this)
    .attr("transform","translate("+[d.x=d3.event.x,d.y=d3.event.y]+")"); 
}
text {
  text-anchor: middle;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="400"></svg>

Также нет необходимости использовать append("text").data(data), это ничего не делает - ваши данные уже привязаны к новымдобавленный элемент

Наконец, вы можете выполнить эту работу с помощью selectAll (), если вы устанавливаете атрибуты, используя второй параметр любой предоставленной функции при установке атрибутов: (d,i)=>... i - индексэлемент, так что если ваши метки братьев и сестер регулярно разнесены, вы можете использовать что-то вроде:

var data = [
 { x: 100, y: 100, label: "label1", value: "17%" },
 { x: 300, y: 200, label: "label2", value: "83%" },
 { x: 100, y: 200, label: "label3", value: "11%" },
 { x: 300, y: 100, label: "label4", value: "96%" }
];

var svg = d3.select("svg");

var labels = svg.selectAll("g")
  .data(data)
  .enter()
  .append("g")
  .call(d3.drag()
  .on("drag",drag));
    
labels.append("text")
  .attr("font-size", "1em")
  .attr("x", function(d) { return d.x;})
  .attr("y", function(d) { return d.y;})
  .text(function(d) { return d.label; })
     
labels.append("text")
  .attr("font-size", ".75em")
  .attr("x", function(d) { return d.x;})
  .attr("y", function(d) { return d.y + 20;})  
  .text(function(d) { return d.value; })

function drag(d) {
  var x = d3.event.x;
  var y = d3.event.y;
  d3.select(this)
    .selectAll("text")
    .attr("x", function(d) { return d.x = x; })
    .attr("y", function(d,i) { d.y = y;
      return d.y + i * 20;
    })
}
text {
  text-anchor:middle;
  cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="400"></svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...