Visualizing the Graph Relationships - DDMAL/linkedmusic-datalake GitHub Wiki
Having a visual of the relationships between entities within a graph is useful for both debugging graph structure and generating/debugging SPARQL queries. Once a graph structure is finalized, the visual will not need to be recreated and thus automation of this process would be overkill.
Visualizing a graph first requires the general relationships between entities. In the Virtuoso SPARQL endpoint, write the following SPARQL command
CONSTRUCT {
?stype ?p ?otype .
}
WHERE {
VALUES ?g { <<Graph URI>> }
{
SELECT DISTINCT ?stype ?p ?otype
WHERE {
{
GRAPH ?g {
?s ?p ?o .
?s rdf:type ?stype .
?o rdf:type ?otype .
}
} UNION {
GRAPH ?g {
?s rdfs:label ?o .
?s rdf:type ?stype .
BIND(rdfs:label AS ?p)
BIND("label" AS ?otype)
}
} UNION {
GRAPH ?g {
?s skos:altLabel ?o .
?s rdf:type ?stype .
BIND(skos:altLabel AS ?p)
BIND("alt label" AS ?otype)
}
} UNION {
GRAPH ?g {
?s ?p ?o .
?s rdf:type ?stype .
FILTER(isLiteral(?o) || STRSTARTS(STR(?o), STR(wd:)))
}
{
SELECT DISTINCT ?p ?otype
WHERE {
SERVICE <https://query.wikidata.org/sparql> {
?prop wikibase:directClaim ?p .
?prop rdfs:label ?otype .
FILTER(LANG(?otype) = "en")
}
}
}
}
}
}
}
e.g., for DIAMM:
CONSTRUCT {
?stype ?p ?otype .
}
WHERE {
VALUES ?g { diamm: }
{
SELECT DISTINCT ?stype ?p ?otype
WHERE {
{
GRAPH ?g {
?s ?p ?o .
?s rdf:type ?stype .
?o rdf:type ?otype .
}
} UNION {
GRAPH ?g {
?s rdfs:label ?o .
?s rdf:type ?stype .
BIND(rdfs:label AS ?p)
BIND("label" AS ?otype)
}
} UNION {
GRAPH ?g {
?s skos:altLabel ?o .
?s rdf:type ?stype .
BIND(skos:altLabel AS ?p)
BIND("alt label" AS ?otype)
}
} UNION {
GRAPH ?g {
?s ?p ?o .
?s rdf:type ?stype .
FILTER(isLiteral(?o) || STRSTARTS(STR(?o), STR(wd:)))
}
{
SELECT DISTINCT ?p ?otype
WHERE {
SERVICE <https://query.wikidata.org/sparql> {
?prop wikibase:directClaim ?p .
?prop rdfs:label ?otype .
FILTER(LANG(?otype) = "en")
}
}
}
}
}
}
}
Download the results as turtle (this option will only appear once you have written a query containing "CONSTRUCT").
Open the TTL from Step 1 into the text editor of your choice.
Replace all instances of @en
with nothing.
Copy the output from Step 2 and paste it into RDF Grapher.
Make sure the "From format:" is set to "Turtle" and the "To format:" is set to "SVG". If the dataset is large, it may be prudent to check the "Send form as HTTP POST (needed for large RDF data):" option.
Click "Visualize" to generate the graph visual.
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX wd: <http://www.wikidata.org/entity/>
CONSTRUCT {
?property a rdf:Property ;
rdfs:domain ?domain ;
rdfs:range ?range .
?class a rdfs:Class .
wd:Entity a rdfs:Class .
}
WHERE {
VALUES ?g {<<GRAPH URI>>}
{
GRAPH ?g {
?instance rdf:type ?class .
}
}
UNION
{
GRAPH ?g {
?subject ?property ?object .
?subject rdf:type ?domain .
OPTIONAL {
?object rdf:type ?oType .
}
}
# Determine range
BIND(
IF(
isIRI(?object),
IF(
STRSTARTS(STR(?object), "http://www.wikidata.org/entity/"),
wd:Entity,
COALESCE(?oType, owl:Thing)
),
IF(
isLiteral(?object),
COALESCE(datatype(?object), rdfs:Literal),
UNDEF
)
) AS ?range
)
}
}
This SPARQL query should theoretically be quicker at generating the ontology, but it has not been tested
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX wd: <http://www.wikidata.org/entity/>
CONSTRUCT {
?property a rdf:Property ;
rdfs:domain ?domain ;
rdfs:range ?range .
?class a rdfs:Class .
wd:Entity a rdfs:Class .
}
WHERE {
GRAPH <GRAPH_URI> {
{
SELECT DISTINCT ?class WHERE {
?instance rdf:type ?class .
}
}
UNION
{
SELECT DISTINCT ?domain ?property ?range WHERE {
?subject ?property ?object .
?subject rdf:type ?domain .
OPTIONAL {
?object rdf:type ?oType .
}
# Determine range
BIND(
IF(
isIRI(?object),
IF(
STRSTARTS(STR(?object), "http://www.wikidata.org/entity/"),
wd:Entity,
COALESCE(?oType, owl:Thing)
),
IF(
isLiteral(?object),
COALESCE(datatype(?object), rdfs:Literal),
UNDEF
)
) AS ?range
)
}
}
}
}