Поместите элементы набора данных, используя шкалы в d3.js - PullRequest
0 голосов
/ 27 января 2019

Мне нужно сделать что-то подобное в SVG:

image

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

предположим, у меня есть линейная шкала для позиционирования элементов по горизонтали, а другая - для позиционирования элементов по вертикали:

const myDomainH = ?
const myRangeH = ?
const scaleHorizontally = d3.scaleLinear().domain(myDomainH).range(myRangeH)

const myDomainV = ?
const myRangeV = ?
const scaleVertically = d3.scaleLinear().domain(myDomainV).range(myRangeV)

и мой набор данных:

[
  [
    {
      "category": "Category 1",
      "color": 1,
      "value": 73.55989924542436,
      "objects": [
        {
          "object": "Object 11",
          "value": 70.77137994021379
        },
        {
          "object": "Object 12",
          "value": 81.4082571028975
        },
        {
          "object": "Object 13",
          "value": 70.77137994021379
        }
      ]
    },
    {
      "category": "Category 1",
      "color": 2,
      "value": 22.2597985833491,
      "objects": [
        {
          "object": "Object 11",
          "value": 15.853930976590469
        },
        {
          "object": "Object 12",
          "value": 56.56972660299733
        },
        {
          "object": "Object 13",
          "value": 70.77137994021379
        }
      ]
    },
    {
      "category": "Category 1",
      "color": 3,
      "value": 22.709698156338032,
      "objects": [
        {
          "object": "Object 11",
          "value": 74.99319041632756
        },
        {
          "object": "Object 12",
          "value": 68.41322493812694
        },
        {
          "object": "Object 13",
          "value": 70.77137994021379
        }
      ]
    },
    {
      "category": "Category 1",
      "color": 4,
      "value": 23.66413869920101,
      "objects": [
        {
          "object": "Object 11",
          "value": 17.61500366859401
        },
        {
          "object": "Object 12",
          "value": 11.147400814940344
        },
        {
          "object": "Object 13",
          "value": 70.77137994021379
        }
      ]
    },
    {
      "category": "Category 1",
      "color": 5,
      "value": 45.82962655452327,
      "objects": [
        {
          "object": "Object 11",
          "value": 9.967028966701474
        },
        {
          "object": "Object 12",
          "value": 13.944328943444905
        },
        {
          "object": "Object 13",
          "value": 70.77137994021379
        }
      ]
    },
    {
      "category": "Category 1",
      "color": 6,
      "value": 24.865266198819302,
      "objects": [
        {
          "object": "Object 11",
          "value": 37.45282918258137
        },
        {
          "object": "Object 12",
          "value": 62.40512982903728
        },
        {
          "object": "Object 13",
          "value": 70.77137994021379
        }
      ]
    }
  ],
  [
    {
      "category": "Category 2",
      "color": 1,
      "value": 35.30633472871503,
      "objects": [
        {
          "object": "Object 21",
          "value": 32.017889605115336
        },
        {
          "object": "Object 22",
          "value": 22.600901269005913
        },
      ]
    },
    {
      "category": "Category 2",
      "color": 2,
      "value": 15.763575845434152,
      "objects": [
        {
          "object": "Object 21",
          "value": 32.017889605115336
        },
        {
          "object": "Object 22",
          "value": 22.600901269005913
        },
      ]
    },
    {
      "category": "Category 2",
      "color": 3,
      "value": 65.66932804750859,
      "objects": [
        {
          "object": "Object 21",
          "value": 32.017889605115336
        },
        {
          "object": "Object 22",
          "value": 22.600901269005913
        },
      ]
    },
    {
      "category": "Category 2",
      "color": 4,
      "value": 35.79326347817449,
      "objects": [
        {
          "object": "Object 21",
          "value": 32.017889605115336
        },
        {
          "object": "Object 22",
          "value": 22.600901269005913
        },
      ]
    },
    {
      "category": "Category 2",
      "color": 5,
      "value": 91.79806542930078,
      "objects": [
        {
          "object": "Object 21",
          "value": 32.017889605115336
        },
        {
          "object": "Object 22",
          "value": 22.600901269005913
        },
      ]
    },
    {
      "category": "Category 2",
      "color": 6,
      "value": 34.574064983647766,
      "objects": [
        {
          "object": "Object 21",
          "value": 32.017889605115336
        },
        {
          "object": "Object 22",
          "value": 22.600901269005913
        },
      ]
    }
  ],
  [
    {
      "category": "Category 3",
      "color": 1,
      "value": 57.64950041773291,
      "objects": [
        {
          "object": "Object 31",
          "value": 42.86818415221803
        },
        {
          "object": "Object 32",
          "value": 42.86818415221803
        },
        {
          "object": "Object 33",
          "value": 42.86818415221803
        },
        {
          "object": "Object 34",
          "value": 42.86818415221803
        }
      ]
    },
    {
      "category": "Category 3",
      "color": 2,
      "value": 17.76033855108046,
      "objects": [
        {
          "object": "Object 31",
          "value": 89.52070065904911
        },
        {
          "object": "Object 32",
          "value": 42.86818415221803
        },
        {
          "object": "Object 33",
          "value": 42.86818415221803
        },
        {
          "object": "Object 34",
          "value": 42.86818415221803
        }
      ]
    },
    {
      "category": "Category 3",
      "color": 3,
      "value": 11.845610356899815,
      "objects": [
        {
          "object": "Object 31",
          "value": 54.76278304243267
        },
        {
          "object": "Object 32",
          "value": 42.86818415221803
        },
        {
          "object": "Object 33",
          "value": 42.86818415221803
        },
        {
          "object": "Object 34",
          "value": 42.86818415221803
        }
      ]
    },
    {
      "category": "Category 3",
      "color": 4,
      "value": 80.55423937728892,
      "objects": [
        {
          "object": "Object 31",
          "value": 63.74492886059537
        },
        {
          "object": "Object 32",
          "value": 42.86818415221803
        },
        {
          "object": "Object 33",
          "value": 42.86818415221803
        },
        {
          "object": "Object 34",
          "value": 42.86818415221803
        }
      ]
    },
    {
      "category": "Category 3",
      "color": 5,
      "value": 3.6629102311577455,
      "objects": [
        {
          "object": "Object 31",
          "value": 63.260999161538535
        },
        {
          "object": "Object 32",
          "value": 42.86818415221803
        },
        {
          "object": "Object 33",
          "value": 42.86818415221803
        },
        {
          "object": "Object 34",
          "value": 42.86818415221803
        }
      ]
    },
    {
      "category": "Category 3",
      "color": 6,
      "value": 66.08487065166841,
      "objects": [
        {
          "object": "Object 31",
          "value": 70.16436770369718
        },
        {
          "object": "Object 32",
          "value": 42.86818415221803
        },
        {
          "object": "Object 33",
          "value": 42.86818415221803
        },
        {
          "object": "Object 34",
          "value": 42.86818415221803
        }
      ]
    }
  ]
]

(игнорируется поле value, которое в данный момент не используется).

, а затем?

С этими данными мне нужно создать и расположить ячейки (svg rects) и написано с использованием d3.js.Идея состоит в том, чтобы иметь отзывчивую страницу, тогда ячейки будут иметь ширину, которая изменяется в зависимости от ширины страницы.

Тогда я подумал, что горизонтальный масштаб может иметь в качестве диапазона ширину window.innerwidht) но я не знаю, правильно ли это.

Высота свектов svg должна быть установлена ​​на 15px.

В любом случае, я не знаю, как поступить,Кто-нибудь может мне помочь?

Спасибо.

1 Ответ

0 голосов
/ 27 января 2019

Вы рисуете вложенную структуру, и хитрость здесь в том, что в то время как для внешнего слоя вы используете .data(dataSet), для внутренних слоев вам нужно подойти, извлекая его данные из уже сопоставленного элемента внешнего слоя с помощью функции, например:когда внешний слой - это столбцы, а внутренний слой - ячейки: .data(function(d) { return d.objects; }.

Что касается самого позиционирования, я рекомендую интенсивно использовать g элементов с transform атрибутами.Таким образом, когда вы находитесь внутри внутреннего слоя, вам не нужно беспокоиться о позиционировании элемента внешнего слоя (например, когда вы рисуете ячейку, вам не нужно знать смещение x столбца).Для расчета позиции, PointScale может иметь больше смысла в этом контексте, хотя это не так уж важно.

Тогда я подумал, что горизонтальная шкала может иметь в качестве диапазона ширину окна. (Innerwidht), но я не знаю, правильно ли это.

ДаЭто правильный подход.Скорее всего, вы захотите выполнить рендеринг, поместив его в один метод (я имею в виду, что это единственная открытая точка для вызова рендеринга; конечно, он будет и должен делегировать его части для частных методов), и вы будете вызыватьэтот метод в слушателе события resize.

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

var dataSet = [{
    "category": "Category 1",
    "color": 1,
    "value": 73.55989924542436,
    "objects": [{
        "object": "Object 11",
        "value": 70.77137994021379
      },
      {
        "object": "Object 12",
        "value": 81.4082571028975
      },
      {
        "object": "Object 13",
        "value": 70.77137994021379
      }
    ]
  },
  {
    "category": "Category 1",
    "color": 2,
    "value": 22.2597985833491,
    "objects": [{
        "object": "Object 11",
        "value": 15.853930976590469
      },
      {
        "object": "Object 12",
        "value": 56.56972660299733
      },
      {
        "object": "Object 13",
        "value": 70.77137994021379
      }
    ]
  }
];

var svg = d3.select('svg');
var winWidth = 300;

var colScale = d3.scalePoint()
  .domain(dataSet.map(function(d) {
    return d.color;
  }))
  .range([0, winWidth]);


var objects = dataSet[0].objects.map(function(o) {
  return o.object;
});

var cellScale = d3.scalePoint()
  .domain(objects)
  .range([0, objects.length * 15]);

var columns = svg.selectAll('g.column')
  .data(dataSet);

columns = columns.enter()
  .append('g')
  .classed('column', true)
  .merge(columns)
  .attr('transform', function(d, i) {
    return 'translate(' + colScale(d.color) + ',0)';
  });

var cells = columns
  .selectAll('g.cell')
  .data(function(d) {
    return d.objects;
  });

cells = cells.enter()
  .append('g')
  .classed('cell', true)
  .merge(cells)
  .attr('transform', function(d, i) {
    return 'translate(0,' + cellScale(d.object) + ')';
  });

cells.append('rect')
  //Styles should be in CSS
  .style('fill', 'none')
  .style('stroke', 'black')
  .attr('width', colScale.step())
  .attr('height', cellScale.step());

cells.append('text')
  .style('dominant-baseline', 'text-before-edge')
  .text(function(d) {
    return d.value;
  });
...