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, так что это своего рода авторитетный ответ.:)
- Да, вы правы, у нас нет способа сказать это. Хм... Я могу придумать один способ взлома, но я никогда не пробовал этого раньше, так что... Присоединяйте обработчики событий к элементу контейнера NetChart. Прикрепите их к
pointerup
,pointercancel
,mouseup
,touchend
,touchcancel
,MSPointerUp
,MSPointerCancel
, Это все события, которые прервут операцию перетаскивания. Возможно, вам придется проверить, какие из них доступны, и только прикрепить к ним. Вам необходимо прикрепить кcapture
фаза, потому что NetChart предотвратит образование пузырьков. Затем также приложите кonPositionChange
событие NetChart, чтобы увидеть, когда начинается перетаскивание узла. вonPositoinChange
событие проверитьidentifier
поле события мыши. Это скажет вам, какой указатель является перетаскиваемым (важно для поддержки мультитач). Итак, теперь у вас есть событие, когда узел перетаскивается, и событие, когда узел освобождается, и идентификатор указателя, который соответствует им. Должен работать, я думаю. - Опять нет, извините. Но есть взлом, который мы использовали сами. Глядя на
._impl.scene.centerX
а также._impl.scene.centerY
В свойствах вашего объекта NetChart вы можете получить координаты x/y центра диаграммы в координатах сцены. Увеличение может быть получено совершенно легально с.zoom()
Вызов API. Добавьте немного математики, и вы сможете определить координаты сцены вашего курсора мыши. Поместите свой узел туда. Обратите внимание, что это НЕ документированный подход и может прекратить работу в любое время. Используйте на свой риск.
ZoomCharts представила новые события для NetChart с выпуском 1.18.0 (2017-10-05). Все события можно найти здесь.
Здесь я подготовил быстрый пример, где можно перетаскивать узел поверх других узлов. В этом случае это создаст связь между узлами с направлением.
Код:
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]});
}
}