From 6fe346c9a680b0361c0679fffc227c214641e8a0 Mon Sep 17 00:00:00 2001 From: Darren Zal Date: Mon, 13 Feb 2023 13:43:00 -0800 Subject: [PATCH] add search bar --- Terminus/__pycache__/schema.cpython-39.pyc | Bin 4678 -> 4515 bytes Terminus/config.json | 2 +- Terminus/insert_data.py | 125 +++++-- Terminus/schema.py | 3 + package-lock.json | 100 ++++++ package.json | 1 + search/import.py | 33 ++ search/search.py | 7 + src/components/explore/Explore copy 2.svelte | 334 +++++++++++++++++++ src/components/explore/Explore.svelte | 288 +++++++++++++--- src/components/explore/cytoscape.svelte | 96 ++++++ src/components/explore/cytoscape.ts | 164 +++++++++ 12 files changed, 1066 insertions(+), 87 deletions(-) create mode 100644 search/import.py create mode 100644 search/search.py create mode 100644 src/components/explore/Explore copy 2.svelte create mode 100644 src/components/explore/cytoscape.svelte create mode 100644 src/components/explore/cytoscape.ts diff --git a/Terminus/__pycache__/schema.cpython-39.pyc b/Terminus/__pycache__/schema.cpython-39.pyc index d0c91d1290a5c766f50d7082b049684fcfef2c4e..38489418fff6fe948c358dc1283d230462e5ed63 100644 GIT binary patch delta 177 zcmX@6vRIink(ZZ?0SFGtyhxrnkyqAi3Xqe+kiwY55Cx){au{=&qL^}-qnLA9qF5L~ zV$30-Ib3WAE8dwBbp8D~tE7Hs9v6u8BbRh*wUd4*uBBqK*KX*bLhJjU7;LVczNx0E`Du&dGtQ4d+1Kf^m z?nDl+L={kG4s*E|dAu4`xgYsuHaS1LTkcs6c=HyVP{T+I9S@`+v6PpnFBNKE5iL1E zJ%g1QWP**BN^&UFHF~y>|#^O;hFF$_&T5&)v|8{0BILtp5UI57Q z(?tTjhl1+O=`GyK=SzE2XGa_A6iLa A>i_@% diff --git a/Terminus/config.json b/Terminus/config.json index 74ed07c..8b13aba 100644 --- a/Terminus/config.json +++ b/Terminus/config.json @@ -1,5 +1,5 @@ { - "database": "playground3", + "database": "play", "endpoint": "https://cloud.terminusdb.com/Myseelia/", "team": "Myseelia", "use JWT token": true diff --git a/Terminus/insert_data.py b/Terminus/insert_data.py index 59e187a..47e05fa 100644 --- a/Terminus/insert_data.py +++ b/Terminus/insert_data.py @@ -6,15 +6,23 @@ from datetime import datetime import pytz import re import emoji +import json +import meilisearch +import ast +import hashlib + # we keep all the information in dictionaries with Employee id as keys orgs = {} +orgsjson = [] client = WOQLClient("https://cloud.terminusdb.com/Myseelia/") -client.connect(db="playground3", team="Myseelia", use_token=True) +client.connect(db="play", team="Myseelia", use_token=True) -import re +client1 = meilisearch.Client( + 'https://ms-9ea4a96f02a8-1969.sfo.meilisearch.io', '117c691a34b21a6651798479ebffd181eb276958') +index = client1.index('orgs') def get_emoji_regexp(): # Sort emoji by length to make sure multi-character emojis are @@ -23,9 +31,44 @@ def get_emoji_regexp(): pattern = u'(' + u'|'.join(re.escape(u) for u in emojis) + u')' return re.compile(pattern) + def remove_emojis(string): return get_emoji_regexp().sub(r'', string) +def hash_string(string): + sha256 = hashlib.sha256() + sha256.update(string.encode('utf-8')) + return sha256.hexdigest() + +def to_json(obj): + obj_dict = obj.__dict__ + if obj_dict['blockchainecosystem']: + print(obj_dict['blockchainecosystem']) + obj_dict['blockchainecosystem'] = [ + bc.name for bc in obj_dict['blockchainecosystem']] + else: + obj_dict['web3'] = None + if obj_dict['impactarea']: + print(obj_dict['impactarea']) + obj_dict['impactarea'] = [ia.name for ia in obj_dict['impactarea']] + else: + obj_dict['web3'] = None + if obj_dict['topic']: + print(obj_dict['topic']) + obj_dict['topic'] = [t.name for t in obj_dict['topic']] + else: + obj_dict['web3'] = None + if obj_dict['web3']: + print(obj_dict['web3']) + obj_dict['web3'] = [w.name for w in obj_dict['web3']] + else: + obj_dict['web3'] = None + print(obj_dict['datecreated']) + obj_dict['datecreated'] = obj_dict['datecreated'].isoformat() + print("here") + print("here" + json.dumps(obj_dict)) + return json.dumps(obj_dict) + with open("Organizations.csv") as file: csv_file = csv.reader(file) @@ -47,7 +90,7 @@ with open("Organizations.csv") as file: value = value.strip().strip('"') if value == "Social justice": impact_area_set.add(ImpactArea.SocialJustice) - elif value in ("Food & Agriculture","Food & Ag."): + elif value in ("Food & Agriculture", "Food & Ag."): impact_area_set.add(ImpactArea.FoodAg) elif value == "Invest": impact_area_set.add(ImpactArea.Politicsactivism) @@ -55,7 +98,8 @@ with open("Organizations.csv") as file: impact_area_set.add(ImpactArea.Investing) elif value == "Innovate": impact_area_set.add(ImpactArea.Innovation) - else: impact_area_set.add(ImpactArea[value]) + else: + impact_area_set.add(ImpactArea[value]) blockchainEcosystem = row[1].strip("{}").split(",") blockchainEcosystem_set = set() for value in blockchainEcosystem: @@ -70,11 +114,11 @@ with open("Organizations.csv") as file: elif blockchain == "Hyperledger Fabric": blockchain = Blockchain.HyperledgerFabric elif blockchain == "Zero Carbon": - blockchain = Blockchain.ZeroCarbon + blockchain = Blockchain.ZeroCarbon elif blockchain == "IXO": - blockchain = Blockchain.ixo - elif blockchain in ("Not found","Not sure / still deciding"): - blockchain = Blockchain.Other + blockchain = Blockchain.ixo + elif blockchain in ("Not found", "Not sure / still deciding"): + blockchain = Blockchain.Other elif blockchain == "Not applicable": break else: @@ -85,8 +129,8 @@ with open("Organizations.csv") as file: for value in re.split(",(?![^(]*\))", web3): if value: web3 = value.strip().strip('"') - #someone put "Blockchain (L1,DAO" which will match to "Blockchain (L1" since we strip the '"' - if web3 in ("Blockchain (L1, L2)","Blockchain (L1,L2)","Blockchain (L1"): + # someone put "Blockchain (L1,DAO" which will match to "Blockchain (L1" since we strip the '"' + if web3 in ("Blockchain (L1, L2)", "Blockchain (L1,L2)", "Blockchain (L1"): web3 = Web3.Blockchain else: web3 = Web3[web3] @@ -114,7 +158,8 @@ with open("Organizations.csv") as file: topic = Topic.FoodForests elif topic == "Eco-Living": topic = Topic.EcoLiving - else: topic = Topic[topic] + else: + topic = Topic[topic] topic_set.add(topic) date_string = row[2] utc_date = datetime.min @@ -132,25 +177,43 @@ with open("Organizations.csv") as file: if upvotesstr.isdigit(): upvotesint = int(upvotesstr) - orgs[counter] = Organization( - assignee = row[0] if row[0] not in [None, ''] else None, - blockchainecosystem = blockchainEcosystem_set if len(blockchainEcosystem_set) > 0 else None, - description = row[3] if row[3] not in [None, ''] else None, - logo = row[5] if row[5] not in [None, ''] else None, - #name is the only mandatory field, so default it to "" if blank - name = row[6] if row[6] not in [None, ''] else "", - preJan20thUpvotes = preJan20thUpvotesint if preJan20thUpvotesint not in [0] else None, - reviewed = row[8] if row[3] not in [None, ''] else None, - submittedbyemail = row[9] if row[9] not in [None, ''] else None, - submittedbyname = row[10] if row[10] not in [None, ''] else None, - submittedbyowner = row[11] if row[11] not in [None, ''] else None, - subscribed = row[12] if row[12] not in [None, ''] else None, - topic = topic_set if len(topic_set) > 0 else None, - upvotes = upvotesint if upvotesint not in [0] else None, - web3 = web3_set if len(web3_set) > 0 else None, - impactarea = impact_area_set if len(impact_area_set) > 0 else None, - datecreated = utc_date if impact_area_set not in [datetime.min] else None, + org = Organization( + assignee=row[0] if row[0] not in [None, ''] else None, + blockchainecosystem=blockchainEcosystem_set if len( + blockchainEcosystem_set) > 0 else None, + description=row[3] if row[3] not in [None, ''] else None, + logo=row[5] if row[5] not in [None, ''] else None, + # name is the only mandatory field, so default it to "" if blank + name=row[6] if row[6] not in [None, ''] else "", + preJan20thUpvotes=preJan20thUpvotesint if preJan20thUpvotesint not in [ + 0] else None, + reviewed=row[8] if row[3] not in [None, ''] else None, + submittedbyemail=row[9] if row[9] not in [None, ''] else None, + submittedbyname=row[10] if row[10] not in [None, ''] else None, + submittedbyowner=row[11] if row[11] not in [ + None, ''] else None, + subscribed=row[12] if row[12] not in [None, ''] else None, + topic=topic_set if len(topic_set) > 0 else None, + upvotes=upvotesint if upvotesint not in [0] else None, + web3=web3_set if len(web3_set) > 0 else None, + impactarea=impact_area_set if len( + impact_area_set) > 0 else None, + datecreated=utc_date if impact_area_set not in [ + datetime.min] else None, ) - counter += 1 - client.insert_document(list(orgs.values()), commit_msg="Adding orgs") + orgs[counter] = org + # print(to_json(org)) + # orgsjson.append(to_json(org)) + counter += 1 + inserted = client.insert_document( + list(orgs.values()), commit_msg="Adding orgs") + documents = [] + for id in inserted: + document = client.get_document(id) + real_id = document['@id'] + num_id = real_id.split("/")[-1] + document = {k: json.dumps(v) for k, v in document.items() if k != '@id'} + document.update({'id': num_id}) + documents.append(document) + index.add_documents(documents) diff --git a/Terminus/schema.py b/Terminus/schema.py index 417e475..4a62e8a 100644 --- a/Terminus/schema.py +++ b/Terminus/schema.py @@ -1,3 +1,4 @@ +import json #### # This is the script for storing the schema of your TerminusDB # database for your project. @@ -56,6 +57,7 @@ class Blockchain(EnumTemplate): ZeroCarbon = () Topl = () HBAR = () + class Organization(DocumentTemplate): """ @@ -208,3 +210,4 @@ class Topic(EnumTemplate): Other = () IoT = () EcoLiving = () + diff --git a/package-lock.json b/package-lock.json index 76ff3d5..79dba98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "clipboard-copy": "^4.0.1", "cytoscape": "^3.23.0", + "meilisearch": "^0.31.1", "qrcode-svg": "^1.1.0", "uint8arrays": "^3.1.0", "webnative": "^0.34.1" @@ -3142,6 +3143,33 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", @@ -6375,6 +6403,14 @@ "node": ">=8" } }, + "node_modules/meilisearch": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/meilisearch/-/meilisearch-0.31.1.tgz", + "integrity": "sha512-ajMieU0e25lLkT+05J0snX0Ycow1UofxIy5sag03flERUbjXq8ouVwkrJkW27JsKftIeDeffRRRr89LasU9+0w==", + "dependencies": { + "cross-fetch": "^3.1.5" + } + }, "node_modules/mem": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/mem/-/mem-9.0.2.tgz", @@ -8502,6 +8538,11 @@ "node": ">=6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/ts-node": { "version": "10.9.1", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", @@ -8799,6 +8840,11 @@ "node": ">= 8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, "node_modules/webnative": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/webnative/-/webnative-0.34.1.tgz", @@ -8839,6 +8885,15 @@ "node": ">=6" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", @@ -11292,6 +11347,24 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "requires": { + "node-fetch": "2.6.7" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + } + } + }, "cross-spawn": { "version": "7.0.3", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", @@ -13610,6 +13683,14 @@ "blueimp-md5": "^2.10.0" } }, + "meilisearch": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/meilisearch/-/meilisearch-0.31.1.tgz", + "integrity": "sha512-ajMieU0e25lLkT+05J0snX0Ycow1UofxIy5sag03flERUbjXq8ouVwkrJkW27JsKftIeDeffRRRr89LasU9+0w==", + "requires": { + "cross-fetch": "^3.1.5" + } + }, "mem": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/mem/-/mem-9.0.2.tgz", @@ -15043,6 +15124,11 @@ "integrity": "sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==", "dev": true }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "ts-node": { "version": "10.9.1", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", @@ -15242,6 +15328,11 @@ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, "webnative": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/webnative/-/webnative-0.34.1.tgz", @@ -15276,6 +15367,15 @@ "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", "dev": true }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "2.0.2", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", diff --git a/package.json b/package.json index a652036..8ca496a 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "dependencies": { "clipboard-copy": "^4.0.1", "cytoscape": "^3.23.0", + "meilisearch": "^0.31.1", "qrcode-svg": "^1.1.0", "uint8arrays": "^3.1.0", "webnative": "^0.34.1" diff --git a/search/import.py b/search/import.py new file mode 100644 index 0000000..ce9155f --- /dev/null +++ b/search/import.py @@ -0,0 +1,33 @@ +import meilisearch + +client = meilisearch.Client('https://ms-9ea4a96f02a8-1969.sfo.meilisearch.io', '117c691a34b21a6651798479ebffd181eb276958') + +# An index is where the documents are stored. +index = client.index('movies') + +documents = [ + { 'id': 1, 'title': 'Carol', 'genres': ['Romance', 'Drama'] }, + { 'id': 2, 'title': 'Wonder Woman', 'genres': ['Action', 'Adventure'] }, + { 'id': 3, 'title': 'Life of Pi', 'genres': ['Adventure', 'Drama'] }, + { 'id': 4, 'title': 'Mad Max: Fury Road', 'genres': ['Adventure', 'Science Fiction'] }, + { 'id': 5, 'title': 'Moana', 'genres': ['Fantasy', 'Action']}, + { 'id': 6, 'title': 'Philadelphia', 'genres': ['Drama'] }, +] + +# If the index 'movies' does not exist, Meilisearch creates it when you first add the documents. +index.add_documents(documents) # => { "uid": 0 }', 'masterKey') + +# An index is where the documents are stored. +index = client.index('movies') + +documents = [ + { 'id': 1, 'title': 'Carol', 'genres': ['Romance', 'Drama'] }, + { 'id': 2, 'title': 'Wonder Woman', 'genres': ['Action', 'Adventure'] }, + { 'id': 3, 'title': 'Life of Pi', 'genres': ['Adventure', 'Drama'] }, + { 'id': 4, 'title': 'Mad Max: Fury Road', 'genres': ['Adventure', 'Science Fiction'] }, + { 'id': 5, 'title': 'Moana', 'genres': ['Fantasy', 'Action']}, + { 'id': 6, 'title': 'Philadelphia', 'genres': ['Drama'] }, +] + +# If the index 'movies' does not exist, Meilisearch creates it when you first add the documents. +index.add_documents(documents) # => { "uid": 0 } \ No newline at end of file diff --git a/search/search.py b/search/search.py new file mode 100644 index 0000000..4963320 --- /dev/null +++ b/search/search.py @@ -0,0 +1,7 @@ +import meilisearch + +client = meilisearch.Client('https://ms-9ea4a96f02a8-1969.sfo.meilisearch.io', '117c691a34b21a6651798479ebffd181eb276958') + +result = index.search('caorl') + +print(result) \ No newline at end of file diff --git a/src/components/explore/Explore copy 2.svelte b/src/components/explore/Explore copy 2.svelte new file mode 100644 index 0000000..d8392c4 --- /dev/null +++ b/src/components/explore/Explore copy 2.svelte @@ -0,0 +1,334 @@ + + +
+ { + if (event.keyCode === 13) { + entered(event) + } + }} + /> +
+
+
+ +
+
+ + diff --git a/src/components/explore/Explore.svelte b/src/components/explore/Explore.svelte index f260a28..8cb7577 100644 --- a/src/components/explore/Explore.svelte +++ b/src/components/explore/Explore.svelte @@ -2,9 +2,11 @@ import cytoscape from 'cytoscape' import { onMount } from 'svelte' import { bubble } from 'svelte/internal' + import TerminusClient from '@terminusdb/terminusdb-client' + import { MeiliSearch } from 'meilisearch' + import { generateKnowledgeGraph } from './cytoscape.ts' let cy - let cyDiv interface INodeData { id: string @@ -24,14 +26,12 @@ interface IEdge { data: IEdgeData } - - - import json_graph from './knowledge_graph.json'; + import json_graph from './knowledge_graph.json' - let knowledgeGraphJson: any = json_graph; + let knowledgeGraphJson: any = json_graph -// knowledgeGraphJson = await response.json() + // knowledgeGraphJson = await response.json() // } else { // alert(`HTTP-Error: ${response.status}`) // } @@ -41,7 +41,6 @@ let edges: IEdge[] = [] onMount(async () => { - //await fetchData(); nodes = knowledgeGraphJson.entities.map((entity: any) => ({ data: { id: entity.id, label: entity.label } })) @@ -57,7 +56,7 @@ }) ) - let cy = cytoscape({ + cy = cytoscape({ container: document.getElementById('cy'), elements: { nodes, @@ -70,26 +69,36 @@ 'text-valign': 'center', 'text-halign': 'center', 'text-wrap': 'wrap', - "text-max-width": function(ele){ return Math.max(1, Math.ceil(ele.degree()/2)) * 30; }, - "font-size": function(ele){ return Math.max(1, Math.ceil(ele.degree()/2)) * 6; }, - 'background-color': "#75f6df", - 'border-color': "#223152", - 'border-width': function(ele){ return Math.max(1, Math.ceil(ele.degree()/2)); }, + 'text-max-width': function (ele) { + return Math.max(1, Math.ceil(ele.degree() / 2)) * 30 + }, + 'font-size': function (ele) { + return Math.max(1, Math.ceil(ele.degree() / 2)) * 6 + }, + 'background-color': '#75f6df', + 'border-color': '#223152', + 'border-width': function (ele) { + return Math.max(1, Math.ceil(ele.degree() / 2)) + }, label: 'data(label)', - width: function(ele){ return Math.max(1, Math.ceil(ele.degree()/2)) * 40; }, - height: function(ele){ return Math.max(1, Math.ceil(ele.degree()/2)) * 40; } + width: function (ele) { + return Math.max(1, Math.ceil(ele.degree() / 2)) * 40 + }, + height: function (ele) { + return Math.max(1, Math.ceil(ele.degree() / 2)) * 40 + } } }, { selector: 'edge', style: { - "font-size": 20, + 'font-size': 20, width: 5, - 'line-color': "#223152", - 'target-arrow-color': "#223152", + 'line-color': '#223152', + 'target-arrow-color': '#223152', 'target-arrow-shape': 'triangle', 'curve-style': 'bezier', - "text-rotation": "autorotate", + 'text-rotation': 'autorotate', 'text-offset': { x: 20, y: -20 }, 'text-background-opacity': 1, 'text-background-color': '#fafafa', @@ -104,50 +113,65 @@ } }) - let toggle = true; - + cy.nodes().forEach(function (node) { + node.data({ + degree: node.connectedEdges().length + }) + }) + + var nodes = cy.nodes() + nodes = nodes.sort(function (a, b) { + return b.data('degree') - a.data('degree') + }) + + var top100 = nodes.slice(0, 1000) + + //console.log(top100) + + cy.nodes().forEach(function (node) { + if (!top100.includes(node)) { + node.hide() + } + }) + + let toggle = true // cy.off('tap', 'node', event => { // const node = event.target; // const nodeId = node.data('id'); // alert('unDisplay info for ' + nodeId); // }); - - - + cy.on('tap', 'node', function (evt) { + var node = evt.target + var connectedEdges = node.connectedEdges() + var connectedNodes = node.neighborhood().nodes() + var allElements = cy.elements() + var allNodes = cy.nodes() + var allEdges = cy.edges() - cy.on('tap', 'node', function(evt){ - var node = evt.target; - var connectedEdges = node.connectedEdges(); - var connectedNodes = node.neighborhood().nodes(); - var allElements = cy.elements(); - var allNodes = cy.nodes(); - var allEdges = cy.edges(); - - if (node.style("display") == "element") { - // hide all nodes and edges except the selected node and its neighbors - allNodes.style("display", "none"); - allEdges.style("display", "none"); - connectedNodes.style("display", "element"); - node.style("display", "element"); - connectedEdges.style("display", "element"); - } else { - // show all nodes and edges - allNodes.style("display", "element"); - allEdges.style("display", "element"); - } -}); - -// Reset the state when clicking away from the node -cy.on('tap', function(e){ - if (e.target === cy) { - cy.nodes().style('display', 'element'); - cy.edges().style('display', 'element'); - cy.nodes().data('highlighted', false); - } -}); + if (node.style('display') == 'element') { + // hide all nodes and edges except the selected node and its neighbors + allNodes.style('display', 'none') + allEdges.style('display', 'none') + connectedNodes.style('display', 'element') + node.style('display', 'element') + connectedEdges.style('display', 'element') + } else { + // show all nodes and edges + allNodes.style('display', 'element') + allEdges.style('display', 'element') + } + }) + // Reset the state when clicking away from the node + cy.on('tap', function (e) { + if (e.target === cy) { + cy.nodes().style('display', 'element') + cy.edges().style('display', 'element') + cy.nodes().data('highlighted', false) + } + }) cy.on('tap', 'edge', event => { const edge = event.target @@ -163,15 +187,169 @@ cy.on('tap', function(e){ // name: 'cola' // }).run(); }) + + var searchTerm = '' + function updateSearchTerm(e) { + searchTerm = e.target.value + // Perform search in real timebased on searchTerm here + } + + async function entered(e) { + const searchclient = new MeiliSearch({ + host: 'https://ms-9ea4a96f02a8-1969.sfo.meilisearch.io', + apiKey: '117c691a34b21a6651798479ebffd181eb276958' + }) + const index = searchclient.index('orgs') + // this will search both keys and values + // const search = await index.search(e.target.value.toString(), { q: '*' }); + // const searchResult = await index.search('orgs', { + // attributesToRetrieve: ['id'] + // }) + const searchResult = await index.search(e.target.value.toString(), { + attributesToRetrieve: ['id'] + }) + + // need to turn the search results into an array of ids which can be used to query the knowledge graph + const resultsgraph = await generateKnowledgeGraph(searchResult.hits).then( + resultsgraph => { + const allNodes = resultsgraph.entities.map((entity: any) => ({ + data: { id: entity.id, label: entity.label } + })) + + const allEdges = resultsgraph.relations.map( + (relation: any, index: string) => ({ + data: { + id: index, + source: relation.source, + target: relation.target, + label: relation.type + } + }) + ) + cy.remove(cy.elements()) + cy.add(allNodes) + cy.add(allEdges) + cy.layout({ + name: 'cose', + // other layout options here +}).run(); + } + ) + // var node = cy.nodes().filter(function (ele) { + // return ele.data('id') == "Organization/" + searchResult.hits[0].id + // }) + // console.log(node); + // var connectedEdges = node.connectedEdges() + // var connectedNodes = node.neighborhood().nodes() + // var allElements = cy.elements() + // var allNodes = cy.nodes() + // var allEdges = cy.edges() + + // if (node.style('display') == 'element') { + // console.log("a"); + // // hide all nodes and edges except the selected node and its neighbors + // allNodes.style('display', 'none') + // allEdges.style('display', 'none') + // connectedNodes.style('display', 'element') + // node.style('display', 'element') + // connectedEdges.style('display', 'element') + // } else { + // console.log("b"); + // // show all nodes and edges + // allNodes.style('display', 'element') + // allEdges.style('display', 'element') + // } + + // Perform search in real time based on searchTerm here + const client = new TerminusClient.WOQLClient( + 'https://cloud.terminusdb.com/Myseelia/', + { + user: 'zaldarren@gmail.com', + organization: 'Myseelia', + db: 'playground3', + token: + 'dGVybWludXNkYjovLy9kYXRhL2tleXNfYXBpLzJkMDU4N2IwYjgzMzhmODdjMjc0ZDdiNmM1MzgwNjFmYTYyMmZkOTcyZTc3NjI1NzIyYjY3MTllYTE3NmQxYjE=_bd6f9c37d87abcaf0c16b7a68335b31010c8dd04aac0b07bf0f31676af131888666200aac080e72cdc746197334eac4f52d821c90652b5611784878afabe1267535cbd896a00a396' + } + ) + try { + await client.connect() + //console.log(schema); + // console.log("result"); + + // const result = await client.getDocument({as_list:true,type:"Person",query: { userName: "tester" }}) + // console.log(result); + } catch (err) { + console.error('this is it' + err.message) + } + + // let v = WOQL.vars('person_id', 'impactarea', '@schema:checked'); + // const WOQL = TerminusClient.WOQL + // const query = WOQL.triple( + // 'v:OrganizationID', + // 'name', + // WOQL.string('Sustainable Impact Token') + // ) + + // const query3 = WOQL.and( + // WOQL.triple('v:NodeID', 'property_name', WOQL.like(`%${keyword}%`)), + // WOQL.triple('v:NodeID', 'property_name', 'v:Value') + // ) + + // const result = await client.getDocument({ + // as_list: true, + // type: 'Organization', + // query: { name: 'Sustainable Impact Token' } + // }) + // console.log('result ', result) + // const results = await client.query(query) + // console.log('Query Documents using WOQL: ', results.bindings) + } +
+ { + if (event.keyCode === 13) { + entered(event) + } + }} + /> +
-
+