ZoomCharts перетаскивать

Я новичок в увеличении масштаба диаграмм (сетевые диаграммы) и у меня есть пара вопросов:

  • Я хотел бы иметь возможность перетаскивать узел и, когда пользователь удаляет его, обрабатывать событие. Есть способ сделать это? Я смотрел на событие onPositionChange, но это событие срабатывает несколько раз во время перетаскивания. Нет никакого способа узнать, когда пользователь фактически отбросил узел. По крайней мере, я не нашел способ определить это. Может быть, я что-то упустил.
  • У меня есть список элементов, которые я хочу перетаскивать на график и преобразовывать их в узлы. Это работает хорошо, за исключением того, что когда я использую событие dragend (внешнего элемента), я не могу правильно установить координаты x и y вновь созданного узла. Я попытался использовать ClientX и ClientY, LayerX и LayerY и другие координаты, предоставленные аргументами события DragEnd, но ни одна из них не размещает узел, на котором был отпущен курсор. Каков наилучший способ сделать это?

Вот мое определение диаграммы:

this.chart = new ZoomCharts.NetChart({
   container: chartContainer,
   area: {
    height: null,
    style: { fillColor: "rgba(14,33,40,0.9)" }
   },
   data: {
    preloaded: {
     "nodes": this.nodes,
     "links": this.links
    }
   },
   events: {
    onRightClick: function (event: any, args: any) {
     //set up the customer context menu
     event.preventDefault();
    },
    onHoverChange: function (event: any, args: any) {
     var content = "";
     if (args.hoverNode) {
      content = args.hoverNode.data.description;
     }
     infoElementVisible = !!content;
     infoElement.innerHTML = content;
     //delay the showing
     if (infoElementVisible) {
      setTimeout(() => {
       infoElement.style.display = infoElementVisible ? "block" : "none";
      }, 1000);
     } else {
      infoElement.style.display = infoElementVisible ? "block" : "none";
     }   
    }
   },
   style: {
    nodeStyleFunction: function (node: any) {
     if (node.selected) {
      node.lineColor = "yellow";
      node.lineWidth = 3;
      node.radius = node.radius * 1.5;
     } else {
      node.lineColor = null;
      node.lineWidth = 0;
     }

     node.userLock = true;
     node.label = node.data.name;
     if (node.data.auras == "Selection GNQ") {
      node.fillColor = "darkorange";
     } else {
      node.fillColor = "cyan";
     }
    },
    linkStyleFunction: function (link: any) {
     link.fromDecoration = "circle";
     link.toDecoration = "arrow";
     link.radius = 5;
    },
    node: {
     radius: 50,
     imageCropping: true,
     shadowBlur: 15,
     shadowColor: "#262626",
     fillColor: "rgba(44,233,233,0.8)"
    },
    nodeHovered: {
     shadowColor: "white",
     shadowBlur: 15,
    },
    nodeLabelScaleBase: 25,
    nodeSelected: {
     lineColor: null
    },
    selection: {
     fillColor: null,
     lineColor: null
    },
    nodeFocused: {
     shadowColor: "yellow",
     shadowBlur: 15
    },
    nodeLabel: {
     textStyle: { font: '24px Arial' }
    }
   },
   theme: ZoomCharts.NetChart.themes.dark,
   layout: {
    mode: 'static',
    nodeSpacing: 100
   }
  });

Спасибо.

2 ответа

Привет dpdragnev! Я из ZoomCharts, так что это своего рода авторитетный ответ.:)

  1. Да, вы правы, у нас нет способа сказать это. Хм... Я могу придумать один способ взлома, но я никогда не пробовал этого раньше, так что... Присоединяйте обработчики событий к элементу контейнера NetChart. Прикрепите их к pointerup, pointercancel, mouseup, touchend, touchcancel, MSPointerUp, MSPointerCancel, Это все события, которые прервут операцию перетаскивания. Возможно, вам придется проверить, какие из них доступны, и только прикрепить к ним. Вам необходимо прикрепить к capture фаза, потому что NetChart предотвратит образование пузырьков. Затем также приложите к onPositionChange событие NetChart, чтобы увидеть, когда начинается перетаскивание узла. в onPositoinChange событие проверить identifier поле события мыши. Это скажет вам, какой указатель является перетаскиваемым (важно для поддержки мультитач). Итак, теперь у вас есть событие, когда узел перетаскивается, и событие, когда узел освобождается, и идентификатор указателя, который соответствует им. Должен работать, я думаю.
  2. Опять нет, извините. Но есть взлом, который мы использовали сами. Глядя на ._impl.scene.centerX а также ._impl.scene.centerY В свойствах вашего объекта NetChart вы можете получить координаты x/y центра диаграммы в координатах сцены. Увеличение может быть получено совершенно легально с .zoom() Вызов API. Добавьте немного математики, и вы сможете определить координаты сцены вашего курсора мыши. Поместите свой узел туда. Обратите внимание, что это НЕ документированный подход и может прекратить работу в любое время. Используйте на свой риск.

ZoomCharts представила новые события для NetChart с выпуском 1.18.0 (2017-10-05). Все события можно найти здесь.

Здесь я подготовил быстрый пример, где можно перетаскивать узел поверх других узлов. В этом случае это создаст связь между узлами с направлением.

http://jsfiddle.net/cmx907hp/

Код:

var ndata = {
        "nodes":[
            {"id":"n1", "loaded":true, "style":{"label":"Node1", "fillColor":"rgba(236,46,46,0.8)"}, "x":0, "y":0, "locked": true},
            {"id":"n2", "loaded":true, "style":{"label":"Node2", "fillColor":"rgba(47,195,47,0.8)" }, "x":200, "y":50},
            {"id":"n3", "loaded":true, "style":{"labeL":"Node3", "fillColor":"rgba(28,124,213,0.8)" }, "x":100, "y":100},
            {"id":"n4", "loaded":true, "style":{"labeL":"Node4", "fillColor":"rgba(236,46,46,1)" }, "x":250, "y":250, "locked": true}
        ],
        "links":[
            {"id":"l1","from":"n1", "to":"n2"}
        ]
    };



    var chart = new NetChart({
        container: document.getElementById("demo"),
        area: { height: $(window).height() - 120 },
        data: { preloaded: ndata },
        events: {
            onClick: function(e, args) {
                console.log("click", args);
            },
            onPointerDown: function(e, args) {
                console.log("down", args);
            },
            onPointerUp: function(e, args) {
                console.log("up", args);
                if(args.clickNode) {
                    var node = args.clickNode;
                    var onodes = getOverlappingNodes(node);
                    connectNodes(node, onodes);
                }
            },
            onPointerDrag: function(e, args) {
                console.log("drag", args);
            },
            onPointerMove: function(e, args) {
                //this is basically onMouseMove, but originally was named like this.
            }
        },
        navigation: {
          //  mode: "showall"
        }
    });


    function getOverlappingNodes(node) {
    if(!node) return;

    var found = [];
    var dim = chart.getNodeDimensions(node);

    var x = x1 = dim.x;
    var y = y1 = dim.y;
    var radius = dim.radius;

    //get all nodes:
    var nodes = chart.nodes();
    for (var i = 0; i < nodes.length; i++) {
        var obj = nodes[i];
        //skip dragged node itself.
        if(obj.id === node.id) {
            continue;
        }
        var odim = chart.getNodeDimensions(obj);
        var x0 = odim.x;
        var y0 = odim.y;

        var m = Math.sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)) < radius;
        if(m) {
            found.push(obj);
        }
    }
    return found;
}


function connectNodes(node, onodes) {
    for (var i = 0; i < onodes.length; i++) {
        var onode = onodes[i];

        var link = {"id": "link-" + node.id + "-" + onode.id,"from": node.id, "to": onode.id, style: {"toDecoration": "arrow"}}
        chart.addData({nodes:[],links: [link]});
    }
}
Другие вопросы по тегам