Created
November 4, 2023 16:13
-
-
Save nigjo/4faca926fa714d715734e94bae1c2201 to your computer and use it in GitHub Desktop.
A single function to convert JSON Data to a SVG Element
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Convert a JSON data structure to a svg element with content. | |
* | |
* Some special keys are treated as tag name ("<"), text content ("_"), | |
* style-attribute ("~") or child elements (">"). All other | |
* keys are used as attribute names to the svg element. | |
* | |
* Text content or attribute values may be a single string or an array of | |
* strings (joined together for output). | |
* | |
* "styles" may be defined as a "normal" attribute or via the "~" key as an | |
* object of CSS key-value-pairs. | |
* | |
* This function does no validation to the json or svg data. | |
* | |
* @argument {object} data svg image (part) as json structure | |
* | |
* @returns {Element} A SVG Element | |
*/ | |
function jsonToSvg(data) { | |
const SVGNS = 'http://www.w3.org/2000/svg'; | |
if (data['<'] === '!') { | |
if (typeof (data['_']) === 'object') { | |
return document.createComment(data['_'].join('')); | |
} else { | |
return document.createComment(data['_']); | |
} | |
} | |
let e = document.createElementNS(SVGNS, data['<']); | |
for (let k of Object.keys(data)) { | |
switch (k) { | |
case '<': | |
//ignore tag name here | |
break; | |
case '_': | |
if (typeof (data[k]) === 'object') { | |
e.textContent = data[k].join(''); | |
} else { | |
e.textContent = data[k]; | |
} | |
break; | |
case '~': | |
//styles | |
let styles = ""; | |
for (const [n, v] of Object.entries(data[k])) { | |
styles += `${n}:${v};`; | |
} | |
e.setAttribute('style', styles); | |
break; | |
case '>': | |
//children | |
for (let c of data[k]) { | |
e.append(jsonToSvg(c)); | |
} | |
break; | |
default: | |
if (typeof (data[k]) === 'object') { | |
e.setAttribute(k, data[k].join('')); | |
} else { | |
e.setAttribute(k, data[k]); | |
} | |
break; | |
} | |
} | |
return e; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title>json2svg Sample</title> | |
<script src="json2svg.js"></script> | |
<script> | |
fetch('sample.json').then(r => r.json()).then(j => { | |
j.width = j.height = 512; | |
j['>'].unshift({ | |
"<": "style", | |
"_": [ | |
"path{", | |
"fill:red;", | |
"stroke:none;", | |
"}" | |
] | |
}); | |
document.body.append(jsonToSvg(j)); | |
}); | |
</script> | |
</head> | |
<body> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"<": "svg", | |
"viewBox": "0 0 100 100", | |
">": [ | |
{ | |
"<": "!", | |
"_": "from https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path" | |
}, | |
{ | |
"<": "path", | |
"d": [ | |
"M 10,30\n", | |
"A 20,20 0,0,1 50,30\n", | |
"A 20,20 0,0,1 90,30\n", | |
"Q 90,60 50,90\n", | |
"Q 10,60 10,30 z" | |
] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment