Использовать рендеринг svg по умолчанию D3.js
Древовидная карта D3 по умолчанию использует svg, например, этот пример от автора D3:
Исходно.OCExam.org/MBO stock/43…
Есть плюсы и минусы использования svg:
- Преимущество в том, что удобно манипулировать элементами dom и добавлять взаимодействие с пользователем.
- Недостатком является то, что эффективность рендеринга невысока, а страница легко пропускает кадры и зависает при большом объеме данных.
В большинстве случаев, когда объем данных не особенно велик, преимущества использования svg намного перевешивают недостатки, но что, если нам действительно нужно отобразить большой объем данных?
Рендеринг с помощью D3.js + Canvas
source code
demo page
SST house.GitHub.IO/organ i Разное...
Приведенная выше демонстрация реализована с использованием D3.js + Canvas.Когда количество слоев организации превышает 300, будут очевидные лаги, которые могут соответствовать данным большинства организационных диаграмм.
идеи
- Трое используют D3.js в
虚拟Dom
хорошее изображение - Используйте API рисования холста, чтобы
虚拟Dom
Данные (координаты и путь линии) и т. д. рисуются на холсте. - использовать
Unique-color
Способ реализовать взаимодействие пользователя с Canvas - Рисуя скрытый холст с теми же данными, что и предыдущий холст, и присваивая каждому узлу, который хочет получать взаимодействие с пользователем, уникальный цвет.
- Прослушивая событие щелчка Canvas, получите значение цвета щелкнутого пикселя, чтобы определить щелкнутый узел.
- В этой статье есть подробное введение в эту идею:medium.com/@greener о разрушительной силе/…
1. Использование D3.js Три в虚拟Dom
хорошее изображение
Сначала вызовите виртуальный дом, который использует D3 для создания дерева:
this.data = this.d3.hierarchy(data)
this.treeGenerator = this.d3.tree()
.nodeSize([this.nodeWidth, this.nodeHeight])
let nodes = this.treeData.descendants()
let links = this.treeData.links()
переменная вышеnodes
а такжеlinks
Теперь включает в себя каждую из структурных диаграмм组织节点
а также连接线
Координировать информацию.
2. Используйте API рисования холста, чтобы虚拟Dom
Данные (координаты и путь линии) и т. д. рисуются на холсте.
В drawShowCanvas используйте d3.select, чтобы получить узел виртуального дома, а затем используйте функцию рисования Canvas для рисования. Здесь используются некоторые инструменты и методы Util. Конкретную реализацию см. в исходном коде.
drawShowCanvas () {
this.context.clearRect(-50000, -10000, 100000, 100000)
let self = this
// draw links
this.virtualContainerNode.selectAll('.link')
.each(function () {
let node = self.d3.select(this)
let linkPath = self.d3.linkVertical()
.x(function (d) {
return d.x
})
.y(function (d) {
return d.y
})
.source(function () {
return {x: node.attr('sourceX'), y: node.attr('sourceY')}
})
.target(function () {
return {x: node.attr('targetX'), y: node.attr('targetY')}
})
let path = new Path2D(linkPath())
self.context.stroke(path)
})
this.virtualContainerNode.selectAll('.orgUnit')
.each(function () {
let node = self.d3.select(this)
let treeNode = node.data()[0]
let data = treeNode.data
self.context.fillStyle = '#3ca0ff'
let indexX = Number(node.attr('x')) - self.unitWidth / 2
let indexY = Number(node.attr('y')) - self.unitHeight / 2
// draw unit outline rect (if you want to modify this line ===> please modify the same line in `drawHiddenCanvas`)
Util.roundRect(self.context, indexX, indexY, self.unitWidth, self.unitHeight, 4, true, false)
Util.text(self.context, data.name, indexX + self.unitPadding, indexY + self.unitPadding, '20px', '#ffffff')
// Util.text(self.context, data.title, indexX + self.unitPadding, indexY + self.unitPadding + 30, '20px', '#000000')
let maxWidth = self.unitWidth - 2 * self.unitPadding
Util.wrapText(self.context, data.title, indexX + self.unitPadding, indexY + self.unitPadding + 24, maxWidth, 20)
})
}
3. ИспользуйтеUnique-color
Способ реализовать взаимодействие пользователя с Canvas
Как вы можете видеть на рисунке ниже, на самом деле есть два Canvas, из которых Canvas ниже — это то же самое, что и данные, нарисованные Cavans выше, за исключением того, что цвет узлов отличается.
drawCanvas () {
this.drawShowCanvas()
this.drawHiddenCanvas()
}
Прослушайте событие щелчка пользователя на приведенном выше холсте и получите узел, щелкнутый пользователем на следующем изображении, через координаты пикселя (Примечание: пара ключ-значение цвета и узла создается, когда следующий холст рисуется из .)
setClickListener () {
let self = this
this.canvasNode.node().addEventListener('click', function (e) {
let colorStr = Util.getColorStrFromCanvas(self.hiddenContext, e.layerX, e.layerY)
let node = self.colorNodeMap[colorStr]
if (node) {
// let treeNodeData = node.data()[0]
// self.hideChildren(treeNodeData, true)
self.toggleTreeNode(node.data()[0])
self.update(node.data()[0])
}
})
}
Вот справочный код для создания пар ключ-значение уникального цвета и узла:
addColorKey () {
// give each node a unique color
let self = this
this.virtualContainerNode.selectAll('.orgUnit')
.each(function () {
let node = self.d3.select(this)
let newColor = Util.randomColor()
while (self.colorNodeMap[newColor]) {
newColor = Util.randomColor()
}
node.attr('colorKey', newColor)
node.data()[0]['colorKey'] = newColor
self.colorNodeMap[newColor] = node
})
}
разное
To draw your own nested data
please replace the data in /src/base/data-generator
with your own nested data.
please add your data drawing logic in /src/components/org-chart.js #drawShowCanvas
Want to develop locally ?
source code
if you like it , welcome to star and fork :tada:
# install dependencies
npm install
# serve with hot reload at localhost
npm run dev
# build for production with minification (build to ./docs folder, which can be auto servered by github page 🤓)
npm run build
Хотите узнать больше о D3.js?
вот мойD3.js,визуализация данныхадрес github, добро пожаловать на старт и форк :tada: