Вопрос по d3.js, angularjs – D3 в приложении AngularJS

42

Я пытаюсь создать свое первое приложение с AngularJS. Это выглядит аккуратно, но здесь много абстракций, и мне просто любопытно, есть ли у кого-нибудь совет относительно самого идиоматического способа использования угловой методологии для обновления визуалов, созданных с помощью d3js.

Спасибо, п.н.

Ваш Ответ

4   ответа
0

Если мы используем d3 внутри директивы для генерации элементов с другими директивами Angular (как я думаю, вы найдете это довольно распространенное требование), вы можете вызвать$compile в конце этапа ОБНОВЛЕНИЕ процесса рендеринга сcall() метод. Вот так (при условии, что мы рендерим несколько кругов):

mySvg.selectAll("circle")
                .data(scope.nodes)
                .enter()
                .append("circle")
                .attr("someDirective")
                .call(function(){
                    $compile(this[0].parentNode)(scope);
                });
0

Вы также можете следовать этому уроку / скринкасту, чтобы увидеть, как использовать D3 с угловым. Он немного другой, потому что он использует библиотеку-обертку вокруг d3, которая называется рикша, которая обеспечивает некоторые графические особенности, но подход точно такой же:

http://tagtree.tv/d3-with-rickshaw-and-angular

34

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

http://docs.angularjs.org/guide/directive

То, что вы хотите сделать, это сообщить угловому моменту, когда данные были обновлены с помощью «другого» рамки. Если угловой не нужно знать, тогда ваша задача проще.

Вот пример, который работает с SVG, его удивительным

http://sullerandras.github.com/SVG-Sequence-Diagram/

Вот пример, который оборачивает TinyMCE

http://jsfiddle.net/programmieraffe/kjsEV/

3

Также есть возможность вставить синтаксис панели управления AngularJS непосредственно в сгенерированные элементы d3:

var containerDiv = d3.select(targetCSSSelectorForADiv);
var svgG = containerDiv
                                .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 + ")")

 svgG.selectAll(".tempclass").data(scope.circles).enter()
                                .append("circle")
                                .attr("class", "tempclass")
                                .attr("cx", function (d, i) { return "{{circles[" + i + "].cx}}" })
                                .attr("cy", function (d, i) { return "{{circles[" + i + "].cy}}" })
                                .attr("r", function (d, i) { return "{{circles[" + i + "].radius}}" })
                                .attr("ng-style", function (d, i)
                                {
                                    return "{fill: circles[" + i + "].circolor"
                                        + ", opacity: circles[" + i + "].opa"
                                        + ", 'stroke-width': 4*circles[" + i + "].opa"
                                        + ", stroke: 'red' }";
                                });

Обратите внимание на следующее: область действия - это фактически объект угловой области, переданный из директивы в функцию рендеринга. Установка стиля элемента на & quot; {{...}} & quot; Выражение не будет работать, поэтому я использую & quot; ng-style & quot; атрибут здесь.

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

//the target div is the one with the angular ng-controller attribute 
//this you can call at the end of the d3 rendering call from within the render function
angular.bootstrap(document.getElementById("d3ContainerDivID"), ['d3App']);

Другой способ это:

//and this could be called from the directive that triggered the rendering or
//some other place that could have the angular $compile service injected
$compile(document.getElementById("d3ContainerDivID"))(scope);

Теперь вы можете изменить элементы области видимости, и они будут напрямую обновлены до ваших элементов d3, в данном случае кружков svg. В угловом контроллере (который создается до запуска директивы, которая рисует объекты d3).

    $scope.circles = [];
    for (var i = 0; i < 50; i++)
    {
        $scope.circles.push(new Circle());
    }
    setInterval(function ()
    {
        $scope.circles.forEach(function (d, i) { $scope.circles[i] = new Circle(); });
        $scope.$digest();
    }, 2000);

Обратите внимание на вызов $ digest, который сообщает angular переварить измененную область видимости; это изменит значения на элементах svg circle. За что-то вроде анимации и тому подобного, d3 теперь больше не несет ответственности, и его придется реализовать вручную или использовать другой шаблон.

Похожие вопросы