0

我正在用javascript制作一个应用程序来处理来自json对象的数据并显示它并以漂亮的方式过滤它。示例 1 示例 2

然而,当我深入到下一个选择时,我遇到了各种问题。问题是我的onclick事件仍然同步到旧节点列表而不是新节点。正如您从屏幕截图中看到的那样,让花朵出现在正确的节点上曾经是一个问题,但我通过将 ids 映射到坐标发现了一个肮脏的 hack。然而,我想最终解决这个问题,因为这真的很令人沮丧。

http://shrani.si/f/2E/Tb/1bQrSkhW/firstlevel.png

http://shrani.si/f/3u/dO/4uPNhGCt/secondlevel.png

正如您所看到的,图表本身会更新,但点击事件仍然说我点击了一个不存在的节点。

我不妨粘贴尽可能多的代码,所以这里是主要部分:

currentRows = []
shistory = []
keyhistory = []
prototypeKeys = Object.keys(podatki)

//For flower selection
openSubselection = false;
openNode = null;

firstkeyid = 3;
currentKey = prototypeKeys[firstkeyid];
unavailableKeys = [];
//availableKeys = {0 : {name: nameofkey, available: true}}
availableKeys = genAvailable(prototypeKeys, firstkeyid)


keys = ["domenskiProstor", "sistemNaziv"]

selectedNodes = []

kc = 0
first_key = keys[kc]

for (var k = 0; k < Object.keys(podatki[first_key]).length; k++) {
  var templ = []
  for (key in podatki)
    templ.push(podatki[key][k]);
  currentRows.push(templ)
}

shistory.push(currentRows)
keyhistory.push(first_key)
nodes = genNodes(first_key)
edges = genEdges(nodes)

var container = document.getElementById('mynetwork');
var data = {
  nodes: nodes,
  edges: edges
};

var width = 1000;
var height = 800;

var options = {
  width: width + 'px',
  height: height + 'px',
  nodes: {
    shape: 'ellipse'
  },
  edges: {
    smooth: true
  },
  physics: false,
  interaction: {
    dragNodes: true,// do not allow dragging nodes
    zoomView: true, // do not allow zooming
    dragView: true  // do not allow dragging
  }
};

var network = new vis.Network(container, data, options);
centerNetwork();

function setEvents() {
  network.on('click', function (properties) {
    //console.log(network.data.nodes)
    //console.log(openSubselection)
    //najdi v svojem novem seznamu GENIUS!
    // https://stackoverflow.com/questions/35563147/vis-js-network-graph-not-updating-with-node-changes

    var ids = properties.nodes;
    var clickedNode = nodes.get(ids)[0];
    console.log(nodes);

    var newl = []
    try {
      if (openSubselection) {
        if (clickedNode.id < 0) {
          for (ind in currentRows)
            if (currentRows[ind].indexOf(selectedNode.label) > -1)
              newl.push(currentRows[ind]);

          currentRows = newl;
          shistory.push(currentRows);
          //select the next key and do house keeping / house keeping exists also when we exist etc. - TODO
          //main problem with available keys now - will fix in future

          var somekey = clickedNode.label;


          //make current key unavailable

          for (var k in availableKeys)
            if (availableKeys[k].name == somekey) {
              availableKeys[k].available = false;
              currentKey = availableKeys[k].name
            }

          kc++
          openSubselection = false;
          openNode = null;
          updateNetwork()
          updateTable()

        } else {
          throw "flower closing"
        }
      } else {

        if (clickedNode.id != 1) {
          console.log(clickedNode.label)
          console.log(clickedNode.id)
          if (clickedNode.title == 1) {
            console.log("just 1 lool");
          } else {

            openSubselection = true;
            selectedNode = clickedNode;

            //get available keys
            var ak = []
            for (var k in availableKeys)
              if (availableKeys[k].available == true)
                ak.push(availableKeys[k].name);

            var na = ak.length;
            var angle = (360 / na) * 0.0174532925
            for (var k = -1; k >= -na; k--) {

              data.nodes.update({ id: k, y: (Math.sin((-k) * angle) * 100) + ncords[clickedNode.id].y, x: (Math.cos((-k) * angle) * -100) + ncords[clickedNode.id].x, label: ak[(k * -1) - 1] })
              data.edges.update({ id: k, from: clickedNode.id, to: k, arrows: 'to' });
            }

            network.setData({ nodes: data.nodes, edges: data.edges })
          }
        }
      }
    } catch (err) {
      deleteFlower();
    }
  });

  network.on('doubleClick', function (properties) {
    var ids = properties.nodes;
    var clickedNode = nodes.get(ids)[0];

    if (clickedNode.id == 1) {
      if (shistory.length > 1) {
        shistory.pop()
        currentRows = shistory[shistory.length - 1]

        //go back - TODO
        //currentKey = unavailableKeys.pop();
        for (var k in availableKeys)
          if (currentKey == availableKeys[k].name)
            availableKeys[k].available = true;

        currentKey = clickedNode.label;
        console.log("going back and currentKey became " + clickedNode.label)
        //make current key available again
        //availableKeys.push(currentKey) //this pushes wrong key 

        kc--
        updateNetwork()
        updateTable()
      }
    } else {
    }
  })
}
setEvents();

以下是我用来更新的一些功能:

  ncords = {}

  function genNodes(key) {
    var ns = []
    var c = 1
    var fn = { id: c, label: key, title: "Klikni za vrnitev na prejšnjo kategorijo" }
    var seen = {}
    c = c + 1
    ns.push(fn)

    var keyi = Object.keys(podatki).indexOf(key);

    for (var x in currentRows) {
      if (!Object.keys(seen).includes(currentRows[x][keyi])) {
        ns.push({ id: c, label: currentRows[x][keyi] })
        c = c + 1
        seen[currentRows[x][keyi]] = 1
      } else {
        seen[currentRows[x][keyi]]++
      }
    }

    for (var en in ns)
      ns[en].title = seen[ns[en].label];

    return new vis.DataSet(ns)
  }

  function genEdges(ns) {
    ed = []
    for (k in ns["_data"])
      if (k != 1)
        ed.push({ from: 1, to: k, arrows: 'to', length: 300 });

    for (var x = -1; x >= -prototypeKeys.length; x--)
      ed.push({ id: x, from: 0, to: x, arrows: 'to' });

    return new vis.DataSet(ed)
  }

  function centerNetwork() {

    network.moveTo({
      position: { x: -500, y: -400 },
      offset: { x: -width / 2, y: -height / 2 },
      scale: 1,
    })

    data.nodes.update({ id: 1, x: 0, y: 0 })
    ncords[1] = { x: 0, y: 0 }
    na = data.nodes.length
    //Conversion to radians
    angle = (360 / na) * 0.0174532925
    for (var k = 2; k <= na; k++) {
      var newx = Math.cos((k - 1) * angle) * -350
      var newy = Math.sin((k - 1) * angle) * 350
      data.nodes.update({ id: k, y: newy, x: newx })
      ncords[k] = { x: newx, y: newy }
    }

    var edgs = genEdges(nodes);

    network.setData({ nodes: data.nodes, edges: edgs })
    //network = new vis.Network(container,{ nodes: data.nodes, edges: edgs },options)
    //setEvents();
  }

  function updateNetwork() {
    console.log("next key used when updating " + currentKey)
    var nodes = genNodes(currentKey)
    data = { nodes: nodes, edges: genEdges(nodes) }
    //network = new vis.Network(container, data, options);
    network.setData(data)
    centerNetwork();
  }

  function updateTable() {
    var insides = document.getElementById("table1").innerHTML
    for (var k in currentRows)
      var en = currentRows[k]
  }

  function deleteFlower() {
    openSubselection = false;
    openNode = null;
    for (var j in data.nodes["_data"]) {
      var node = data.nodes["_data"][j];
      if (node.id < 0) {
        data.nodes.remove(node.id)
        data.edges.update({ id: node.id, })
      }
    }
  }

  function genAvailable(aks, id) {
    var neav = [];
    for (var k = 0; k < aks.length; k++) {
      if (k == id) {
        neav[k] = { name: aks[k], available: false };
      } else {
        neav[k] = { name: aks[k], available: true };
      }
    }

    return neav;
  }

我想我应该以某种方式动态地将我的事件处理程序放在某个地方,但我不确定如何并且正在寻找一些好的建议。

4

0 回答 0