UNPKG

g-chart-component

Version:

自定义图表插件

823 lines (778 loc) 24.5 kB
import * as d3 from "d3"; const TreeList = (data, loadAPiData, setMsg, waterText) => { const target = document.getElementById("treeListBox"); const svgId = 'treeListBox'; var width = target ? target.clientWidth : '100%'; const height = target ? target.clientHeight : '100%'; var guquanTupu; var rootData; var barHeight = 50; var barWidth = width; var nodes; var _rootD; getDataTupu(); function getDataTupu() { rootData = { name: data.rootName, children: data.children }; addFlag(rootData); guquanTupu = new drawGuquanTupu(rootData); } function drawGuquanTupu(rootData) { var i = 0; var duration = 400; var container; var isExtent = false; var scale = 1; var diagonal,tree, treeRoot; d3.select("#" + svgId).selectAll("*").remove(); var svg = d3.select("#" + svgId).append("svg").attr("xmlns", "http://www.w3.org/2000/svg"); initSvg(); update(rootData); function dragmove() { var x = parseInt(container.attr("transform").split(',')[0].split('(')[1]); var y = parseInt(container.attr("transform").split(',')[1].split(')')[0]); var transform = d3.zoomTransform(event.target); container.attr("transform", "translate(" + (x + transform.x) + "," + (y + transform.y) + ") scale(" + scale + ")"); } function initSvg() { svg.selectAll("*").remove(); svg.attr("width", width); svg.attr("height", height); svg.attr("class", "svgBox"); container = svg.append("g"); var zoom = d3.drag().on("drag", dragmove); svg.call(zoom); container.attr("transform", "translate(5,60)"); container.attr("id", "gbox"); } function update(source) { rootData.x0 = 0; rootData.y0 = 0; tree = d3.tree().nodeSize([0, 20]); diagonal = function (d) { return "M" + d.source.y + "," + d.source.x + "C" + (d.source.y + d.target.y) / 2 + "," + d.source.x + " " + (d.source.y + d.target.y) / 2 + "," + d.target.x + " " + d.target.y + "," + d.target.x; } treeRoot = d3.hierarchy(rootData); tree(treeRoot); nodes = treeRoot.descendants(); var nodeX = 0; nodes.forEach(function (n, i) { n.x = nodeX; nodeX += n.data.height + 5; }); svg.attr("height", Math.max(590, nodeX + 160)); var height = Math.max(500, nodeX); d3.select("svg").transition() .duration(duration); d3.select(self.frameElement).transition() .duration(duration) .style("height", height + "px"); // Update the nodes… var node = container.selectAll("g.node") .data(nodes, function (d) { return d.id || (d.id = ++i); }); var nodeEnter = node.enter().append("g") .attr("class", "node") .attr("transform", function (d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) .style("opacity", 1); // Enter any new nodes at the parent's previous position. nodeEnter.append("rect") .attr("y", function (d) { if (d.depth == 0) { return -d.data.height / 2 } else { return -15; } }) .attr("height", function (d) { return d.data.height }) .attr("width", function(d){ if(d.depth == 0){ return barWidth-20 }else{ return barWidth-30 } }) .style("stroke", "#999999") .attr("fill", "#ffffff") .attr('fill-opacity', 0) .attr("stroke-width", 0.5) .on("click", click); nodeEnter.append("rect") .attr("y", function (d) { if (d.depth == 0) { return -d.data.height / 2 } else { return -15; } }) .attr("height", function (d) { return d.data.height }) .attr("width", 5) .style("fill", color) .style("fill-opacity", 1) .on("click", click); nodeEnter.append("text") .attr("dy", 3.5) .attr("dx", 30.5) .text(function (d) { if (d.data.name && d.data.name.length > 24) { return d.data.name.substr(0, 23) + '…'; } else { return d.data.name; } }) .attr("fill", "#333333") .style("font-size", "12px") .style("font-weight", "bold") .on("click", click); nodeEnter.each(function (d) { if (d.data.sign1) { d3.select(this).append("rect") .attr("x", 30) .attr("y", 13) .attr("rx", 2) .attr("ry", 2) .attr("height", 20) .attr("width", 44) .attr("fill", "#FE485E") .attr('fill-opacity', 0.08) .attr("stroke-width", 0.5); d3.select(this).append("text") .attr("dx", 35) .attr("dy", 27) .attr("fill", "#fe485e") .style("font-size", "11px") .text(d=> d.data.sign1); if (d.data.sign2) { d3.select(this).append("rect") .attr("x", 84) .attr("y", 13) .attr("rx", 2) .attr("ry", 2) .attr("height", 20) .attr("width", 66) .attr("fill", "#EEA324") .attr('fill-opacity', 0.08) .attr("stroke-width", 0.5); d3.select(this).append("text") .attr("dx", 89) .attr("dy", 27) .attr("fill", "#EEA324") .style("font-size", "11px") .text(d => d.data.sign2); if (d.data.sign3) { d3.select(this).append("rect") .attr("x", 160) .attr("y", 13) .attr("rx", 2) .attr("ry", 2) .attr("height", 20) .attr("width", 66) .attr("fill", "#128BED") .attr('fill-opacity', 0.08) .attr("stroke-width", 0.5); d3.select(this).append("text") .attr("dx", 165) .attr("dy", 27) .attr("fill", "#128BED") .style("font-size", "11px") .text(d => d.data.sign3); } } } else { if (d.data.sign2) { d3.select(this).append("rect") .attr("x", 30) .attr("y", 13) .attr("rx", 2) .attr("ry", 2) .attr("height", 20) .attr("width", 66) .attr("fill", "#EEA324") .attr('fill-opacity', 0.08) .attr("stroke-width", 0.5); d3.select(this).append("text") .attr("dx", 35) .attr("dy", 27) .attr("fill", "#EEA324") .style("font-size", "11px") .text(d => d.data.sign2); if (d.data.sign3) { d3.select(this).append("rect") .attr("x", 106) .attr("y", 13) .attr("rx", 2) .attr("ry", 2) .attr("height", 20) .attr("width", 66) .attr("fill", "#128BED") .attr('fill-opacity', 0.08) .attr("stroke-width", 0.5); d3.select(this).append("text") .attr("dx", 111) .attr("dy", 27) .attr("fill", "#128BED") .style("font-size", "11px") .text(d => d.data.sign3); } } else { if (d.data.sign3) { d3.select(this).append("rect") .attr("x", 30) .attr("y", 13) .attr("rx", 2) .attr("ry", 2) .attr("height", 20) .attr("width", 66) .attr("fill", "#128BED") .attr('fill-opacity', 0.08) .attr("stroke-width", 0.5); d3.select(this).append("text") .attr("dx", 35) .attr("dy", 27) .attr("fill", "#128BED") .style("font-size", "11px") .text(d => d.data.sign3); } } } }) nodeEnter.append("text") .attr("dy", function (d) { if (d.data.sign2 || d.data.sign3 || d.data.sign1) { return 50.5; } return 20.5; }) .attr("dx", 30.5) .style("font", "11px sans-serif") .attr("fill", "#666666") .text(function (d) { if (d.depth == 0) { return ""; } else { return d.data.key1 + ':'; } }); nodeEnter.append("text") .attr("dy", function (d) { if (d.data.sign2 || d.data.sign3 || d.data.sign1) { return 50.5; } return 20.5; }) .attr("dx", 85.5) .style("font", "11px sans-serif") .attr("fill", "#ff7e00") .text(function (d) { if (d.depth == 0) { return ""; } else { if (d.data.value1) { return d.data.value1; } return '-'; } }); nodeEnter.append("text") .attr("dy", function (d) { if (d.data.sign2 || d.data.sign3 || d.data.sign1) { return 50.5; } return 20.5; }) .attr("dx", 150.5) .style("font", "11px sans-serif") .attr("fill", "#666666") .text(function (d) { if (d.depth == 0) { return ""; } else { return d.data.key2 + ':' } }); nodeEnter.append("text") .attr("dy", function (d) { if (d.data.sign2 || d.data.sign3 || d.data.sign1) { return 50.5; } return 20.5; }) .attr("dx", 205.5) .style("font", "11px sans-serif") .attr("fill", "#ff7e00") .text(function (d) { if (d.depth == 0) { return ""; } else { if (d.data.value2) { return d.data.value2; } return "-"; } }); nodeEnter.append("path") .attr("d", function (d) { if (d.depth == 0) { _rootD = d; if (d.data._children && d.data._children.length > 0) { return "M7 -2 H11 V-6 H13 V-2 H17 V0 H13 V4 H11 V0 H7 Z" } else if (d.children && d.children.length > 0) { return "M7 -2 H17 V0 H7 Z" } } else { if (d.data._children && d.data._children.length > 0) { return "M7 6 H11 V2 H13 V6 H17 V8 H13 V12 H11 V8 H7 Z" } else if ((d.data.children && d.data.children.length > 0)) { return "M7 6 H17 V8 H7 Z" } if(d.data.isSearch==='Y')return "M7 6 H11 V2 H13 V6 H17 V8 H13 V12 H11 V8 H7 Z" } }) .attr("fill", "#bbbbbb") .on("click", function (d) { if (d.depth > 0 || true) { click(d); } }); nodeEnter.append("circle") .attr("cx", 12) .attr("cy", function (d) { if (d.depth == 0) { return -1; } return 7; }) .attr("r", function (d) { if ((d._children && d._children.length > 0) || (d.data._children && d.data._children.length > 0) ||d.data.isSearch==='Y') { return "6" } else if ((d.children && d.children.length > 0)|| (d.data.children && d.data.children.length > 0) || d.data.isSearch==='Y') { return "6" } }) .attr("fill", "none") .attr("stroke", "#999999") .attr("stroke-width", "0.5") .on("click", function (d) { if (d.depth > 0) { click(d); } }); // Transition nodes to their new position. nodeEnter.transition() .duration(duration) .attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; }) .style("opacity", 1); node.transition() .duration(duration) .attr("transform", function (d) { const y = d.y || d.y0; const x = d.x || d.x0; return "translate(" + y + "," + x + ")"; }) .style("opacity", 1) .select("rect") .style("stroke", "#999999"); node.transition() .duration(duration) .attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; }) .style("opacity", 1) .select("path") .attr("d", function (d) { if (d.depth == 0) { if (d.data._children && d.data._children.length > 0) { return "M7 -2 H11 V-6 H13 V-2 H17 V0 H13 V4 H11 V0 H7 Z" } else if (d.data.children && d.data.children.length > 0) { return "M7 -2 H17 V0 H7 Z" } } else { if (d.data._children && d.data._children.length > 0) { return "M7 6 H11 V2 H13 V6 H17 V8 H13 V12 H11 V8 H7 Z" } else if (d.data.children && d.data.children.length > 0) { return "M7 6 H17 V8 H7 Z" } if(d.data.isSearch==='Y')return "M7 6 H11 V2 H13 V6 H17 V8 H13 V12 H11 V8 H7 Z" } }); // Transition exiting nodes to the parent's new position. node.exit().transition() .duration(duration) .attr("transform", function (d) { const y = source.y || source.y0; const x = source.x || source.x0; return "translate(" + y + "," + x + ")"; }) .style("opacity", 1e-6) .remove(); // Update the links… var link = container.selectAll("path.link") .data(treeRoot.links(), function (d) { return d.target.id; }); // Enter any new links at the parent's previous position. link.enter().insert("path", "g") .attr("class", "link") .attr("fill", "none") .attr("stroke-width", "0.5px") .attr("stroke", function (d) { if (d.target.data.sign1) { return "#fe485e"; } else if (d.target.data.type == 1) { return "#7985f3"; } else if(d.target.data.type == 2) { return "#4aceb1"; }else{ return "#FB813D"; } }) .attr("d", function (d) { var o = { x: source.x0, y: source.y0 }; return diagonal({ source: o, target: o }); }) .style("stroke", function (d) { if (d.target.data.sign1) { return "#fe5151"; } }) .transition() .duration(duration) .attr("d", function (d) { return diagonal(d) }) .style("stroke", function (d) { if (d.target.data.sign1) { return "#fe5151"; } }); // Transition links to their new position. link.transition() .duration(duration) .attr("d", function (d) { return diagonal(d) }); // Transition exiting nodes to the parent's new position. link.exit().transition() .duration(duration) .attr("d", function (d) { var o = { x: source.x || source.x0, y: source.y || source.y0 }; return diagonal({ source: o, target: o }); }) .remove(); // Stash the old positions for transition. nodes.forEach(function (d) { d.x0 = d.x; d.y0 = d.y; }); } function click(e) { var d = e.target.__data__; if(d.data.children === undefined){ const param = { key: d.name, id: d.id } loadAPiData(param, ({code, data}) => { d.children = data.children.map((item)=>{ if(item.sign1){ item.height = barHeight+30 }else{ item.height = barHeight } return item }) update(rootData); },()=>{ setMsg('暂无下探数据'); d.data.children = undefined update(rootData); }) return } const children = d.children || d.data.children; if (children) { for(let i = 0; i< children.length; i++) { if(children[i].data) { children[i] = { ...children[i], ...children[i].data } } } d.data._children = children; d._children = children; d.data.children = null; d.children = null; d.data.isClose = true; } else { const _children = d._children || d.data._children; if(_children){ for(let i = 0; i< _children.length; i++) { if(_children[i].data) { _children[i] = { ..._children[i], ..._children[i].data } } } } d.children = _children; d.data.children = _children; d.data._children = null; d._children = null; d.data.isClose = false; } update(rootData); } function color(d) { if (d.depth == 0) { return "#128bed"; } else { if (d.data.sign1) { return "#fe5151"; } if (d.data.type == 1) { return "#7985f3"; } if (d.data.type == 2) { return "#4aceb1"; } if(d.data.type == 3){ return "#FB813D" //其它类型左侧边边的颜色 } } } function traverseTree(node) { if (node._children) { node.children = node._children; node._children = null; } if (node.children && node.children.length > 0) { for (var i = 0; i < node.children.length; i++) { traverseTree(node.children[i]); } } } function post(URL, PARAMS) { var temp = document.createElement("form"); temp.action = URL; temp.enctype = "multipart/form-data"; temp.method = "post"; temp.style.display = "none"; for (var x in PARAMS) { var opt = document.createElement("textarea"); opt.name = x; opt.value = PARAMS[x]; // alert(opt.name) temp.appendChild(opt); } document.body.appendChild(temp); temp.submit(); return temp; } // 展开收缩 d3.select("#guquanExtent").on('click', () => { if (!isExtent) { traverseTree(rootData); update(rootData); d3.select("#guquanExtent").html(` <i class="iconfont iconTab_icon_Putaway ft24"></i> <span>收起</span> `); isExtent = true; } else { nodes.forEach(function (d) { if (d.depth > 0) { if (d.data.children) { d.data._children = d.data.children; d.data.children = null; } } }); update(rootData); d3.select("#guquanExtent").html(`<i class="iconfont iconTab_icon_Expand ft24"></i> <span>展开</span>`) isExtent = false; } }) // 一键展开 d3.select("#open").on("click", ()=>{ traverseTree(rootData); update(rootData); isExtent = true; }); // 一键收起 d3.select("#close").on("click", ()=>{ if (!_rootD.data.isClose) { click(_rootD); } }); // 还原 d3.select("#reduction").on("click", () => { nodes.forEach(function (d) { if (d.depth > 0) { if (d.data.children) { d.data._children = d.data.children; d.data.children = null; } } }); update(rootData); isExtent = false; }); // 刷新 d3.select("#guquanRefresh").on('click', () => { d3.select("#guquanExtent").html(` <i class="iconfont iconTab_icon_Expand ft24"></i> <span>展开</span> `); traverseTree(rootData); initSvg(); update(rootData); isExtent = false; scrollTo(0, 0); }) //放大 d3.select("#scaleLar").on('click', () => { var arr = container.attr("transform").split(','); var x = arr[0].split('(')[1] var y = arr[1].split(')')[0] if (scale < 4) { scale += 0.2; } container.transition() .duration(500) .attr("transform", "translate(" + (x) + "," + (y) + ") scale(" + scale + ")"); }) // 缩小 d3.select("#scaleSml").on('click', () => { var arr = container.attr("transform").split(','); var x = arr[0].split('(')[1] var y = arr[1].split(')')[0] if (scale > 0.2) { scale -= 0.2; } container.transition() .duration(500) .attr("transform", "translate(" + (x) + "," + (y) + ") scale(" + scale + ")"); }) // 保存图片 d3.select("#save").on('click', () => { var gNode = target.querySelector('#gbox'); var _gData = gNode.getBoundingClientRect(); var saveMain = document.getElementById('saveMain'); // 需要保存的内容的暂存处理空间 var d3Svg = d3.select('#' + svgId + ' svg'); var _svgWidth = d3Svg.attr('width'); var _svgHeight = d3Svg.attr('height'); var maxW = Math.max(_svgWidth, _gData.width)+10; var maxH = Math.max(_svgHeight, _gData.height); var svgXml = target.innerHTML; // 将所需保存的内容放到暂存空间 saveMain.innerHTML = svgXml; var saveMainSvg = saveMain.querySelector('.svgBox'); var saveMainG = saveMain.querySelector('#gbox'); saveMainSvg.setAttribute('width', maxW); saveMainSvg.setAttribute('height', maxH); saveMainG.setAttribute('transform', `translate(5,60) scale(1)`) var newSvgXml = saveMain.innerHTML; var image = new Image(); image.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(newSvgXml))); setTimeout(function () { var canvas = document.createElement('canvas'); //准备空画布 canvas.width = maxW; canvas.height = maxH; var context = canvas.getContext('2d'); //取得画布的2d绘图上下文 if (waterText) { var shuiyinCvs = shuiyin().shuiyinCvs; var pat = context.createPattern(shuiyinCvs, "repeat"); context.fillStyle = pat; } else { context.fillStyle = "#fff"; } context.fillRect(0, 0, maxW, maxH); context.drawImage(image, 0, 0); downloadimg(canvas); }, 100); }) } function downloadimg(canvas) { var qual = 1; if (canvas.width > 3000) { qual = 0.8; } else if (canvas.width > 5000) { qual = 0.6; } //设置保存图片的类型 var downUrl = canvas.toDataURL('image/jpg', qual); var filename = `${rootData.name}${new Date().toLocaleDateString()}结构图.jpg`; var a = document.createElement("a"); a.style.display = "none"; a.href = downUrl; a.download = filename; a.click(); } // 设置水印 function shuiyin() { var cvs = document.createElement('canvas'); var ctx = cvs.getContext('2d'); cvs.width = 180; cvs.height = 160; ctx.fillStyle = "rgba(255, 255, 255, 1)"; ctx.fillRect(0, 0, 180, 160); ctx.fill(); ctx.rotate(-30*Math.PI/180); ctx.font = "19px 微软雅黑"; ctx.textAlign = 'left'; ctx.textBaseline = 'Middle'; // ctx.strokeStyle = '#c0c0c0'; // ctx.strokeText(waterText, -30, 80); ctx.fillStyle = '#ddd'; ctx.fillText(waterText, -30, 125); ctx.rotate(30*Math.PI/180); const shuiyinUrl = cvs.toDataURL('image/jpeg', 1); // new Image().src = shuiyinUrl; return { shuiyinImg: shuiyinUrl, shuiyinCvs: cvs }; } function addFlag(node) { if (node.sign2 || node.sign3 || node.sign1) { node.height = barHeight + 30; } else { node.height = barHeight; } if (node.children) { for (var i = 0; i < node.children.length; i++) { addFlag(node.children[i]); } } } } export default TreeList;