SORU
2 Mart 2012, Cuma


Yeni düğümler yönelik Kuvvet düzeni ekleme

Yığın Taşması ilk soru, sabırlı ol! D3.js ama sürekli başkaları ile gerçekleştirmek mümkün ne hayran olmuş yeni duyuyorum... ve ne kadar az kendim ile yapmak mümkün oldum neredeyse gibi hayret! Açıkça tür ruhlar burada bana ışığı göster umuyorum öyle bir şey grokking, ben değilim.

Benim niyetim şudur: yapan yeniden kullanılabilir bir javascript işlevi yapmaktır

  • Zorla yönettiği bir boş belirtilen bir DOM öğesi grafik oluşturur
  • Sen eklemek ve silmek etiketli görüntü taşıyan bu grafik için, onların arasında bağlantı belirtme düğümler

Bir başlangıç noktası olarak http://bl.ocks.org/950642 aldım, aslında düzen bir yana oluşturmak mümkün olmak istiyorum

enter image description here

Benim kod şöyle görünür:

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="jquery.min.js"></script>
    <script type="text/javascript" src="underscore-min.js"></script>
    <script type="text/javascript" src="d3.v2.min.js"></script>
    <style type="text/css">
        .link { stroke: #ccc; }
        .nodetext { pointer-events: none; font: 10px sans-serif; }
        body { width:100%; height:100%; margin:none; padding:none; }
        #graph { width:500px;height:500px; border:3px solid black;border-radius:12px; margin:auto; }
    </style>
</head>
<body>
<div id="graph"></div>
</body>
<script type="text/javascript">

function myGraph(el) {

    // Initialise the graph object
    var graph = this.graph = {
        "nodes":[{"name":"Cause"},{"name":"Effect"}],
        "links":[{"source":0,"target":1}]
    };

    // Add and remove elements on the graph object
    this.addNode = function (name) {
        graph["nodes"].push({"name":name});
        update();
    }

    this.removeNode = function (name) {
        graph["nodes"] = _.filter(graph["nodes"], function(node) {return (node["name"] != name)});
        graph["links"] = _.filter(graph["links"], function(link) {return ((link["source"]["name"] != name)&&(link["target"]["name"] != name))});
        update();
    }

    var findNode = function (name) {
        for (var i in graph["nodes"]) if (graph["nodes"][i]["name"] === name) return graph["nodes"][i];
    }

    this.addLink = function (source, target) {
        graph["links"].push({"source":findNode(source),"target":findNode(target)});
        update();
    }

    // set up the D3 visualisation in the specified element
    var w = $(el).innerWidth(),
        h = $(el).innerHeight();

    var vis = d3.select(el).append("svg:svg")
        .attr("width", w)
        .attr("height", h);

    var force = d3.layout.force()
        .nodes(graph.nodes)
        .links(graph.links)
        .gravity(.05)
        .distance(100)
        .charge(-100)
        .size([w, h]);

    var update = function () {

        var link = vis.selectAll("line.link")
            .data(graph.links);

        link.enter().insert("line")
            .attr("class", "link")
            .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; });

        link.exit().remove();

        var node = vis.selectAll("g.node")
            .data(graph.nodes);

        node.enter().append("g")
            .attr("class", "node")
            .call(force.drag);

        node.append("image")
            .attr("class", "circle")
            .attr("xlink:href", "https://d3nwyuy0nl342s.cloudfront.net/images/icons/public.png")
            .attr("x", "-8px")
            .attr("y", "-8px")
            .attr("width", "16px")
            .attr("height", "16px");

        node.append("text")
            .attr("class", "nodetext")
            .attr("dx", 12)
            .attr("dy", ".35em")
            .text(function(d) { return d.name });

        node.exit().remove();

        force.on("tick", function() {
          link.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; });

          node.attr("transform", function(d) { return "translate("   d.x   ","   d.y   ")"; });
        });

        // Restart the force layout.
        force
          .nodes(graph.nodes)
          .links(graph.links)
          .start();
    }

    // Make it all go
    update();
}

graph = new myGraph("#graph");

// These are the sort of commands I want to be able to give the object.
graph.addNode("A");
graph.addNode("B");
graph.addLink("A", "B");

</script>
</html>

Her zaman yeni bir düğüm eklemek, yeniden etiketleri mevcut tüm düğümleri; üst üste bu kazık ve işler çirkin bir hal almaya başlar. Yeni bir düğüm ekleme üzerine update() İşlev işlevi aradığımda, tüm veri kümesi için node.append(...). çünkü bu yüzden anlıyorum: Bunu nasıl yapacağımı çözemedimekliyorum tek düğüm... ve sadece görünüşte node.enter() tek bir yeni öğe oluşturmak için kullanabilirsiniz, bu düğüme bağlı gereken ek unsurlar için çalışmıyor. Bu durumu nasıl düzeltebilirim?

Bu konuda herhangi verebilecek olduğun herhangi bir yardım için teşekkür ederiz!

Ben hızlı bir şekilde daha önce sözü birkaç diğer hata kaynağı sabit çünkü düzenlenmiştir

CEVAP
3 Mart 2012, CUMARTESİ


Bu çalışma elde edememesi çok uzun saatler sonra, nihayet belgelere herhangi bir bağlantı olduğunu sanmıyorum bu bir demo tökezledi arasında: http://bl.ocks.org/1095795:

enter image description here

Bu demo sonunda bana sorunu çözmek yardımcı anahtarları içeriyordu.

enter() birden çok nesne ekleme bir değişken için enter() atama, ve sonra bunun için ekleme yapılabilir. Bu mantıklı. İkinci önemli kısmı, düğüm ve Bağlantı diziler grafik ve model düğümleri silinmiş ve eklendikçe uyumu gidecek force() -- aksi dayalı olmalıdır.

Bu ise yeni bir dizi yerine inşa edilirse, aşağıdaki attributes eksikliği meydana gelir:

  • dizin düğümler içinde dizi düğüm sıfır tabanlı dizini.
  • x - x-koordinatı geçerli düğüm pozisyon.
  • y - y-koordinatı geçerli düğüm pozisyon.
  • px - x-koordinat önceki düğüm yerleştirin.
  • py - y-koordinat önceki düğüm pozisyon.
  • sabit bir boolean olup olmadığını düğüm konumunu gösteren kilitlendi.
  • kilo - düğüm ağırlığı; ilgili bağlantıları sayısı.

Bu nitelikler kesinlikle force.nodes() ama eğer bu mevcut değilse, o zaman onlar için arama için gerekli değildirrastgeleilk çağrı üzerine force.start() tarafından başlatıldığını.

Eğer herkes merak ediyor, çalışma kodu bu gibi görünüyor:

<script type="text/javascript">

function myGraph(el) {

    // Add and remove elements on the graph object
    this.addNode = function (id) {
        nodes.push({"id":id});
        update();
    }

    this.removeNode = function (id) {
        var i = 0;
        var n = findNode(id);
        while (i < links.length) {
            if ((links[i]['source'] === n)||(links[i]['target'] == n)) links.splice(i,1);
            else i  ;
        }
        var index = findNodeIndex(id);
        if(index !== undefined) {
            nodes.splice(index, 1);
            update();
        }
    }

    this.addLink = function (sourceId, targetId) {
        var sourceNode = findNode(sourceId);
        var targetNode = findNode(targetId);

        if((sourceNode !== undefined) && (targetNode !== undefined)) {
            links.push({"source": sourceNode, "target": targetNode});
            update();
        }
    }

    var findNode = function (id) {
        for (var i=0; i < nodes.length; i  ) {
            if (nodes[i].id === id)
                return nodes[i]
        };
    }

    var findNodeIndex = function (id) {
        for (var i=0; i < nodes.length; i  ) {
            if (nodes[i].id === id)
                return i
        };
    }

    // set up the D3 visualisation in the specified element
    var w = $(el).innerWidth(),
        h = $(el).innerHeight();

    var vis = this.vis = d3.select(el).append("svg:svg")
        .attr("width", w)
        .attr("height", h);

    var force = d3.layout.force()
        .gravity(.05)
        .distance(100)
        .charge(-100)
        .size([w, h]);

    var nodes = force.nodes(),
        links = force.links();

    var update = function () {

        var link = vis.selectAll("line.link")
            .data(links, function(d) { return d.source.id   "-"   d.target.id; });

        link.enter().insert("line")
            .attr("class", "link");

        link.exit().remove();

        var node = vis.selectAll("g.node")
            .data(nodes, function(d) { return d.id;});

        var nodeEnter = node.enter().append("g")
            .attr("class", "node")
            .call(force.drag);

        nodeEnter.append("image")
            .attr("class", "circle")
            .attr("xlink:href", "https://d3nwyuy0nl342s.cloudfront.net/images/icons/public.png")
            .attr("x", "-8px")
            .attr("y", "-8px")
            .attr("width", "16px")
            .attr("height", "16px");

        nodeEnter.append("text")
            .attr("class", "nodetext")
            .attr("dx", 12)
            .attr("dy", ".35em")
            .text(function(d) {return d.id});

        node.exit().remove();

        force.on("tick", function() {
          link.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; });

          node.attr("transform", function(d) { return "translate("   d.x   ","   d.y   ")"; });
        });

        // Restart the force layout.
        force.start();
    }

    // Make it all go
    update();
}

graph = new myGraph("#graph");

// You can do this from the console as much as you like...
graph.addNode("Cause");
graph.addNode("Effect");
graph.addLink("Cause", "Effect");
graph.addNode("A");
graph.addNode("B");
graph.addLink("A", "B");

</script>

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Android Central

    Android Cent

    13 Kasım 2008
  • Bart Baker

    Bart Baker

    1 Aralık 2006
  • Max Lee

    Max Lee

    18 AĞUSTOS 2006