{ "cells": [ { "cell_type": "code", "execution_count": 2, "id": "d5a29dd1", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.core.display import HTML\n", "HTML(\"\"\"\n", "\n", "\"\"\")" ] }, { "cell_type": "markdown", "id": "11e94730", "metadata": {}, "source": [ "# Collections Data to Linked Art - Cleveland Museum of Art\n", "\n", "This Jupyter notebook transforms collection data from the Cleveland Museum of Art to a Linked Art representation in a JSON-LD format.\n", "\n", "## Collection Data\n", "\n", "The input data file is available from the Cleveland Museum of Art's GitHub repository:\n", "https://github.com/ClevelandMuseumArt/openaccess\n", "\n", "## Transformation Process\n", "\n", "1. Read CSV file\n", "2. Convert CSV file to Python Dictionary\n", "3. Create a field mapping between the CSV file fields and the Linked Art data model\n", "4. Create an object property dictionary" ] }, { "cell_type": "code", "execution_count": 2, "id": "e14c71a3", "metadata": {}, "outputs": [], "source": [ "try:\n", " import IPython\n", "except:\n", " %pip install IPython\n", " import IPython \n", " \n", "from IPython.display import display,IFrame,HTML, Javascript\n", " \n", "try:\n", " import json\n", "except:\n", " %pip install json\n", " import json \n", " \n", "try:\n", " import csv\n", "except:\n", " %pip install csv\n", " import csv\n", " \n", "import os\n", "\n", "try:\n", " import cromulent \n", "except:\n", " %pip install cromulent\n", " import cromulent\n", "\n", "from cromulent.model import factory\n", " \n", "import lib.linkedart as la \n", "\n", "try:\n", " import pandas as pd\n", "except:\n", " %pip install pandas\n", " import pandas as pd\n", " \n", " " ] }, { "cell_type": "markdown", "id": "91b86264", "metadata": {}, "source": [ "### Parse Collection Data CSV File" ] }, { "cell_type": "code", "execution_count": 3, "id": "cf022629", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
idaccession_numbershare_license_statustombstonecurrent_locationtitletitle_in_original_languageseriesseries_in_original_languagecreation_date...digital_descriptionwall_descriptionexternal_resourcescitationscatalogue_raisonneurlimage_webimage_printimage_fullupdated_at
0745392015.449CC0A Miller's Carriage, c. 1895. Albert-Charles L...NaNA Miller's CarriageNaNNaNNaNc. 1895...NaNNaN{'wikidata': [], 'internet_archive': ['https:/...NaNNaNhttps://clevelandart.org/art/2015.449https://openaccess-cdn.clevelandart.org/2015.4...https://openaccess-cdn.clevelandart.org/2015.4...https://openaccess-cdn.clevelandart.org/2015.4...2021-06-29 06:35:50.572000
1745402015.451CC0Leda and the Swan. Adolphe Yvon (French, 1817-...NaNLeda and the SwanNaNNaNNaNNaN...In the late 1520s Michelangelo made a painting...NaN{'wikidata': [], 'internet_archive': []}NaNNaNhttps://clevelandart.org/art/2015.451https://openaccess-cdn.clevelandart.org/2015.4...https://openaccess-cdn.clevelandart.org/2015.4...https://openaccess-cdn.clevelandart.org/2015.4...2020-11-04 19:07:39.161000
2745542015.447CC0Un Borreau (An Executioner), c. 1848. Auguste ...NaNUn Borreau (An Executioner)NaNNaNNaNc. 1848...NaNNaN{'wikidata': [], 'internet_archive': []}NaNNaNhttps://clevelandart.org/art/2015.447https://openaccess-cdn.clevelandart.org/2015.4...https://openaccess-cdn.clevelandart.org/2015.4...https://openaccess-cdn.clevelandart.org/2015.4...2021-03-27 12:12:37.752000
3745702018.41CC0Profile Portrait of a Man, 18th century. Attri...NaNProfile Portrait of a ManNaNNaNNaN18th century...This portrait bust is a counterproof: the reve...NaN{'wikidata': [], 'internet_archive': ['https:/...NaNNaNhttps://clevelandart.org/art/2018.41https://openaccess-cdn.clevelandart.org/2018.4...https://openaccess-cdn.clevelandart.org/2018.4...https://openaccess-cdn.clevelandart.org/2018.4...2021-06-29 06:35:50.582000
4745722018.42CC0The Temptation of St. Anthony, 19th century. J...NaNThe Temptation of St. AnthonyNaNNaNNaN19th century...Boilly’s scene represents the Temptations of S...NaN{'wikidata': [], 'internet_archive': []}NaNNaNhttps://clevelandart.org/art/2018.42https://openaccess-cdn.clevelandart.org/2018.4...https://openaccess-cdn.clevelandart.org/2018.4...https://openaccess-cdn.clevelandart.org/2018.4...2020-11-04 19:07:40.307000
\n", "

5 rows × 41 columns

\n", "
" ], "text/plain": [ " id accession_number share_license_status \\\n", "0 74539 2015.449 CC0 \n", "1 74540 2015.451 CC0 \n", "2 74554 2015.447 CC0 \n", "3 74570 2018.41 CC0 \n", "4 74572 2018.42 CC0 \n", "\n", " tombstone current_location \\\n", "0 A Miller's Carriage, c. 1895. Albert-Charles L... NaN \n", "1 Leda and the Swan. Adolphe Yvon (French, 1817-... NaN \n", "2 Un Borreau (An Executioner), c. 1848. Auguste ... NaN \n", "3 Profile Portrait of a Man, 18th century. Attri... NaN \n", "4 The Temptation of St. Anthony, 19th century. J... NaN \n", "\n", " title title_in_original_language series \\\n", "0 A Miller's Carriage NaN NaN \n", "1 Leda and the Swan NaN NaN \n", "2 Un Borreau (An Executioner) NaN NaN \n", "3 Profile Portrait of a Man NaN NaN \n", "4 The Temptation of St. Anthony NaN NaN \n", "\n", " series_in_original_language creation_date ... \\\n", "0 NaN c. 1895 ... \n", "1 NaN NaN ... \n", "2 NaN c. 1848 ... \n", "3 NaN 18th century ... \n", "4 NaN 19th century ... \n", "\n", " digital_description wall_description \\\n", "0 NaN NaN \n", "1 In the late 1520s Michelangelo made a painting... NaN \n", "2 NaN NaN \n", "3 This portrait bust is a counterproof: the reve... NaN \n", "4 Boilly’s scene represents the Temptations of S... NaN \n", "\n", " external_resources citations \\\n", "0 {'wikidata': [], 'internet_archive': ['https:/... NaN \n", "1 {'wikidata': [], 'internet_archive': []} NaN \n", "2 {'wikidata': [], 'internet_archive': []} NaN \n", "3 {'wikidata': [], 'internet_archive': ['https:/... NaN \n", "4 {'wikidata': [], 'internet_archive': []} NaN \n", "\n", " catalogue_raisonne url \\\n", "0 NaN https://clevelandart.org/art/2015.449 \n", "1 NaN https://clevelandart.org/art/2015.451 \n", "2 NaN https://clevelandart.org/art/2015.447 \n", "3 NaN https://clevelandart.org/art/2018.41 \n", "4 NaN https://clevelandart.org/art/2018.42 \n", "\n", " image_web \\\n", "0 https://openaccess-cdn.clevelandart.org/2015.4... \n", "1 https://openaccess-cdn.clevelandart.org/2015.4... \n", "2 https://openaccess-cdn.clevelandart.org/2015.4... \n", "3 https://openaccess-cdn.clevelandart.org/2018.4... \n", "4 https://openaccess-cdn.clevelandart.org/2018.4... \n", "\n", " image_print \\\n", "0 https://openaccess-cdn.clevelandart.org/2015.4... \n", "1 https://openaccess-cdn.clevelandart.org/2015.4... \n", "2 https://openaccess-cdn.clevelandart.org/2015.4... \n", "3 https://openaccess-cdn.clevelandart.org/2018.4... \n", "4 https://openaccess-cdn.clevelandart.org/2018.4... \n", "\n", " image_full \\\n", "0 https://openaccess-cdn.clevelandart.org/2015.4... \n", "1 https://openaccess-cdn.clevelandart.org/2015.4... \n", "2 https://openaccess-cdn.clevelandart.org/2015.4... \n", "3 https://openaccess-cdn.clevelandart.org/2018.4... \n", "4 https://openaccess-cdn.clevelandart.org/2018.4... \n", "\n", " updated_at \n", "0 2021-06-29 06:35:50.572000 \n", "1 2020-11-04 19:07:39.161000 \n", "2 2021-03-27 12:12:37.752000 \n", "3 2021-06-29 06:35:50.582000 \n", "4 2020-11-04 19:07:40.307000 \n", "\n", "[5 rows x 41 columns]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "file = './data/cma/input/data.csv'\n", "mpg = pd.read_csv(file,low_memory=False)\n", "mpg.head()" ] }, { "cell_type": "markdown", "id": "cc6507a6", "metadata": {}, "source": [ "### Read Collection Data CSV file into Python Dictionary\n", "\n", "- Remove Byte Order Mark (BOM) from CSV file \n", "- Use `csv.DictReader()` to create an object that operates like a regular reader but maps the information in each row to a dict whose keys are given by the optional fieldnames parameter. \n", "\n" ] }, { "cell_type": "code", "execution_count": 4, "id": "66bad752", "metadata": {}, "outputs": [ { "data": { "text/html": [ "

Example Record in Python Dictionary

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"id\": \"74539\",\n", " \"accession_number\": \"2015.449\",\n", " \"share_license_status\": \"CC0\",\n", " \"tombstone\": \"A Miller's Carriage, c. 1895. Albert-Charles Lebourg (French, 1849-1928). Black and white chalk with stumping ; sheet: 33.2 x 49.7 cm (13 1/16 x 19 9/16 in.). The Cleveland Museum of Art, Bequest of Muriel Butkin 2015.449\",\n", " \"current_location\": \"\",\n", " \"title\": \"A Miller's Carriage\",\n", " \"title_in_original_language\": \"\",\n", " \"series\": \"\",\n", " \"series_in_original_language\": \"\",\n", " \"creation_date\": \"c. 1895\",\n", " \"creation_date_earliest\": \"1890\",\n", " \"creation_date_latest\": \"1900\",\n", " \"creators\": \"Albert-Charles Lebourg (French, 1849-1928), artist\",\n", " \"culture\": \"France, 19th-20th century\",\n", " \"technique\": \"Black and white chalk with stumping \",\n", " \"support_materials\": \"gray laid paper\",\n", " \"department\": \"Drawings\",\n", " \"collection\": \"DR - French\",\n", " \"type\": \"Drawing\",\n", " \"measurements\": \"Sheet: 33.2 x 49.7 cm (13 1/16 x 19 9/16 in.)\",\n", " \"state_of_the_work\": \"\",\n", " \"edition_of_the_work\": \"\",\n", " \"creditline\": \"Bequest of Muriel Butkin\",\n", " \"copyright\": \"\",\n", " \"inscriptions\": \"Verso: upper right in green ink: 80355 / circular estate stamp (Lugt 1664b) \",\n", " \"exhibitions\": \" **LEGACY: Exposition de Lebourg, Mus\\u00e9e de Rouen, 1932\",\n", " \"provenance\": \"\",\n", " \"find_spot\": \"\",\n", " \"related_works\": \"\",\n", " \"former_accession_numbers\": \"[]\",\n", " \"fun_fact\": \"\",\n", " \"digital_description\": \"\",\n", " \"wall_description\": \"\",\n", " \"external_resources\": \"{'wikidata': [], 'internet_archive': ['https://archive.org/details/clevelandart-2015.449-a-miller-s-carriage']}\",\n", " \"citations\": \"\",\n", " \"catalogue_raisonne\": \"\",\n", " \"url\": \"https://clevelandart.org/art/2015.449\",\n", " \"image_web\": \"https://openaccess-cdn.clevelandart.org/2015.449/2015.449_web.jpg\",\n", " \"image_print\": \"https://openaccess-cdn.clevelandart.org/2015.449/2015.449_print.jpg\",\n", " \"image_full\": \"https://openaccess-cdn.clevelandart.org/2015.449/2015.449_full.tif\",\n", " \"updated_at\": \"2021-06-29 06:35:50.572000\"\n", "}\n" ] } ], "source": [ "# remove BOM see - https://stackoverflow.com/questions/8898294/convert-utf-8-with-bom-to-utf-8-with-no-bom-in-python\n", "s = open(file, mode='r', encoding='utf-8-sig').read()\n", "open(file, mode='w', encoding='utf-8').write(s)\n", "\n", "# open file and read into Python dictionary\n", "allObjects = csv.DictReader(open(file, mode='r',encoding='utf-8'))\n", "\n", "display(HTML(\"

Example Record in Python Dictionary

\"))\n", "for obj in allObjects:\n", " print(json.dumps(obj,indent=2))\n", " break " ] }, { "cell_type": "markdown", "id": "cd9db577", "metadata": {}, "source": [ "#### Further Reading \n", "\n", "- Python CSV https://docs.python.org/3/library/csv.html\n", "- Byte Order Mark https://en.wikipedia.org/wiki/Byte_order_mark" ] }, { "cell_type": "markdown", "id": "db2ff2f8", "metadata": {}, "source": [ "### Create field mapping" ] }, { "cell_type": "code", "execution_count": 5, "id": "f137b0c6", "metadata": {}, "outputs": [], "source": [ "\n", "\n", "\n", "mapp = {\n", " \"id\":\"id\",\n", " \"accession_number\":\"accession_number\",\n", " \"accession_date\": \"\",\n", " \"classification\" : \"type\",\n", " \"title\": \"title\",\n", " \"alt_title\": \"title_in_original_language\",\n", " \"notes\": \"tombstone\",\n", " \"date_created\":\"creation_date\",\n", " \"date_created_earliest\": \"creation_date_earliest\",\n", " \"date_created_latest\": \"creation_date_latest\",\n", " \"created_period\":\"culture\",\n", " \"created_dynasty\":\"\",\n", " \"created_inscriptions\":\"inscriptions\",\n", " \"created_notes\": \"fun_fact\",\n", " \"creator\":\"creators\",\n", " \"physical_medium\": \"Medium\",\n", " \"physical_style\": \"\",\n", " \"physical_technique\": \"technique\",\n", " \"physical_description\": \"\",\n", " \"physical_dimensions\": \"measurements\",\n", " \"created_provenance\": \"provenance\" ,\n", " \"credit_line\": \"creditline\",\n", " \"collection\" : \"department\",\n", " \"current_status\" : \"current_location\",\n", " \"current_location\": \"current_location\",\n", " \"homepage\": \"url\"\n", " \n", "}\n", "\n" ] }, { "cell_type": "markdown", "id": "5225bdbd", "metadata": {}, "source": [ "### Create object property dictionary" ] }, { "cell_type": "code", "execution_count": 6, "id": "01ef203c", "metadata": {}, "outputs": [], "source": [ "def createObjProp(obj,mapp):\n", " objProp = {}\n", " csv_keys = list(obj.keys())\n", " for key in csv_keys:\n", " for prop in mapp:\n", " if key == mapp[prop]:\n", " if prop == \"creator\":\n", " objProp[prop] = {\"name\": obj[key]}\n", " else:\n", " objProp[prop] = obj[key]\n", " \n", " objProp[\"current_owner\"] = {\"name\":\"Cleveland Museum of Art\",\n", " \"location\":\"Cleveland,Ohio\",\n", " \"type\": \"http://vocab.getty.edu/aat/300312281\" ,\n", " \"type_label\": \"\"}\n", " return objProp\n", "\n", "\n", "# baseURI for JSON-LD document\n", "baseURI = \"https://clevelandart.org/art/\"\n", "\n", "\n", "for index,obj in enumerate(allObjects):\n", " if index >= 5:\n", " break\n", " objProp = createObjProp(obj,mapp)\n", " id = obj[mapp.get(\"id\")]\n", " object_uri = baseURI + id\n", " \n", " objLA = None\n", " objLA = la.createObjDesc(objProp,la.objTypes,object_uri)\n", " # write to file \n", " text_file = open(\"./data/cma/output/json/all/\" + id + \".json\", \"wt\")\n", " n = text_file.write(factory.toString(objLA, compact=False))\n", " text_file.close()" ] }, { "cell_type": "code", "execution_count": 7, "id": "27b2578d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "

Data Visualisation

" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import display,HTML,Javascript\n", "HTML('

Data Visualisation

')" ] }, { "cell_type": "code", "execution_count": 8, "id": "d3c03776", "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "\n", "require.config({paths: {\n", " d3: \"http://d3js.org/d3.v3.min\"\n", "}});\n", "\n", "function visjsonld(file, selector){\n", " \n", " require([\"d3\"], function(d3) {\n", " \n", " d3.json(file, (err, jsonld) => {\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:#446a7f')\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 ? 'navy' : '#78BE21';\n", " })\n", " .style('fill', function(d) {\n", " if (d.isIdNode) {\n", " return d._children ? 'white' : 'white';\n", " } else {\n", " return d._children ? 'white' : '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", " \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 ? '#78BE21' : '#78BE21';\n", " })\n", " .style('fill', function(d) {\n", " if (d.isIdNode) {\n", " return d._children ? 'navy' : '#78BE21';\n", " } else {\n", " return d._children ? 'navy' : '#78BE21';\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', 'white');\n", " nodeUpdate.select('text').style('font-size', '12px');\n", " \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", "\n", "\n", "\n", "})}\n", "var file = './data/cma/output/json/all/74576.json';var selector = '#example';visjsonld(file, selector); " ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.core.display import Javascript\n", "\n", "code2 = \"var file = './data/cma/output/json/all/\" + id + \".json';\"\\\n", " \"var selector = '#example';\" \\\n", " \"visjsonld(file, selector); \" \n", "\n", "with open('src/js/visld.js', 'r') as _jscript:\n", " code = _jscript.read() + code2\n", "\n", "Javascript(code)\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 9, "id": "6cf3e2db", "metadata": {}, "outputs": [ { "data": { "text/html": [ "

File list

Click on a link to view created Linked Art JSON-LD file

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "74572.json" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "74554.json" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "0.json" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "74540.json" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "74576.json" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "74570.json" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from IPython.core.display import Javascript, HTML\n", "\n", "\n", "def fn(fpath): # 1.Get file names from directory\n", " file_list=os.listdir(r\"\" + fpath)\n", " cnt =1 \n", " for file in file_list:\n", " cnt = cnt+1\n", " \n", " display(HTML(\"\" + file + \"\"))\n", "\n", "\n", "display(HTML(\"

File list

Click on a link to view created Linked Art JSON-LD file

\"))\n", " \n", "fn(\"./data/cma/output/json/all/\")\n", "\n", "\n", " " ] }, { "cell_type": "code", "execution_count": null, "id": "66976acc-8d11-493d-bec0-439069a7ecd7", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "0867f3a2-2edf-478f-9ea9-e094a5100464", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "finalized": { "timestamp": 1650627649583, "trusted": true }, "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" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }