github:https://github.com/violectyc/javascript-orgchart
部分截图如下
基本代码如下入口函数在fetch
html
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这个函数即可。