D3 Координати на четката под мащаба на CSS трансформация

D3 четката не функционира правилно при css трансформация. Когато svg е под елемент div и елементът div се трансформира с помощта на CSS мащаб, операцията с четка показва грешни координати.

За да демонстрирате този случай, ето jsFiddle.

Това е проста модификация от пример за Brushable Network на Bostock.

Това, което направих, беше просто да сложа SVG в елемента div и да направя увеличение на елемента div 50%, използвайки CSS transform scale(0.5). И координатите на четкане не се актуализират поради мащабиране.

#test {
transform: scale(0.5);
}

Благодаря.

Деок


person intuinno    schedule 08.07.2015    source източник
comment
Можете да намерите подобен проблем за събитие с единична мишка тук. Той предлага използването на следния код за трансформиране между оригиналните координати. Но би било чудесно, ако някой може да посочи подходящия подход за събитието с четка.   -  person intuinno    schedule 08.07.2015
comment
Вашият jsfiddle ми дава грешка.   -  person Lars Kotthoff    schedule 08.07.2015
comment
Съжалявам, правилната връзка е jsfiddle.net/intuinno/5cpgkqhu   -  person intuinno    schedule 09.07.2015


Отговори (2)


Ако използвате трансформация, базирана на svg:

transform="scale(0.5)"

Тогава ще си играе добре с четката:

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

svg = svg.append("g")
    .attr("transform","scale(0.5)");

Актуализиран цигулка.

За да коригирате изчисленията, имате нужда от две неща.

1.) Мащабирайте степента право срещу div:

.extent {
   transform: scale(2);
}

2.) Коригирайте изчисленията на степента:

   .on("brush", function() {
      var extent = d3.event.target.extent();
      node.classed("selected", function(d) {
        return extent[0][0] <= d.x && d.x < extent[1][0] && 
               extent[0][1] <= (d.y/2) && (d.y/2) < extent[1][1]; // scale y opposite div transform
      });
   });

Нов пример тук.

person Mark    schedule 08.07.2015
comment
Благодаря ви за любезния отговор. Въпреки това нямам достъп до svg поради настройките в моя проект. Така че търся решението за трансформацията, базирана на css. - person intuinno; 08.07.2015
comment
@intuinno, нямате достъп до svg? ако оставите трансформацията в CSS, ще трябва да я вземете предвид при изчисленията на четката. - person Mark; 09.07.2015
comment
да Звучи странно, че нямам достъп до svg. Моята ситуация е, че използвам d3 визуализация вътре в обекта jsplumb. Обектът jsplumb обработва мащабирането на div с помощта на css трансформация. Трябва да изчеткам някакъв регион на svg в div. Така че не мога да приложа вашето решение. Бихте ли ме уведомили повече за вземането му в изчислението на четката? - person intuinno; 09.07.2015
comment
@intuinno, виж нов отговор. - person Mark; 09.07.2015

Ако използвате CSS трансформация, трябва да я приложите към всички класове, свързани с възли:

 .node {
  stroke: #fff;
  stroke-width: 1.5px;
  transform: scale(0.5);
 }

 .node .selected {
        stroke: red;
  }

.link {
   stroke: #999;
     transform: scale(0.5);
  }

.brush .extent {
  fill-opacity: .1;
  stroke: #fff;
  shape-rendering: crispEdges;
  transform: scale(0.5);
}

Когато добавите transform: scale(0.5);, можете да изчеткате целия възел. Опитайте от ляво надясно над позицията на възела.

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


    graph.links.forEach(function(d) {
        d.source = graph.nodes[d.source];
        d.target = graph.nodes[d.target];
    });

    var link = svg.append("g")
        .attr("class", "link")
        .selectAll("line")
        .data(graph.links)
        .enter().append("line")
        .attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    var node = svg.append("g")
        .attr("class", "node")
        .selectAll("circle")
        .data(graph.nodes)
        .enter().append("circle")
        .attr("r", 4)
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });

    var brush = svg.append("g")
        .attr("class", "brush")
        .call(d3.svg.brush()
            .x(d3.scale.identity().domain([0, width]))
            .y(d3.scale.identity().domain([0, height]))
            .on("brush", function() {
                var extent = d3.event.target.extent();
                node.classed("selected", function(d) {
                    return extent[0][0] <= d.x && d.x < extent[1][0]
                        && extent[0][1] <= d.y && d.y < extent[1][1];
                });
            }));

Завършете jsfiddle тук.

person Gabriel    schedule 08.07.2015
comment
Благодаря ви за отговора Въпреки това не съм сигурен, че сте споделили правилната връзка jsfiddle. В jsfiddle, който споделихте, грешката все още е там. Бихте ли проверили отново? Благодаря. - person intuinno; 09.07.2015
comment
Това е правилната връзка, тъй като domain([0, width]) най-добрата четка е отляво надясно. започнете от лявата позиция и плъзнете до дясната позиция на страницата, четката ще работи правилно. - person Gabriel; 09.07.2015
comment
Не, според мен координатите на четката са малко по-различни от позицията на мишката. Мисля, че това не решава проблема с четката с CSS transform. Съжалявам. - person intuinno; 09.07.2015