Иерархическое дерево с циклическим подключением

#reactjs #jsplumb

#reactjs #jsplumb

Вопрос:

Я пытаюсь реализовать иерархическое дерево (используя React amp; jsPlumb) с циклическим соединением между узлами и соединением двух узлов в один узел. Проблема в том, что при подключении позиционирование иерархического дерева работает неправильно. Фактически, циклическое соединение перекрывается с другими узлами.

Я попытался подключить конечный узел к начальному узлу в иерархическом дереве с помощью соединителя Безье от нижнего якоря конечного узла до верхнего якоря начального узла без перекрытия узлов. Но дерево подключено от верхнего якоря конечного узла к нижнему якорю начального узла с перекрытием узлов.

Конфигурации:

 const layoutConfig = {
  type: 'Hierarchical',
  parameters: {
    padding: [120, 150],
    spacing: 'compress',
    orientation: 'horizontal',
    magnetize: true,
  },
};
export const viewConfig = {
  nodes: {
    singleTrigger: { component: SingleTriggerComponent, events },
    action: { component: ActionComponent, events },
    delay: { component: DelayComponent, events },
    decision: { component: DecisionComponent, events },
    fork: { component: SplitComponent, events },
    fork_path: { component: LabelComponent, events },
    if: { component: LabelComponent, events },
    else: { component: LabelComponent, events },
    exit: { component: ExitComponent, events },
    placeholder: { component: PlaceholderComponent, events },
  },
  edges: {
    default: { paintStyle: { lineWidth: 2, strokeStyle: '#d9e3eb' } },
    bezier: simpleBezierEdgeConfig(),
    straight: straightEdgeConfig(),
    straightWithoutEndPoint: straightEdgeConfigWithoutEndPoint(),
  },
};
export const renderConfig = {
  layout: layoutConfig,
  refreshLayoutOnEdgeConnect: true,
  zoomToFit: false,
  zoomRange: [minZoom, maxZoom],
  consumeRightClick: false,
  elementsDraggable: false,
  enablePan: true,
  enableWheelZoom: false,
  enablePanButtons: false,
  jsPlumb: {
    Anchors: ['Bottom', 'Top'],
    Endpoints: ['Dot', 'Blank'],
  },
};
 

Иерархический граф:

 "{"nodes":[{"id":"2813","type":"singleTrigger","data":{"workflow":[{"id":2813,"component_type":"root","parent_id":null,"properties":{},"active_people_count":0,"completed_people_count":1},{"id":2815,"component_type":"trigger","parent_id":null,"properties":{"campaign_id":575,"trigger_type":"unsubscribed_contact","display_values":{"campaign":{"id":575,"name":"Test for clicked link workflow","status":"live"}},"unsubscription_type":"campaign"},"active_people_count":0,"completed_people_count":1}]}},{"id":"2953","type":"action","data":{"id":2953,"component_type":"action","parent_id":2813,"properties":{"action_type":"move_from_one_campaign_to_another","parent_type":"root","display_values":{"to_campaign":{"id":572,"name":"Workflow test by me","status":"live"},"from_campaign":{"id":487,"name":"email 08(Copy) 1213 23","status":"live"}},"to_campaign_id":572,"from_campaign_id":487},"active_people_count":0,"completed_people_count":0}},{"id":"2952","type":"action","data":{"id":2952,"component_type":"action","parent_id":2953,"properties":{"action_type":"send_broadcast_mail","parent_type":"action","display_values":{"mail_filter":{"id":2517,"name":"Test ","status":"draft"}},"mail_filter_id":2517,"send_multiple_times":false},"active_people_count":0,"completed_people_count":0}},{"id":"2869","type":"action","data":{"id":2869,"component_type":"action","parent_id":2952,"properties":{"tag_id":1042,"action_type":"apply_tag","parent_type":"action","display_values":{"tag":{"id":1042,"name":"CSV Import - 2019-04-16 06:23:30 UTC","status":"present"}}},"active_people_count":0,"completed_people_count":0}},{"id":"2871","type":"fork","data":{"id":2871,"component_type":"fork","parent_id":2869,"properties":{"parent_type":"action"},"active_people_count":0,"completed_people_count":0}},{"id":"2872","type":"fork_path","data":{"id":2872,"component_type":"fork_path","parent_id":2871,"properties":{"position":1,"parent_type":"fork"},"active_people_count":0,"completed_people_count":0}},{"id":"2875","type":"decision","data":{"id":2875,"component_type":"decision","parent_id":2872,"properties":{"filters":[{"criteria":[{"key":"name","value":"test","condition":"contains","display_values":{}}]}],"parent_type":"fork_path","display_values":{}},"active_people_count":0,"completed_people_count":0}},{"id":"2876","type":"else","data":{"id":2876,"component_type":"else","parent_id":2875,"properties":{"parent_type":"decision"},"active_people_count":0,"completed_people_count":0}},{"id":"2870","type":"delay","data":{"id":2870,"component_type":"delay","parent_id":2876,"properties":{"delay_type":"timed_delay","parent_type":"else","interval_unit":"mins","interval_value":5,"processable_days":[0,1,2,3,4,5,6]},"active_people_count":0,"completed_people_count":0}},{"id":"2814","type":"exit","data":{"id":2814,"component_type":"exit","parent_id":2870,"properties":{"parent_type":"delay"},"active_people_count":0,"completed_people_count":1}},{"id":"2877","type":"if","data":{"id":2877,"component_type":"if","parent_id":2875,"properties":{"parent_type":"decision"},"active_people_count":0,"completed_people_count":0}},{"id":"2878","type":"exit","data":{"id":2878,"component_type":"exit","parent_id":2877,"properties":{"parent_type":"if"},"active_people_count":0,"completed_people_count":0}},{"id":"2873","type":"fork_path","data":{"id":2873,"component_type":"fork_path","parent_id":2871,"properties":{"position":2,"parent_type":"fork"},"active_people_count":0,"completed_people_count":0}},{"id":"2874","type":"exit","data":{"id":2874,"component_type":"exit","parent_id":2873,"properties":{"parent_type":"fork_path"},"active_people_count":0,"completed_people_count":0}}],"edges":[{"source":"2813","target":"2953","data":{"type":"straight","id":2953,"component_type":"action","parent_id":2813,"properties":{"action_type":"move_from_one_campaign_to_another","parent_type":"root","display_values":{"to_campaign":{"id":572,"name":"Workflow test by me","status":"live"},"from_campaign":{"id":487,"name":"email 08(Copy) 1213 23","status":"live"}},"to_campaign_id":572,"from_campaign_id":487},"active_people_count":0,"completed_people_count":0}},{"source":"2953","target":"2952","data":{"type":"straight","id":2952,"component_type":"action","parent_id":2953,"properties":{"action_type":"send_broadcast_mail","parent_type":"action","display_values":{"mail_filter":{"id":2517,"name":"Test ","status":"draft"}},"mail_filter_id":2517,"send_multiple_times":false},"active_people_count":0,"completed_people_count":0}},{"source":"2952","target":"2869","data":{"type":"straight","id":2869,"component_type":"action","parent_id":2952,"properties":{"tag_id":1042,"action_type":"apply_tag","parent_type":"action","display_values":{"tag":{"id":1042,"name":"CSV Import - 2019-04-16 06:23:30 UTC","status":"present"}}},"active_people_count":0,"completed_people_count":0}},{"source":"2869","target":"2871","data":{"type":"straight","id":2871,"component_type":"fork","parent_id":2869,"properties":{"parent_type":"action"},"active_people_count":0,"completed_people_count":0}},{"source":"2871","target":"2872","data":{"type":"bezier","id":2872,"component_type":"fork_path","parent_id":2871,"properties":{"position":1,"parent_type":"fork"},"active_people_count":0,"completed_people_count":0}},{"source":"2871","target":"2873","data":{"type":"bezier","id":2873,"component_type":"fork_path","parent_id":2871,"properties":{"position":2,"parent_type":"fork"},"active_people_count":0,"completed_people_count":0}},{"source":"2872","target":"2875","data":{"type":"straightWithoutEndPoint","id":2875,"component_type":"decision","parent_id":2872,"properties":{"filters":[{"criteria":[{"key":"name","value":"test","condition":"contains","display_values":{}}]}],"parent_type":"fork_path","display_values":{}},"active_people_count":0,"completed_people_count":0}},{"source":"2875","target":"2876","data":{"type":"bezier","id":2876,"component_type":"else","parent_id":2875,"properties":{"parent_type":"decision"},"active_people_count":0,"completed_people_count":0}},{"source":"2875","target":"2877","data":{"type":"bezier","id":2877,"component_type":"if","parent_id":2875,"properties":{"parent_type":"decision"},"active_people_count":0,"completed_people_count":0}},{"source":"2876","target":"2870","data":{"type":"straightWithoutEndPoint","id":2870,"component_type":"delay","parent_id":2876,"properties":{"delay_type":"timed_delay","parent_type":"else","interval_unit":"mins","interval_value":5,"processable_days":[0,1,2,3,4,5,6]},"active_people_count":0,"completed_people_count":0}},{"source":"2870","target":"2814","data":{"type":"straight","id":2814,"component_type":"exit","parent_id":2870,"properties":{"parent_type":"delay"},"active_people_count":0,"completed_people_count":1}},{"source":"2877","target":"2878","data":{"type":"straightWithoutEndPoint","id":2878,"component_type":"exit","parent_id":2877,"properties":{"parent_type":"if"},"active_people_count":0,"completed_people_count":0}},{"source":"2873","target":"2874","data":{"type":"straightWithoutEndPoint","id":2874,"component_type":"exit","parent_id":2873,"properties":{"parent_type":"fork_path"},"active_people_count":0,"completed_people_count":0}}],"ports":[],"groups":[]}"
 

Функция:

 toolkit.addEdge({source: '2813', target: '2874'});
 

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

Комментарии:

1. Я также пытаюсь создать иерархическое дерево в React TS, но сталкиваюсь со многими проблемами. Несмотря на то, что я не могу импортировать пакет. Не могли бы вы помочь мне с этим? Возможно, небольшая настройка jsPlumb в приложении React была бы очень полезна для меня, чтобы начать.

Ответ №1:

Если мы используем toolkit.addEdge({source, target}) метод для создания соединения в иерархическом древовидном макете, узлы, присутствующие в иерархическом дереве, смещаются, и дерево выглядит не очень эстетично. Итак, jsPlumb поддерживает другой метод, вызываемый jsPlumb.connect({source, target}) для создания межузловых соединений. Это соединение не рассматривается как ребра. Итак, решение состоит в том, чтобы использовать

Функция:

jsPlumb.connect({source: '2813', target: '2874'});

Примечание: Чтобы избежать перекрытия, нам нужно использовать соединитель FlowChat.