Предварительный просмотр результата
Роль vue и d3
Рисование можно разделить на два этапа:
- Расчет координат элемента
- привязка данных
Для расчета координат нужен только API, в этой статье используется d3.
Привязка данных может быть выполнена либо с помощью d3, либо с помощью vue. d3 реализуется путем манипулирования dom, что немного похоже на jQuery. d3 предлагает три концепции состояния данных и dom: Update, Enter, Exit. Если вам интересно, вы можете обратиться к официальному сайту. В этой статье для привязки данных используется vue.
Резюме: Используйте API, предоставляемый D3 для расчета координат элементов и используйте Vue для привязки данных
Расчет координат
Дерево состоит из узлов и соединений, и вам нужно только вычислить координаты этих двух элементов.
Существуют две общие структуры данных для рисования дерева: одна вложенная, а другая плоская. следующим образом:
// 嵌套的
var treeData = {
name: '中国',
children: [{
name: '北京',
children: [{
name: '海淀'
}, {
name: '朝阳'
}]
}, {
name: '上海'
}]
};
// 扁平的
var flattenData = [{
name: '中国',
parent: ''
}, {
name: '北京',
parent: '中国'
}, {
name: '上海',
parent: '中国'
}, {
name: '海淀',
parent: '北京'
}, {
name: '朝阳',
parent: '北京'
}]
Для вложенных данных используйте d3.hierarchy() для вычисления координат, а для сглаженных данных используйте d3.stratify(). Результирующая структура выглядит следующим образом (перечисление корневого узла):
var hierarchyNode = {
depth: 0
height: 2
parent: null
x: 60
y: 0,
data: {
name: "中国",
children: []
},
children: []
};
После получения корневого узла используйте потомки() для получения всей информации об узле и ссылки() для получения всей информации о соединении. Структура узла такая же, как указано выше, а структура соединения следующая:
var link = {
source: Node,
target: Node
}
На данный момент получены координаты всех элементов
привязка данных
использовать SVG
Узел дерева — это прямоугольник + текст, как показано ниже:
<g :transform="rootTransform">
<rect :width="nodeWidth" :height="nodeHeight" :fill="nodeFill"></rect>
<text :fill="nodeTextColor" text-anchor="middle" dominant-baseline="middle"
:y="nodeHeight / 2" :x="nodeWidth / 2">{{node.data.name}}</text>
</g>
Соединение - это путь, как показано ниже:
<g>
<path :d="getLinkPath(link)" :stroke="linkStroke" fill="none" :stroke-width="linkStrokeWidth"></path>
</g>
code
talk is cheap show me the code