Feature:新增时间轴结构
This commit is contained in:
parent
3825c3769f
commit
de77a2b613
@ -21,7 +21,9 @@ const layouts = {
|
|||||||
// 组织结构图
|
// 组织结构图
|
||||||
[CONSTANTS.LAYOUT.ORGANIZATION_STRUCTURE]: OrganizationStructure,
|
[CONSTANTS.LAYOUT.ORGANIZATION_STRUCTURE]: OrganizationStructure,
|
||||||
// 时间轴
|
// 时间轴
|
||||||
[CONSTANTS.LAYOUT.TIMELINE]: Timeline
|
[CONSTANTS.LAYOUT.TIMELINE]: Timeline,
|
||||||
|
// 时间轴2
|
||||||
|
[CONSTANTS.LAYOUT.TIMELINE2]: Timeline
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染
|
// 渲染
|
||||||
@ -68,7 +70,7 @@ class Render {
|
|||||||
layouts[this.mindMap.opt.layout]
|
layouts[this.mindMap.opt.layout]
|
||||||
? layouts[this.mindMap.opt.layout]
|
? layouts[this.mindMap.opt.layout]
|
||||||
: layouts[CONSTANTS.LAYOUT.LOGICAL_STRUCTURE]
|
: layouts[CONSTANTS.LAYOUT.LOGICAL_STRUCTURE]
|
||||||
)(this)
|
)(this, this.mindMap.opt.layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 绑定事件
|
// 绑定事件
|
||||||
|
|||||||
@ -266,6 +266,11 @@ class Base {
|
|||||||
generalizationNodeMargin
|
generalizationNodeMargin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取节点实际存在几个子节点
|
||||||
|
getNodeActChildrenLength(node) {
|
||||||
|
return node.nodeData.children && node.nodeData.children.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Base
|
export default Base
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
import Base from './Base'
|
import Base from './Base'
|
||||||
import { walk, asyncRun } from '../utils'
|
import { walk, asyncRun } from '../utils'
|
||||||
|
import { CONSTANTS } from '../utils/constant'
|
||||||
|
|
||||||
// 时间轴
|
// 时间轴
|
||||||
class CatalogOrganization extends Base {
|
class CatalogOrganization extends Base {
|
||||||
// 构造函数
|
// 构造函数
|
||||||
constructor(opt = {}) {
|
constructor(opt = {}, layout) {
|
||||||
super(opt)
|
super(opt)
|
||||||
|
this.layout = layout
|
||||||
}
|
}
|
||||||
|
|
||||||
// 布局
|
// 布局
|
||||||
@ -32,13 +34,28 @@ class CatalogOrganization extends Base {
|
|||||||
walk(
|
walk(
|
||||||
this.renderer.renderTree,
|
this.renderer.renderTree,
|
||||||
null,
|
null,
|
||||||
(cur, parent, isRoot, layerIndex) => {
|
(cur, parent, isRoot, layerIndex, index) => {
|
||||||
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
|
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
|
||||||
// 根节点定位在画布中心位置
|
// 根节点定位在画布中心位置
|
||||||
if (isRoot) {
|
if (isRoot) {
|
||||||
this.setNodeCenter(newNode)
|
this.setNodeCenter(newNode)
|
||||||
} else {
|
} else {
|
||||||
// 非根节点
|
// 非根节点
|
||||||
|
// 时间轴2类型需要交替显示
|
||||||
|
if (this.layout === CONSTANTS.LAYOUT.TIMELINE2) {
|
||||||
|
// 三级及以下节点以上级为准
|
||||||
|
if (parent._node.dir) {
|
||||||
|
newNode.dir = parent._node.dir
|
||||||
|
} else {
|
||||||
|
// 节点生长方向
|
||||||
|
newNode.dir =
|
||||||
|
index % 2 === 0
|
||||||
|
? CONSTANTS.TIMELINE_DIR.BOTTOM
|
||||||
|
: CONSTANTS.TIMELINE_DIR.TOP
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newNode.dir = ''
|
||||||
|
}
|
||||||
if (parent._node.isRoot) {
|
if (parent._node.isRoot) {
|
||||||
newNode.top =
|
newNode.top =
|
||||||
parent._node.top +
|
parent._node.top +
|
||||||
@ -51,7 +68,7 @@ class CatalogOrganization extends Base {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(cur, parent, isRoot, layerIndex) => {},
|
null,
|
||||||
true,
|
true,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
@ -62,7 +79,7 @@ class CatalogOrganization extends Base {
|
|||||||
walk(
|
walk(
|
||||||
this.root,
|
this.root,
|
||||||
null,
|
null,
|
||||||
(node, parent, isRoot, layerIndex) => {
|
(node, parent, isRoot, layerIndex, index) => {
|
||||||
if (
|
if (
|
||||||
node.nodeData.data.expand &&
|
node.nodeData.data.expand &&
|
||||||
node.children &&
|
node.children &&
|
||||||
@ -78,11 +95,18 @@ class CatalogOrganization extends Base {
|
|||||||
totalLeft += cur.width + marginX
|
totalLeft += cur.width + marginX
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let totalTop = node.top + node.height + marginY + node.expandBtnSize
|
let totalTop =
|
||||||
|
node.top +
|
||||||
|
node.height +
|
||||||
|
marginY +
|
||||||
|
(this.getNodeActChildrenLength(node) > 0 ? node.expandBtnSize : 0)
|
||||||
node.children.forEach(cur => {
|
node.children.forEach(cur => {
|
||||||
cur.left = node.left + node.width * 0.5
|
cur.left = node.left + node.width * 0.5
|
||||||
cur.top = totalTop
|
cur.top = totalTop
|
||||||
totalTop += cur.height + marginY + node.expandBtnSize
|
totalTop +=
|
||||||
|
cur.height +
|
||||||
|
marginY +
|
||||||
|
(this.getNodeActChildrenLength(cur) > 0 ? cur.expandBtnSize : 0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,14 +135,34 @@ class CatalogOrganization extends Base {
|
|||||||
let marginY = this.getMarginY(layerIndex + 1)
|
let marginY = this.getMarginY(layerIndex + 1)
|
||||||
let totalHeight =
|
let totalHeight =
|
||||||
node.children.reduce((h, item) => {
|
node.children.reduce((h, item) => {
|
||||||
return h + item.height
|
return (
|
||||||
|
h +
|
||||||
|
item.height +
|
||||||
|
(this.getNodeActChildrenLength(item) > 0
|
||||||
|
? item.expandBtnSize
|
||||||
|
: 0)
|
||||||
|
)
|
||||||
}, 0) +
|
}, 0) +
|
||||||
(len + 1) * marginY +
|
(len + 1) * marginY
|
||||||
len * node.expandBtnSize
|
|
||||||
this.updateBrothersTop(node, totalHeight)
|
this.updateBrothersTop(node, totalHeight)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
null,
|
(node, parent, isRoot, layerIndex) => {
|
||||||
|
if (
|
||||||
|
parent &&
|
||||||
|
parent.isRoot &&
|
||||||
|
node.dir === CONSTANTS.TIMELINE_DIR.TOP
|
||||||
|
) {
|
||||||
|
// 遍历二级节点的子节点
|
||||||
|
node.children.forEach(item => {
|
||||||
|
let totalHeight = this.getNodeAreaHeight(item)
|
||||||
|
let _top = item.top
|
||||||
|
item.top =
|
||||||
|
node.top - (item.top - node.top) - totalHeight + node.height
|
||||||
|
this.updateChildren(item.children, 'top', item.top - _top)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -141,6 +185,24 @@ class CatalogOrganization extends Base {
|
|||||||
return Math.max(...widthArr)
|
return Math.max(...widthArr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 递归计算节点的宽度
|
||||||
|
getNodeAreaHeight(node) {
|
||||||
|
let totalHeight = 0
|
||||||
|
let loop = node => {
|
||||||
|
totalHeight +=
|
||||||
|
node.height +
|
||||||
|
(this.getNodeActChildrenLength(node) > 0 ? node.expandBtnSize : 0) +
|
||||||
|
this.getMarginY(node.layerIndex)
|
||||||
|
if (node.children.length) {
|
||||||
|
node.children.forEach(item => {
|
||||||
|
loop(item)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loop(node)
|
||||||
|
return totalHeight
|
||||||
|
}
|
||||||
|
|
||||||
// 调整兄弟节点的left
|
// 调整兄弟节点的left
|
||||||
updateBrothersLeft(node) {
|
updateBrothersLeft(node) {
|
||||||
let childrenList = node.children
|
let childrenList = node.children
|
||||||
@ -150,7 +212,9 @@ class CatalogOrganization extends Base {
|
|||||||
if (item.children && item.children.length) {
|
if (item.children && item.children.length) {
|
||||||
this.updateChildren(item.children, 'left', totalAddWidth)
|
this.updateChildren(item.children, 'left', totalAddWidth)
|
||||||
}
|
}
|
||||||
let areaWidth = this.getNodeAreaWidth(item)
|
// let areaWidth = this.getNodeAreaWidth(item)
|
||||||
|
let { left, right } = this.getNodeBoundaries(item, 'h')
|
||||||
|
let areaWidth = right - left
|
||||||
let difference = areaWidth - item.width
|
let difference = areaWidth - item.width
|
||||||
if (difference > 0) {
|
if (difference > 0) {
|
||||||
totalAddWidth += difference
|
totalAddWidth += difference
|
||||||
@ -209,12 +273,16 @@ class CatalogOrganization extends Base {
|
|||||||
} else {
|
} else {
|
||||||
// 当前节点为非根节点
|
// 当前节点为非根节点
|
||||||
let maxy = -Infinity
|
let maxy = -Infinity
|
||||||
|
let miny = Infinity
|
||||||
let x = node.left + node.width * 0.3
|
let x = node.left + node.width * 0.3
|
||||||
node.children.forEach((item, index) => {
|
node.children.forEach((item, index) => {
|
||||||
let y = item.top + item.height / 2
|
let y = item.top + item.height / 2
|
||||||
if (y > maxy) {
|
if (y > maxy) {
|
||||||
maxy = y
|
maxy = y
|
||||||
}
|
}
|
||||||
|
if (y < miny) {
|
||||||
|
miny = y
|
||||||
|
}
|
||||||
// 水平线
|
// 水平线
|
||||||
let path = `M ${x},${y} L ${item.left},${y}`
|
let path = `M ${x},${y} L ${item.left},${y}`
|
||||||
lines[index].plot(path)
|
lines[index].plot(path)
|
||||||
@ -224,7 +292,15 @@ class CatalogOrganization extends Base {
|
|||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
let line = this.draw.path()
|
let line = this.draw.path()
|
||||||
expandBtnSize = len > 0 ? expandBtnSize : 0
|
expandBtnSize = len > 0 ? expandBtnSize : 0
|
||||||
line.plot(`M ${x},${top + height + expandBtnSize} L ${x},${maxy}`)
|
if (
|
||||||
|
node.parent &&
|
||||||
|
node.parent.isRoot &&
|
||||||
|
node.dir === CONSTANTS.TIMELINE_DIR.TOP
|
||||||
|
) {
|
||||||
|
line.plot(`M ${x},${top} L ${x},${miny}`)
|
||||||
|
} else {
|
||||||
|
line.plot(`M ${x},${top + height + expandBtnSize} L ${x},${maxy}`)
|
||||||
|
}
|
||||||
node.style.line(line)
|
node.style.line(line)
|
||||||
node._lines.push(line)
|
node._lines.push(line)
|
||||||
style && style(line, node)
|
style && style(line, node)
|
||||||
@ -237,10 +313,21 @@ class CatalogOrganization extends Base {
|
|||||||
let { width, height, expandBtnSize, isRoot } = node
|
let { width, height, expandBtnSize, isRoot } = node
|
||||||
if (!isRoot) {
|
if (!isRoot) {
|
||||||
let { translateX, translateY } = btn.transform()
|
let { translateX, translateY } = btn.transform()
|
||||||
btn.translate(
|
if (
|
||||||
width * 0.3 - expandBtnSize / 2 - translateX,
|
node.parent &&
|
||||||
height + expandBtnSize / 2 - translateY
|
node.parent.isRoot &&
|
||||||
)
|
node.dir === CONSTANTS.TIMELINE_DIR.TOP
|
||||||
|
) {
|
||||||
|
btn.translate(
|
||||||
|
width * 0.3 - expandBtnSize / 2 - translateX,
|
||||||
|
-expandBtnSize / 2 - translateY
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
btn.translate(
|
||||||
|
width * 0.3 - expandBtnSize / 2 - translateX,
|
||||||
|
height + expandBtnSize / 2 - translateY
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -155,7 +155,8 @@ export const CONSTANTS = {
|
|||||||
MIND_MAP: 'mindMap',
|
MIND_MAP: 'mindMap',
|
||||||
ORGANIZATION_STRUCTURE: 'organizationStructure',
|
ORGANIZATION_STRUCTURE: 'organizationStructure',
|
||||||
CATALOG_ORGANIZATION: 'catalogOrganization',
|
CATALOG_ORGANIZATION: 'catalogOrganization',
|
||||||
TIMELINE: 'timeline'
|
TIMELINE: 'timeline',
|
||||||
|
TIMELINE2: 'timeline2'
|
||||||
},
|
},
|
||||||
DIR: {
|
DIR: {
|
||||||
UP: 'up',
|
UP: 'up',
|
||||||
@ -190,6 +191,10 @@ export const CONSTANTS = {
|
|||||||
RIGHT: 'right',
|
RIGHT: 'right',
|
||||||
BOTTOM: 'bottom',
|
BOTTOM: 'bottom',
|
||||||
CENTER: 'center'
|
CENTER: 'center'
|
||||||
|
},
|
||||||
|
TIMELINE_DIR: {
|
||||||
|
TOP: 'top',
|
||||||
|
BOTTOM: 'bottom'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +227,10 @@ export const layoutList = [
|
|||||||
{
|
{
|
||||||
name: '时间轴',
|
name: '时间轴',
|
||||||
value: CONSTANTS.LAYOUT.TIMELINE,
|
value: CONSTANTS.LAYOUT.TIMELINE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '时间轴2',
|
||||||
|
value: CONSTANTS.LAYOUT.TIMELINE2,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
export const layoutValueList = [
|
export const layoutValueList = [
|
||||||
@ -229,5 +238,6 @@ export const layoutValueList = [
|
|||||||
CONSTANTS.LAYOUT.MIND_MAP,
|
CONSTANTS.LAYOUT.MIND_MAP,
|
||||||
CONSTANTS.LAYOUT.CATALOG_ORGANIZATION,
|
CONSTANTS.LAYOUT.CATALOG_ORGANIZATION,
|
||||||
CONSTANTS.LAYOUT.ORGANIZATION_STRUCTURE,
|
CONSTANTS.LAYOUT.ORGANIZATION_STRUCTURE,
|
||||||
CONSTANTS.LAYOUT.TIMELINE
|
CONSTANTS.LAYOUT.TIMELINE,
|
||||||
|
CONSTANTS.LAYOUT.TIMELINE2
|
||||||
]
|
]
|
||||||
Loading…
x
Reference in New Issue
Block a user