Commit 1213f299 authored by Adrian Wuillemet's avatar Adrian Wuillemet
Browse files

#65 Add saving of json, png and code from preview

parent 67008cde
Pipeline #4355 passed with stage
in 40 seconds
......@@ -74,6 +74,7 @@
<button id="save-as-svg-btn" title="Save graph as svg.">SVG</button>
<button id="save-as-png-btn" title="Save graph as png.">PNG</button>
<button id="save-as-json-btn" title="Save graph as json.">JSON</button>
<button id="save-code-btn" title="Save graph as code.">CODE</button>
</div>
</div>
......
......@@ -38,68 +38,129 @@ function graphCSSRules() {
function saveSVG() {
if(graph.nodes.length !== 0) {
let svg : any = document.querySelector("svg").cloneNode(true);
let styles = graphCSSRules();
let svgcode = `<?xml version="1.0" encoding="UTF-8"?>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg="http://www.w3.org/2000/svg"
height="210mm"
width="297mm"
viewBox="0 0 297 210"
version="1.1"
id="svg57"
>
<defs id="defs51" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1330"
inkscape:window-maximized="1" />
<style type="text/css">${styles}</style>
<metadata id="metadata54">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="scale(0.25)" inkscape:label="Ebene 1" inkscape:groupmode="layer" id="layer1">${svg.innerHTML}</g>
</svg>
`;
download(svgcode, `${filename()}.svg`, "image/svg+xml");
download(svgToString(), `${filename()}.svg`, "image/svg+xml");
} else {
window.alert('Draw a graph first to save it as SVG!');
notifyOfEmptyGraph();
}
}
function saveCode() {
let code = d3.select("#code-container").html();
download(code, `${filename()}.txt`, "text/plain");
function svgToString() {
let svg : any = document.querySelector("svg").cloneNode(true);
let styles = graphCSSRules();
return `<?xml version="1.0" encoding="UTF-8"?>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg="http://www.w3.org/2000/svg"
height="210mm"
width="297mm"
viewBox="0 0 297 210"
version="1.1"
id="svg57"
>
<defs id="defs51" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1330"
inkscape:window-maximized="1" />
<style type="text/css">${styles}</style>
<metadata id="metadata54">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="scale(0.25)" inkscape:label="Ebene 1" inkscape:groupmode="layer" id="layer1">${svg.innerHTML}</g>
</svg>
`;
}
let exchangeTypes = new Map([
["python", "py"],
["javascript", "js"],
["typescript", "ts"]
]);
function saveCode(code, language) {
if(code && code.indexOf('ERROR') != 0) {
let ending = language;
if (exchangeTypes.has(language)) {
ending = exchangeTypes.get(language);
}
download(code, `${filename()}.${ending}`, "text/plain");
} else {
window.alert('There is no code to save!');
}
}
function savePNG(): void {
window.alert('Not yet implemented');
if(graph.nodes.length > 0) {
//code adoption of https://stackoverflow.com/questions/3975499/convert-svg-to-image-jpeg-png-etc-in-the-browser
let downloadPNG = (data, filename) => {
var evt = new MouseEvent("click", {
view: window,
bubbles: false,
cancelable: true
});
var a = document.createElement("a");
a.setAttribute("download", filename);
a.setAttribute("href", data);
a.setAttribute("target", '_blank');
a.dispatchEvent(evt);
}
let canvas = document.createElement("canvas");
let container = document.getElementById('graph-container');
canvas.width = container.offsetWidth;
canvas.height = container.offsetHeight;
var context = canvas.getContext("2d");
context.clearRect(0, 0, container.offsetWidth, container.offsetHeight);
//@ts-ignore
let DOMURL = window.URL || window.webkitURL || window;
let img = new Image();
let svgBlob = new Blob([svgToString()], {type: "image/svg+xml;charset=utf-8"});
let url = DOMURL.createObjectURL(svgBlob);
img.onload = () => {
context.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
let imgURI = canvas
.toDataURL("image/png")
.replace("image/png", "image/octet-stream");
downloadPNG(imgURI, `${filename()}.png`);
};
img.src = url;
} else {
notifyOfEmptyGraph();
}
}
function saveJson(): void {
window.alert('Not yet implemented');
if(graph.nodes.length > 0) {
download(JSON.stringify(graph), `${filename()}.json`, 'text/json');
} else {
notifyOfEmptyGraph();
}
}
function notifyOfEmptyGraph() {
window.alert('Please draw a graph first before you save it!');
}
function filename(): string {
......
......@@ -2,6 +2,7 @@
/// <reference path="eel.ts" />
/// <reference path="prism.d.ts" />
let lastGeneratedCode: [string, string];
d3.select("#code-gen-button").on("click", () => {
let fsm = {
......@@ -44,6 +45,8 @@ d3.select('#save-as-png-btn').on('click', () => savePNG());
d3.select('#save-as-json-btn').on('click', () => saveJson());
d3.select('#save-code-btn').on('click', () => saveLastGeneratedCode());
let nameField = d3.select('#graph-name-field')
.on('focusout', () => changedGraphName())
.on("keypress", () => {
......@@ -64,14 +67,26 @@ function changedGraphName(): void {
graph.name = newName;
}
function saveLastGeneratedCode() {
if(lastGeneratedCode) {
saveCode(lastGeneratedCode[0], lastGeneratedCode[1]);
} else {
window.alert('No valid code can be saved!');
}
}
function displayCode(code: string, error: string, language: string): void {
if(error) {
lastGeneratedCode = undefined;
d3.select("#code-container")
.html(`ERROR:\n\n${error}`)
.classed("error", true)
d3.select('#toggle-code-button')
.classed("error", true);
} else {
lastGeneratedCode = [code, language];
let codeContainer = d3.select("#code-container");
if(d3.select('#text-area').classed('selected')) {
codeContainer
......@@ -81,7 +96,7 @@ function displayCode(code: string, error: string, language: string): void {
.classed("error", false);
Prism.highlightAllUnder(document.getElementById("code-container"));
} else {
saveCode();
saveCode(code, language);
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment