Я новичок в d3 js и могу загрузить SVG как png, но я столкнулся с некоторыми проблемами, пожалуйста, помогите мне.
Проблемы:
- Когда диаграмма расширена до ее большого размера, она не может быть загружена. Переменная
blob
равна null
.
canvas.toBlob(function (blob) {
var filesize = Math.round(blob.length / 1024) + ' KB';
if (callback) callback(blob, filesize);
});
Когда я загружаю изображение, оно содержит дополнительное пустое пространство. Изображение действительно загружается, когда диаграмма мала.
Вот мой код скрипта: -
// svg
function draw(redraw) {
var dragGroup = d3.behavior.drag()
.on('dragstart', function () {
d3.event.sourceEvent.stopPropagation();
}).on('drag', function (d, i) {
});
// var w = document.getElementById("chart").clientWidth;
// var h = document.getElementById("chart").clientHeight;
// if (download === true) {
// s.wSVG = '';//document.getElementById("productHierarchychart").clientWidth + 333;
// s.hSVG = '';//document.getElementById("productHierarchychart").clientHeight + (-45);
//}
//else
//{
s.wSVG = document.getElementById("productHierarchychart").clientWidth + 333;
s.hSVG = document.getElementById("productHierarchychart").clientHeight + (-45);
//}
// s.wSVG = window.innerWidth
// s.hSVG = window.innerHeight
s.depth = 1;
s.margin = { top: 20, right: 120, bottom: 60, left: 80 };
s.wChart = s.wSVG - s.margin.left - s.margin.right;
s.hChart = s.hSVG - s.margin.top - s.margin.bottom;
d3.select("#svgtag").remove();
s.nodesize = s.mode === "h" ? [s.def_x_nodesize - s.nodesizechg, s.def_y_nodesize - s.nodesizechg] : [s.def_x_nodesize + 230, s.def_y_nodesize];
s.tree = d3.layout.tree().nodeSize(s.nodesize);
s.diagonal = d3.svg.diagonal()
.projection(function (d) {
// return s.mode === "h" ? [d.y, d.x] : [d.x, d.y];
return s.mode === "h" ? [d.y + rectH + 20, d.x + rectW + (-02)] : [d.x + rectW + (-10), d.y + rectH + 40];
});
s.vis = d3.select(s.parent)
.append("svg:svg")
.attr("id", "svgtag")
// .attr("width", window.innerWidth)
// .attr("height", window.innerHeight)
.attr("width", s.wSVG)
.attr("height", s.hSVG)
// .call(s.zm = d3.behavior.zoom().scaleExtent([1, 3]).on("zoom", redraw)).append("g")
.append("svg:g")
.attr("id", "gtagimage")
.attr("transform", "translate(" + (s.mode === "v" ? ((s.wSVG + 100) / 2.5) : (s.margin.left)) + "," + (s.mode === "v" ? ((s.margin.top) - 60) : ((s.hSVG / 2) - 100)) + ")")
.append("svg:g")
.call(dragGroup)
.attr("id", "changeG")
.attr("class", "drawarea")
.append("svg:g")
.attr("transform", "translate(" + s.margin.left + "," + s.margin.top + ")");
s.root = s.data;
s.maxDepth = 6;
s.root.x0 = s.mode === "h" ? s.hChart / 2 : s.wChart / 2;
s.root.y0 = s.mode === "h" ? 0 : -100;
var zooming = d3.select("svg")
.call(d3.behavior.zoom()
.scaleExtent([0.5, 5])
.on("zoom", zoom));
zooming.on("dblclick.zoom", null);
zooming.on("mousewheel.zoom", null);
zooming.on("DOMMouseScroll.zoom", null); // disables older versions of Firefox
zooming.on("wheel.zoom", null);
// Initialize the display to show a few nodes.
if (redraw === false) {
s.root.children.forEach(toggleAll);
// s.root.children.forEach(collapse_1);
}
update(s.root);
}
function collapse_1(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse_1);
d.children = null;
}
}
function toggleAll(d) {
if (d.children) {
d.children.forEach(toggleAll);
toggle(d);
}
}
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
function update(source) {
var duration = d3.event && d3.event.altKey ? 5000 : 500;
// Compute the new tree layout.
var nodes = s.tree.nodes(s.root).reverse();
// Normalize for fixed-depth.
nodes.forEach(function (d) {
// var dx=0;
// if(d.x<s.root.x0){
// dx=d.x - ((d.name.length*(12)));
// }else{
// dx=d.x + ((d.name.length*(12)));
// }
d.y = s.mode === "h" ? d.depth * 320 : d.y === 0 ? d.depth * 40 : d.depth * 135; // To Change the link height distance
// d.y = s.mode === "h" ? d.depth * 280 : d.depth * 135; // To Change the link height distance
// d.x= s.mode === "h" ? d.x : dx;
});
// Update the nodes
var node = s.vis.selectAll("g.node")
.data(nodes, function (d) { return d.id || (d.id = ++s.i) })
.attr("data-expanded", function (d) {
if (d['children']) {
return true;
} else {
return false;
}
});
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("svg:g")
.attr("class", function (d) {
var typeName = (d.nodeType ? d.nodeType : d.empid);
typeName = typeName.replace(/ /g, '').toLowerCase();
return typeName + " node";
})
.attr("transform", function (d) { return s.mode === "h" ? "translate(" + (source.y0 === 0 ? 0 : (source.y0 + 40)) + "," + (source.x0 + (-15)) + ")" : "translate(" + (source.x0 + (-25)) + "," + (source.y0 === 0 ? 40 : (source.y0 + 05)) + ")" })
.attr("data-expanded", function (d) {
if (d['children']) {
return true;
} else {
return false;
}
})
.on("mouseover", texty)
.on("mouseout", removeTexty)
.on("click", click);
var link = s.vis.selectAll("path.link")
.data(s.tree.links(nodes), function (d) {
return d.target.id;
});
// Enter any new links at the parent's previous position.
link.enter().insert("svg:path", "g")
.attr("class", "link")
// .attr("id",function(d,i){return d.source.name.replace(/ /g,'')+'-'+d.source.children[i].name.replace(/ /g,'');})
.attr("d", function (d) {
var o = { x: source.x0, y: source.y0 };
return s.diagonal({ source: o, target: o });
})
.transition()
.duration(duration)
.attr("d", s.diagonal);
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", s.diagonal)
.attr("class", function (d) {
var text = $("#txtPosition").data('kendoComboBox').value();
if (text !== "") {
if (d.target.class !== undefined && d.target.class.includes("found")) {
return "link link-found";
}
else {
return "link";
}
}
else {
return "link";
}
});
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function (d) {
var o = { x: source.x, y: source.y };
return s.diagonal({ source: o, target: o });
})
.remove();
nodeEnter.append("svg:rect")
.attr("x", "-100px")
.attr("y", "-15px")
.attr("id", function (d) {
return (d.empid + "rectest");
})
.attr("width", "230px")
.attr("height", "55px")
.attr("border-radius", "25px !important")
.style("fill", "rgb(255,255,255)")
.style("stroke-width", "1")
//.style("stroke", "rgb(53,150,216)")
.style("stroke", "rgb(204, 204, 204)")
.style("rx", "3")
nodeEnter.append("image")
.attr("id", function (d) {
return d.empid;
})
.attr("xlink:href", function (d) {
var data = "";
$.ajax({
type: 'POST',
url: PhotoUrl,
async: false,
cache: false,
data: { Image1: d.Image, EmpID: d.empid },
success: function (response) {
data = response;
}
});
return data;
})
.attr("x", "-95px")
.attr("y", "-7px")
.attr("width", "40px")
.attr("height", "40px");
nodeEnter.append("svg:foreignObject")
.attr("width", 170)
.attr("height", 25)
.attr("x", -50)
.attr("y", -5)
.attr("class", "foreignObject1")
.append("xhtml:body")
.style("font", "14px 'Helvetica Neue'")
.attr("width", 170)
.attr("height", 18)
.attr("dx", ".35em")
.attr("dy", ".35em")
.attr("text-anchor", "unset")
.style("background-color", "white")
.style("fill-opacity", 1e-6)
.html(function (d) {
return ("<span class='texthide Nametext'>" + d.name + " (" + d.empid + ")" + "</span>");
});
nodeEnter.append("svg:foreignObject")
.attr("width", 125)
.attr("height", 25)
.attr("x", -50)
.attr("y", 15)
.append("xhtml:body")
.style("font", "14px 'Helvetica Neue'")
.attr("width", 170)
.attr("height", 18)
.attr("dx", ".35em")
.attr("dy", ".35em")
.attr("text-anchor", "unset")
.style("background-color", "white")
.style("fill-opacity", 1e-6)
.html(function (d) {
return ("<span class='texthide designationtext'>" + d.designation + "</span>");
});
nodeEnter.append("svg:foreignObject")
.attr("width", 45)
.attr("height", 25)
.attr("x", 80)
.attr("y", 15)
.append("xhtml:body")
.style("font", "14px 'Helvetica Neue'")
.attr("width", 170)
.attr("height", 18)
.attr("dx", ".35em")
.attr("dy", ".35em")
.attr("text-anchor", "unset")
.style("background-color", "white")
.style("fill-opacity", 1e-6)
.html(function (d) {
if (d.noofchild > 0) {
return ("<span class='pull-right noofchildtext'><img src='Assets/Images/Orgchart_Reportees.png' style='width: 14px; margin-top: -2px; fill : #91a4a5;'/>" + d.noofchild + "</span>");
}
});
//Photo
$('#saveButton').click(function (e) {
var oldx = $("#gtagimage")[0].getAttribute("transform").substr(10).split(",")[0];
var oldy = $("#gtagimage")[0].getAttribute("transform").substr(10).split(",")[1].slice(0, $("#gtagimage")[0].getAttribute("transform").substr(10).split(",")[1].length - 1);
$("#svgtag").attr("width", " ");
$("#svgtag").attr("height", " ");
var svgString = getSVGString(d3.select('svg').node());
if ($("#gtagimage")[0].getBoundingClientRect().width > 1200) {
svgString2Image(svgString, ((($("#gtagimage")[0].getBoundingClientRect().width + 2000))), ($("#gtagimage")[0].getBoundingClientRect().height + 500), 'png', save); // passes Blob and filesize String to the callback
}
else {
svgString2Image(svgString, ($("#gtagimage")[0].getBoundingClientRect().width + 2000), ($("#gtagimage")[0].getBoundingClientRect().height + 500), 'png', save); // passes Blob and filesize String to the callback
}
$("#svgtag").attr("width", "1256");
$("#svgtag").attr("height", "485");
d3.select('g').transition()
.duration(400)
//.attr('transform', 'translate(' + 542.4 + ',' + -40 + ')');
.attr('transform', 'translate(' + oldx + ',' + oldy + ')');
});
function save(dataBlob, filesize) {
saveAs(dataBlob, 'ESSOrgChart.png'); // FileSaver.js function
}
function getSVGString(svgNode) {
var cssStyleText = getCSSStyles(svgNode);
appendCSS(cssStyleText, svgNode);
var serializer = new XMLSerializer();
var svgString = serializer.serializeToString(svgNode);
if ($("#gtagimage")[0].getBoundingClientRect().width > 1200) {
var oldx = $("#gtagimage")[0].getAttribute("transform").substr(10).split(",")[0];
svgString = svgString.replace(oldx, $("#gtagimage")[0].getBoundingClientRect().width);
var oldy = $("#gtagimage")[0].getAttribute("transform").substr(10).split(",")[1].slice(0, $("#gtagimage")[0].getAttribute("transform").substr(10).split(",")[1].length - 1)
svgString = svgString.replace(oldy, (parseInt(oldy) + (600)));
}
svgString = svgString.replace("path.link { fill: none; stroke: rgb(204, 204, 204); stroke-width: 1.5px; }", "path.link { fill: none; stroke: rgb(204, 204, 204); stroke-width: 5px; }");
return svgString;
}
function getCSSStyles(parentElement) {
var selectorTextArr = [];
// Add Parent element Id and Classes to the list
selectorTextArr.push('#' + parentElement.id);
for (var c = 0; c < parentElement.classList.length; c++)
if (!contains('.' + parentElement.classList[c], selectorTextArr))
selectorTextArr.push('.' + parentElement.classList[c]);
// Add Children element Ids and Classes to the list
var nodes = parentElement.getElementsByTagName("*");
for (var i = 0; i < nodes.length; i++) {
var id = nodes[i].id;
if (!contains('#' + id, selectorTextArr))
selectorTextArr.push('#' + id);
var classes = nodes[i].classList;
for (var c = 0; c < classes.length; c++)
if (!contains('.' + classes[c], selectorTextArr))
selectorTextArr.push('.' + classes[c]);
}
// Extract CSS Rules
var extractedCSSText = "";
for (var i = 0; i < document.styleSheets.length; i++) {
var s = document.styleSheets[i];
try {
if (!s.cssRules) continue;
} catch (e) {
if (e.name !== 'SecurityError') throw e; // for Firefox
continue;
}
var cssRules = s.cssRules;
for (var r = 0; r < cssRules.length; r++) {
if (includes(cssRules[r].selectorText, selectorTextArr))
extractedCSSText += cssRules[r].cssText;
}
}
return extractedCSSText;
function contains(str, arr) {
return arr.indexOf(str) === -1 ? false : true;
}
function includes(str, arr) {
if ("undefined" !== typeof str) {
for (var q = 0; q < arr.length; q++) {
if (str.indexOf(arr[q]) !== -1) { return true; }
}
}
}
}
function appendCSS(cssText, element) {
var styleElement = document.createElement("style");
styleElement.setAttribute("type", "text/css");
styleElement.innerHTML = cssText;
var refNode = element.hasChildNodes() ? element.children[0] : null;
element.insertBefore(styleElement, refNode);
}
function svgString2Image(svgString, width, height, format, callback) {
var format = format ? format : 'png';
var imgsrc = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgString))); // Convert SVG string to data URL
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
var image = new Image();
image.onload = function () {
context.clearRect(0, 0, width, height);
context.drawImage(image, 0, 0, width, height);
canvas.toBlob(function (blob) {
var filesize = Math.round(blob.length / 1024) + ' KB';
if (callback) callback(blob, filesize);
});
};
image.src = imgsrc;
}