"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"HTML('')"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "07fb82cd",
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
"require.config({paths: {\n",
" d3: \"http://d3js.org/d3.v3.min\"\n",
"}});\n",
"\n",
"\n",
"\n",
"function visjsonld(jsonld, selector){\n",
" \n",
" require([\"d3\"], function(d3) {\n",
" \n",
" var config = {};\n",
" \n",
" var h = config.h || 800\n",
" , w = config.w || 3000\n",
" , maxLabelWidth = config.maxLabelWidth || 200\n",
" , transitionDuration = config.transitionDuration || 750\n",
" , transitionEase = config.transitionEase || 'cubic-in-out'\n",
" , minRadius = config.minRadius || 5\n",
" , scalingFactor = config.scalingFactor || 2;\n",
" \n",
" var i = 0;\n",
"\n",
" var tree = d3.layout.tree()\n",
" .size([h, w]);\n",
" \n",
" var diagonal = d3.svg.diagonal()\n",
" .projection(function(d) { return [d.y, d.x]; });\n",
" \n",
" d3.select(selector).selectAll(\"svg\").remove();\n",
" \n",
" var svg = d3.select(selector).append('svg')\n",
" .attr('width', w)\n",
" .attr('height', h)\n",
" .attr('style', 'background-color:#80CBC4 ')\n",
" .append('g')\n",
" .attr('transform', 'translate(' + maxLabelWidth + ',0)');\n",
" \n",
" var root = jsonldTree(jsonld);\n",
" root.x0 = h / 2;\n",
" root.y0 = 0;\n",
" root.children.forEach(collapse);\n",
" \n",
" function changeSVGWidth(newWidth) {\n",
" if (w !== newWidth) {\n",
" d3.select(selector + ' > svg').attr('width', newWidth);\n",
" }\n",
" }\n",
" \n",
" function jsonldTree(source) {\n",
" var tree = {};\n",
" \n",
" if ('@id' in source) {\n",
" tree.isIdNode = true;\n",
" tree.name = source['@id'];\n",
" if (tree.name.length > maxLabelWidth / 9) {\n",
" tree.valueExtended = tree.name;\n",
" tree.name = '...' + tree.valueExtended.slice(-Math.floor(maxLabelWidth / 9));\n",
" }\n",
" } else {\n",
" tree.isIdNode = true;\n",
" tree.isBlankNode = true;\n",
" // random id, can replace with actual uuid generator if needed\n",
" tree.name = '_' + Math.random().toString(10).slice(-7);\n",
" }\n",
" \n",
" var children = [];\n",
" Object.keys(source).forEach(function(key) {\n",
" if (key === '@id' || key === '@context' || source[key] === null) return;\n",
" \n",
" var valueExtended, value;\n",
" if (typeof source[key] === 'object' && !Array.isArray(source[key])) {\n",
" children.push({\n",
" name: key,\n",
" children: [jsonldTree(source[key])]\n",
" });\n",
" } else if (Array.isArray(source[key])) {\n",
" children.push({\n",
" name: key,\n",
" children: source[key].map(function(item) {\n",
" if (typeof item === 'object') {\n",
" return jsonldTree(item);\n",
" } else {\n",
" return { name: item };\n",
" }\n",
" })\n",
" });\n",
" } else {\n",
" valueExtended = source[key];\n",
" value = valueExtended;\n",
" if (value.length > maxLabelWidth / 9) {\n",
" value = value.slice(0, Math.floor(maxLabelWidth / 2)) + '...';\n",
" children.push({\n",
" name: key,\n",
" value: value,\n",
" valueExtended: valueExtended\n",
" });\n",
" } else {\n",
" children.push({\n",
" name: key,\n",
" value: value\n",
" });\n",
" }\n",
" }\n",
" });\n",
" \n",
" if (children.length) {\n",
" tree.children = children;\n",
" }\n",
" \n",
" return tree;\n",
" }\n",
" \n",
" function update(source) {\n",
" var nodes = tree.nodes(root).reverse();\n",
" var links = tree.links(nodes);\n",
" \n",
" nodes.forEach(function(d) { d.y = d.depth * maxLabelWidth; });\n",
" \n",
" var node = svg.selectAll('g.node')\n",
" .data(nodes, function(d) { return d.id || (d.id = ++i); });\n",
" \n",
" var nodeEnter = node.enter()\n",
" .append('g')\n",
" .attr('class', 'node')\n",
" .attr('transform', function(d) { return 'translate(' + source.y0 + ',' + source.x0 + ')'; })\n",
" .on('click', click);\n",
" \n",
" nodeEnter.append('circle')\n",
" .attr('r', 0)\n",
" .style('stroke-width', function(d) {\n",
" return d.isIdNode ? '2px' : '1px';\n",
" })\n",
" .style('stroke', function(d) {\n",
" return d.isIdNode ? '#F7CA18' : '#4ECDC4';\n",
" })\n",
" .style('fill', function(d) {\n",
" if (d.isIdNode) {\n",
" return d._children ? '#F5D76E' : 'white';\n",
" } else {\n",
" return d._children ? '#86E2D5' : 'white';\n",
" }\n",
" })\n",
" \n",
" \n",
" nodeEnter.append('text')\n",
" .attr('x', function(d) {\n",
" var spacing = computeRadius(d) + 5;\n",
" return d.children || d._children ? -spacing : spacing;\n",
" })\n",
" .attr('dy', '4')\n",
" .attr('text-anchor', function(d) { return d.children || d._children ? 'end' : 'start'; })\n",
" .text(function(d) { return d.name + (d.value ? ': ' + d.value : ''); })\n",
" .style('fill-opacity', 0)\n",
";\n",
" \n",
" var maxSpan = Math.max.apply(Math, nodes.map(function(d) { return d.y + maxLabelWidth; }));\n",
" if (maxSpan + maxLabelWidth + 20 > w) {\n",
" changeSVGWidth(maxSpan + maxLabelWidth);\n",
" d3.select(selector).node().scrollLeft = source.y0;\n",
" }\n",
" \n",
" var nodeUpdate = node.transition()\n",
" .duration(transitionDuration)\n",
" .ease(transitionEase)\n",
" .attr('transform', function(d) { return 'translate(' + d.y + ',' + d.x + ')'; });\n",
" \n",
" nodeUpdate.select('circle')\n",
" .attr('r', function(d) { return computeRadius(d); })\n",
" .style('stroke-width', function(d) {\n",
" return d.isIdNode ? '2px' : '1px';\n",
" })\n",
" .style('stroke', function(d) {\n",
" return d.isIdNode ? '#F7CA18' : '#4ECDC4';\n",
" })\n",
" .style('fill', function(d) {\n",
" if (d.isIdNode) {\n",
" return d._children ? '#F5D76E' : 'white';\n",
" } else {\n",
" return d._children ? '#86E2D5' : 'navy';\n",
" }\n",
" });\n",
" \n",
" nodeUpdate.select('text').style('fill-opacity', 1);\n",
" nodeUpdate.select('text').style('font-family', \"'Open Sans', 'Helvetica Neue', Helvetica, sans-serif\");\n",
" nodeUpdate.select('text').style('fill', '#333333');\n",
" nodeUpdate.select('text').style('font-size', '12px');\n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" var nodeExit = node.exit().transition()\n",
" .duration(transitionDuration)\n",
" .ease(transitionEase)\n",
" .attr('transform', function(d) { return 'translate(' + source.y + ',' + source.x + ')'; })\n",
" .remove();\n",
" \n",
" nodeExit.select('circle').attr('r', 0);\n",
" nodeExit.select('text').style('fill-opacity', 0);\n",
" \n",
" var link = svg.selectAll('path.link')\n",
" .data(links, function(d) { return d.target.id; });\n",
" \n",
" link.enter().insert('path', 'g')\n",
" .attr('class', 'link')\n",
" .attr('style', 'fill: none;stroke: #DADFE1;stroke-width: 1px;')\n",
" .attr('d', function(d) {\n",
" var o = { x: source.x0, y: source.y0 };\n",
" return diagonal({ source: o, target: o });\n",
" });\n",
" \n",
" link.transition()\n",
" .duration(transitionDuration)\n",
" .ease(transitionEase)\n",
" .attr('d', diagonal);\n",
" \n",
" link.exit().transition()\n",
" .duration(transitionDuration)\n",
" .ease(transitionEase)\n",
" .attr('d', function(d) {\n",
" var o = { x: source.x, y: source.y };\n",
" return diagonal({ source: o, target: o });\n",
" })\n",
" .remove();\n",
" \n",
" nodes.forEach(function(d) {\n",
" d.x0 = d.x;\n",
" d.y0 = d.y;\n",
" });\n",
" }\n",
" \n",
" function computeRadius(d) {\n",
" if (d.children || d._children) {\n",
" return minRadius + (numEndNodes(d) / scalingFactor);\n",
" } else {\n",
" return minRadius;\n",
" }\n",
" }\n",
" \n",
" function numEndNodes(n) {\n",
" var num = 0;\n",
" if (n.children) {\n",
" n.children.forEach(function(c) {\n",
" num += numEndNodes(c);\n",
" });\n",
" } else if (n._children) {\n",
" n._children.forEach(function(c) {\n",
" num += numEndNodes(c);\n",
" });\n",
" } else {\n",
" num++;\n",
" }\n",
" return num;\n",
" }\n",
" \n",
" function click(d) {\n",
" if (d.children) {\n",
" d._children = d.children;\n",
" d.children = null;\n",
" } else {\n",
" d.children = d._children;\n",
" d._children = null;\n",
" }\n",
" \n",
" update(d);\n",
" \n",
" // fast-forward blank nodes\n",
" if (d.children) {\n",
" d.children.forEach(function(child) {\n",
" if (child.isBlankNode && child._children) {\n",
" click(child);\n",
" }\n",
" });\n",
" }\n",
" }\n",
" \n",
" function collapse(d) {\n",
" if (d.children) {\n",
" d._children = d.children;\n",
" d._children.forEach(collapse);\n",
" d.children = null;\n",
" }\n",
" }\n",
" \n",
" update(root);\n",
" \n",
" \n",
" })\n",
" }\n",
"var data = {\n",
" \"@context\": \"https://linked.art/ns/v1/linked-art.json\",\n",
" \"id\": \"https://clevelandart.org/art/74540\",\n",
" \"type\": \"HumanMadeObject\",\n",
" \"_label\": \"Leda and the Swan\",\n",
" \"classified_as\": {\n",
" \"id\": \"http://vocab.getty.edu/aat/300033973\",\n",
" \"type\": \"Type\",\n",
" \"_label\": \"Drawing\",\n",
" \"classified_as\": {\n",
" \"id\": \"http://vocab.getty.edu/aat/300435443\",\n",
" \"type\": \"Type\",\n",
" \"_label\": \"Type of Work\"\n",
" }\n",
" },\n",
" \"identified_by\": [\n",
" {\n",
" \"id\": \"http://lod.example.org/museum/Identifier/2015.451\",\n",
" \"type\": \"Identifier\",\n",
" \"classified_as\": {\n",
" \"id\": \"http://vocab.getty.edu/aat/300312355\",\n",
" \"type\": \"Type\",\n",
" \"_label\": \"Accession Number\"\n",
" },\n",
" \"content\": \"2015.451\"\n",
" },\n",
" {\n",
" \"id\": \"http://lod.example.org/museum/Identifier/74540\",\n",
" \"type\": \"Identifier\",\n",
" \"classified_as\": {\n",
" \"id\": \"http://vocab.getty.edu/aat/300404621\",\n",
" \"type\": \"Type\",\n",
" \"_label\": \"Owner-Assigned Number\"\n",
" },\n",
" \"content\": \"74540\"\n",
" },\n",
" {\n",
" \"id\": \"https://clevelandart.org/art/74540/primary-name\",\n",
" \"type\": \"Name\",\n",
" \"classified_as\": {\n",
" \"id\": \"http://vocab.getty.edu/aat/300404670\",\n",
" \"type\": \"Type\",\n",
" \"_label\": \"Primary Name\"\n",
" },\n",
" \"content\": \"Leda and the Swan\"\n",
" }\n",
" ],\n",
" \"referred_to_by\": [\n",
" {\n",
" \"id\": \"https://clevelandart.org/art/74540/credit-line\",\n",
" \"type\": \"LinguisticObject\",\n",
" \"_label\": \"Credit Line for the Object\",\n",
" \"classified_as\": {\n",
" \"id\": \"http://vocab.getty.edu/aat/300418049\",\n",
" \"type\": \"Type\",\n",
" \"_label\": \"brief texts\"\n",
" },\n",
" \"content\": \"Bequest of Muriel Butkin\"\n",
" }\n",
" ],\n",
" \"member_of\": {\n",
" \"id\": \"https://clevelandart.org/art/74540/collection/Drawings\",\n",
" \"type\": \"Set\",\n",
" \"_label\": \"Drawings\",\n",
" \"classified_as\": {\n",
" \"id\": \"http://vocab.getty.edu/aat/300025976\",\n",
" \"type\": \"Type\",\n",
" \"_label\": \"collections (object groupings)\"\n",
" }\n",
" },\n",
" \"subject_of\": {\n",
" \"id\": \"https://clevelandart.org/art/2015.451\",\n",
" \"type\": \"LinguisticObject\",\n",
" \"_label\": \"Homepage for the Object\",\n",
" \"classified_as\": {\n",
" \"id\": \"http://vocab.getty.edu/aat/300266277\",\n",
" \"type\": \"Type\",\n",
" \"_label\": \"home pages\"\n",
" },\n",
" \"format\": \"text/html\"\n",
" },\n",
" \"produced_by\": {\n",
" \"id\": \"https://clevelandart.org/art/74540/production\",\n",
" \"type\": \"Production\",\n",
" \"_label\": \"Production of the Object\",\n",
" \"timespan\": {\n",
" \"id\": \"https://clevelandart.org/art/74540/production/timespan\",\n",
" \"type\": \"TimeSpan\",\n",
" \"_label\": \"date unknown\"\n",
" },\n",
" \"carried_out_by\": {\n",
" \"type\": \"Actor\",\n",
" \"_label\": \"Adolphe Yvon (French, 1817-1893), artist\"\n",
" }\n",
" },\n",
" \"current_owner\": {\n",
" \"id\": \"http://vocab.getty.edu/ulan/500300517\",\n",
" \"type\": \"Group\",\n",
" \"_label\": \"Cleveland Museum of Art\",\n",
" \"classified_as\": {\n",
" \"id\": \"http://vocab.getty.edu/aat/300312281\",\n",
" \"type\": \"Type\",\n",
" \"_label\": \"museums (institutions)\"\n",
" }\n",
" }\n",
"}; var selector = \"#example\"; visjsonld(data, selector); "
],
"text/plain": [
""
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import display,HTML,Javascript\n",
"\n",
"code2 = 'var data = ' + factory.toString(objLA, compact=False) + '; var selector = \"#example\"; visjsonld(data, selector); ' \n",
"\n",
"with open('src/js/visld2.js', 'r') as _jscript:\n",
" code = _jscript.read() + code2\n",
"\n",
"Javascript(code)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "82991ad0",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"interpreter": {
"hash": "40d3a090f54c6569ab1632332b64b2c03c39dcf918b08424e98f38b5ae0af88f"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}