Рубрики
Без рубрики

D3.js – пакет сетевого круга

Комбинация двух намного любимых диаграмм D3 – круговой пакет и симуляция силы.

Автор оригинала: Bryony Miles.

Только что написал статью о строительстве 3 Основные диаграммы Я думал, что буду следить за сложным – Пакет сетевого круга Отказ

Это сочетание двух намного любимых диаграмм D3 – Круг пакет и Сила симуляции Отказ

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

Основные данные

Основная структура – узлы :

 {id: 'c1', name:'Crisps', category:'Snacks',children:[
    {id: 1, name: "Salt & Vinegar",value:431},
    {id: 2, name: "Prawn Cocktail",value:363},
    {id: 3, name: "Cheese & Onion",value:173},
    {id: 4, name: "Roast Beef",value:83},
    {id: 5, name: "Ready Salted",value:410}]
  }

где каждый Узел есть ID , Имя , категория и массив детей.

и Ссылки :

{"id": 1,"source": 39,"target": 20,"rating": 1}

Разница в традиционном Сила симуляции Структура данных в том, что ссылка Источник и цель относится к ID из дети не Родители Отказ

Манипуляция данными

Итак, вы начинаете то же самое, что и стандарт Круг пакет :

    let pack_data = d3.pack()
                      .size([width*0.6, width*0.6])
                      .radius(d => radius_scale(d.data.value))
                      .padding(10)
                      (d3.hierarchy({name: 'root',children: nodes})
                       .sum(d => d.value)
                       .sort((a, b) => b.value - a.value));

Но тогда вам нужно петить через пакет и установить pack_x и Pack_y Переменные.

  • Родители – Их позиция будет определена симуляцией силы, поэтому мы хотим потерять позиционирование D3.pack (). Все, что нам нужно, это радиус круга.
  • дети – Мы хотим сохранить позиционирование D3.pack (), но вычтите d3.pack () позиционирование родителя и добавьте радиус круг родительского круга.
    pack_data.children.forEach(function(d){
        const my_x = d.x;
        const my_y = d.y;
        d.pack_x = d.r;
        d.pack_y = d.r;
        d.category = d.data.category;
        for(let c in d.children){
          d.children[c].pack_x = d.children[c].x - my_x + d.r;
          d.children[c].pack_y = d.children[c].y - my_y + d.r;
          d.children[c].category = d.data.category;
        }
    })

Ссылки Sub Country.

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

Вы найдете код в Демо Я уверен, что это может быть улучшено.

Позиционирование круга

Вы увидите, что каждый круг, а другие элементы в группе узлов впервые расположены с pack_x и Pack_y Отказ

   my_group.select(".pack_circle")
            .attr("id",d => "node_" + d.data.id)
            .attr("cx", d => d.pack_x)
            .attr("cy",d => d.pack_y)
            .attr("r",d => d.r)

Если вы оставили его здесь, они все будут на вершине друг друга в верхнем левом углу SVG.

Симуляция силой

Затем я создал симуляцию силы. Я использовал Forcyinabox На этот раз вы можете настроить ваши потребности. Важным битом является функция галочки, где ссылки и элементы узла помещаются с использованием этих двух функций.

 function get_node_translate(d){
        if( d.depth === 1){
          return "translate(" + (d.x + margin) + "," + (d.y + (margin/2)) + ")";
        } else {
          return "translate(" + (d.parent.x + margin) + "," + (d.parent.y + (margin/2)) + ")";
        }      
    }
   
    function get_link_extra(d, type,coord){
      return d.parent === undefined ? d[type].parent[coord] : d[type][coord]
    }

Важно вернуть правильные координаты X и Y, определяемые симуляцией силы.

  • Родители (d.depth) Это просто d.x и d.y
  • дети (Глубина) Вам нужно ссылаться на родитель – d.cparent.x и d.cparent.y.

Я очень доволен этим. Потребовалось много мысли, чтобы адаптировать его должным образом, а также думать через дизайн и взаимодействие на мыши.

Клиент I разработал его для имел большие объемы данных, поэтому я добавил дополнительный уровень увеличения и панорамирования, а также панель для получения информации, поскольку текстовые элементы стали слишком маленькими для чтения.

Надеюсь, вам это нравится.