基于orgChart.js 实现横纵向排列的组织结构图
github:https://github.com/violectyc/javascript-orgchart
部分截图如下
基本代码如下入口函数在fetch
html
export
css
body {
font-family: "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
#chart-container {
display: block;
height: calc(100vh - 60px);
width: calc(100% - 24px);
border: 2px dashed #aaa;
border-radius: 5px;
overflow: auto;
text-align: center;
margin: 0 auto;
}
.orgchart{
cursor: pointer;
}
#export {
position: fixed;
top: 0;
right: 0;
z-index: 100;
display: none;
}
.loading{
display: none;
width: 80px;
height: 40px;
margin: 0 auto;
margin-top:100px;
position: absolute;
z-index: 100;
}
.loading span{
display: inline-block;
width: 8px;
height: 100%;
border-radius: 4px;
background: lightgreen;
-webkit-animation: load .8s ease infinite;
}
@-webkit-keyframes load{
0%,100%{
height: 40px;
background: lightgreen;
}
50%{
height: 70px;
margin: -15px 0;
background: lightblue;
}
}
.loading span:nth-child(2){
-webkit-animation-delay:0.0s;
}
.loading span:nth-child(3){
-webkit-animation-delay:0.2s;
}
.loading span:nth-child(4){
-webkit-animation-delay:0.4s;
}
.loading span:nth-child(5){
-webkit-animation-delay:0.6s;
}
javascript
let _scale = 0.3;
let w = null;
let _w = null;
let h = null;
let _h = null;
let _target = null;
// loading
const loading = visible => {
const chartWrapWidth = $(".loading").width();
const chartWrapHeight = $(".loading").height();
$('.loading').css({
'display': 'block',
'top': '50%',
'left': '50%',
'margin-top': - chartWrapWidth / 2 + 'px',
'margin-left': - chartWrapHeight / 2 + 'px',
'visibility': visible
});
};
// loading('visible');
const ENUMCOLOR = {
1: "rgb(236, 206, 152)",
2: "rgb(229, 131, 144)",
3: "rgb(196, 156, 206)",
4: "rgb(143, 209, 233)",
5: "rgb(156, 212, 149)",
6: "rgb(196, 198, 197)"
};
const templete = data => {
console.log(data.level);
if (data.level == 1) {
return `
${data.name}
`;
} else if (data.level == 2) {
return `
${data.value}
${data.name}
`;
}
else if (data.level >= 3) {
return `${data.value}
${data.name}`;
}
};
const initCompleted = () => {
w = $("#chart-container").find(">div").width();
_w = $("#chart-container").width();
h = $("#chart-container").find(">div").height();
_h = $("#chart-container").height();
_target = $('#chart-container').find('.orgchart');
// 缩放原点
_target.css({
'transform-origin': (w / 2 - _w / 2, h / 2 - _h / 2, 0),
'-webkit-transform-origin': (w / 2 - _w / 2, h / 2 - _h / 2, 0),
'transform': 'scale(' + _scale + ')',
'-webkit-transform': 'scale(' + _scale + ')'
});
$('#chart-container').scrollLeft((w * _scale) / 2 - _w / 2);
$('#chart-container').scrollTop((h * _scale));
// loading('hidden');
}
const init = res => {
const options = {
'data': res.downward,
'nodeContent': 'value',
'pan': true,
'zoom': false,
'toggleSiblingsResp': true,
'nodeTemplate': templete,
'draggable': false,
'zoomoutLimit': .6,
'initCompleted': initCompleted
};
const chart = $('#chart-container').orgchart(options);
const dom = $('.y-content');
dom.each(function (index, item) {
$(item).closest('table').css({
'display': 'inline-block'
});
});
}
const _fixType = type => {
type = type.toLowerCase().replace(/jpg/i, 'jpeg');
let r = type.match(/png|jpeg|bmp|gif/)[0];
return 'image/' + r;
};
const fileDownload = downloadUrl => {
let aLink = document.createElement('a');
aLink.style.display = 'none';
aLink.href = downloadUrl;
aLink.download = "下载文件名xxx.png";
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
let oContainer = document.querySelector("#canvasContainer");
document.body.removeChild(oContainer);
controlScale(_scale);
}
const eportImg = () => {
controlScale(0.8);
const oContainer = document.createElement('div');
oContainer.setAttribute('id', 'canvasContainer');
document.body.append(oContainer);
html2canvas(_target.get(0)).then(function (canvas) {
oContainer.appendChild(canvas);
setTimeout(function () {
const type = 'png';
const oCanvas = document.querySelector('#canvasContainer').getElementsByTagName('canvas')[0];
let imgData = oCanvas.toDataURL(type);
imgData = imgData.replace(_fixType(type), 'image/octet-stream');
fileDownload(imgData);
}, 0);
});
}
fetch('./d3.json').then(res => res.json()).then(res => {
init(res);
});
// 入口函数
const controlScale = scale => {
if (_target != null) {
_target.css({
'transform': 'scale(' + scale + ')',
'-webkit-transform': 'scale(' + scale + ')'
});
}
}
const onMouseScroll = e => {
e.preventDefault();
let wheel = e.originalEvent.wheelDelta || -e.originalEvent.detail;
const delta = Math.max(-1, Math.min(1, wheel));
if (delta < 0) {//向下滚动 放大
if (_scale >= 0.9) {
return;
} else {
_scale += 0.1;
controlScale(_scale);
}
} else {//向上滚动 缩小
if (_scale <= 0.3) {
_scale = 0.3;
// $('#chart-container').scrollTop((h));
return;
} else {
_scale -= 0.1;
controlScale(_scale);
}
}
}
$(document).on('mousewheel DOMMouseScroll', onMouseScroll);
((function () {
setInterval(() => {
$('.orgchart').css({
'cursor': 'pointer'
})
}, 1);
})()) //取悦boss
部分数据格式如下
实现了缩放,脱拽,导出,如果要自定义其他节点层级或样式复写下templete这个函数即可。