Create a gist now

Instantly share code, notes, and snippets.

Clipboard.js for RDF triples presentation

Navigating a URI of a Linked Data resource should return a human-readable response composed by the RDF triples related to the resource. Consulting these the web pages, users often need mechanisms for coping URIs of subjects, predicates and objects. Clipboard.js is used in this example in order to provide a URI-copy interaction solution.

width = 960
height = 500
margin = 20
cb = new Clipboard('.fa-clipboard')
prefixes =
'http://dbpedia.org/resource': 'dbr:'
'http://www.w3.org/2000/01/rdf-schema': 'rdfs:'
'http://dbpedia.org/ontology': 'dbo:'
'http://www.w3.org/2002/07/owl': 'owl:'
data = [
{subject: 'http://dbpedia.org/resource/Pisa', predicate: 'http://www.w3.org/2000/01/rdf-schema/label', object: 'Pisa'},
{subject: 'http://dbpedia.org/resource/Pisa', predicate: 'http://dbpedia.org/ontology/populationTotal', object: '89373', object_datatype: 'http://www.w3.org/2001/XMLSchema#date'},
{subject: 'http://dbpedia.org/resource/Pisa', predicate: 'http://dbpedia.org/ontology/country', object: 'http://dbpedia.org/resource/Italy'},
{subject: 'http://dbpedia.org/resource/Pisa', predicate: 'http://www.w3.org/2002/07/owl/sameAs', object: 'http://sws.geonames.org/6542122/'}
]
container = d3.select 'table'
.style
width: "#{width}px"
height: "#{height}px"
'margin-left': "#{margin}px"
triples = container.selectAll '.triple'
.data data
triples_enter = triples.enter().append 'tr'
.attr
class: 'triple'
# Subjects
subjects = triples.append 'td'
.append 'span'
.attr
class: 'subject'
.on 'mouseover', (d) ->
d3.select(this).select('.clipboard').style('color', '#000')
.on 'mouseout', (d) ->
d3.select(this).select('.clipboard').style('color', '#f2f2f2')
subjects.append 'span'
.attr
class: 'prefix'
title: (d) -> d.subject.split('/').slice(0,-1).join('/')
.text (d) -> prefixes[d.subject.split('/').slice(0,-1).join('/')]
subjects.append 'span'
.text (d) -> d.subject.split('/').slice(-1)[0]
subjects_clip = subjects.append 'span'
.attr
class: 'clipboard'
subjects_clip.append 'i'
.attr
class: 'fa fa-clipboard'
'data-clipboard-text': (d) -> d.subject
title: 'Copy subject to clipboard.'
.on 'click', (d) ->
d3.select(this.parentNode).style('color', 'gray')
# Predicates
predicates = triples.append 'td'
.append 'span'
.attr
class: 'predicate'
.on 'mouseover', (d) ->
d3.select(this).select('.clipboard').style('color', '#000')
.on 'mouseout', (d) ->
d3.select(this).select('.clipboard').style('color', '#f2f2f2')
predicates.append 'span'
.attr
class: 'prefix'
title: (d) -> d.predicate.split('/').slice(0,-1).join('/')
.text (d) -> prefixes[d.predicate.split('/').slice(0,-1).join('/')]
predicates.append 'span'
.text (d) -> d.predicate.split('/').slice(-1)[0]
predicates_clip = predicates.append 'span'
.attr
class: 'clipboard'
predicates_clip.append 'i'
.attr
class: 'fa fa-clipboard'
'data-clipboard-text': (d) -> d.predicate
title: 'Copy precicate to clipboard.'
.on 'click', (d) ->
d3.select(this.parentNode).style('color', 'gray')
# Objects
objects = triples.append 'td'
.append 'span'
.attr
class: 'object'
.on 'mouseover', (d) ->
d3.select(this).select('.clipboard').style('color', '#000')
.on 'mouseout', (d) ->
d3.select(this).select('.clipboard').style('color', '#f2f2f2')
.html (d) ->
if d.object.indexOf('http') is 0 and prefixes[d.object.split('/').slice(0,-1).join('/')]?
"<span class='prefix'>#{prefixes[d.object.split('/').slice(0,-1).join('/')]}</span><span>#{d.object.split('/').slice(-1)[0]}</span><span class='clipboard'><i class='fa fa-clipboard' data-clipboard-text='#{d.object}'></i></span>"
else if d.object.indexOf('http') is 0 and not prefixes[d.object.split('/').slice(0,-1).join('/')]?
"<<span >#{d.object}</span>><span class='clipboard'><i class='fa fa-clipboard' data-clipboard-text='#{d.object}'></i></span>"
else
"<span class='literal'>#{d.object}</span><span class='clipboard'><i class='fa fa-clipboard' data-clipboard-text='#{d.object}'></i></span>"
objects.selectAll 'i'
.on 'click', (d) ->
d3.select(this.parentNode).style('color', 'gray')
html, body {
margin: 0;
padding: 0;
font-family: 'Noto serif', serif;
}
body {
background: #f2f2f2;
}
.prefix {
color: #ff7f00;
font-size: 12px;
}
.literal {
color: #999;
}
.clipboard {
color: #f2f2f2;
cursor: pointer;
padding-left: 5px;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Clipboard.js for RDF triples presentation</title>
<meta name="description" content="Clipboard.js for RDF triples presentation">
<script src="https://cdn.jsdelivr.net/clipboard.js/1.5.5/clipboard.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css?family=Noto+Serif" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="index.css">
</head>
<body>
<table></table>
<script src="index.js"></script>
</body>
</html>
// Generated by CoffeeScript 1.10.0
(function() {
var cb, container, data, height, margin, objects, predicates, predicates_clip, prefixes, subjects, subjects_clip, triples, triples_enter, width;
width = 960;
height = 500;
margin = 20;
cb = new Clipboard('.fa-clipboard');
prefixes = {
'http://dbpedia.org/resource': 'dbr:',
'http://www.w3.org/2000/01/rdf-schema': 'rdfs:',
'http://dbpedia.org/ontology': 'dbo:',
'http://www.w3.org/2002/07/owl': 'owl:'
};
data = [
{
subject: 'http://dbpedia.org/resource/Pisa',
predicate: 'http://www.w3.org/2000/01/rdf-schema/label',
object: 'Pisa'
}, {
subject: 'http://dbpedia.org/resource/Pisa',
predicate: 'http://dbpedia.org/ontology/populationTotal',
object: '89373',
object_datatype: 'http://www.w3.org/2001/XMLSchema#date'
}, {
subject: 'http://dbpedia.org/resource/Pisa',
predicate: 'http://dbpedia.org/ontology/country',
object: 'http://dbpedia.org/resource/Italy'
}, {
subject: 'http://dbpedia.org/resource/Pisa',
predicate: 'http://www.w3.org/2002/07/owl/sameAs',
object: 'http://sws.geonames.org/6542122/'
}
];
container = d3.select('table').style({
width: width + "px",
height: height + "px",
'margin-left': margin + "px"
});
triples = container.selectAll('.triple').data(data);
triples_enter = triples.enter().append('tr').attr({
"class": 'triple'
});
subjects = triples.append('td').append('span').attr({
"class": 'subject'
}).on('mouseover', function(d) {
return d3.select(this).select('.clipboard').style('color', '#000');
}).on('mouseout', function(d) {
return d3.select(this).select('.clipboard').style('color', '#f2f2f2');
});
subjects.append('span').attr({
"class": 'prefix',
title: function(d) {
return d.subject.split('/').slice(0, -1).join('/');
}
}).text(function(d) {
return prefixes[d.subject.split('/').slice(0, -1).join('/')];
});
subjects.append('span').text(function(d) {
return d.subject.split('/').slice(-1)[0];
});
subjects_clip = subjects.append('span').attr({
"class": 'clipboard'
});
subjects_clip.append('i').attr({
"class": 'fa fa-clipboard',
'data-clipboard-text': function(d) {
return d.subject;
},
title: 'Copy subject to clipboard.'
}).on('click', function(d) {
return d3.select(this.parentNode).style('color', 'gray');
});
predicates = triples.append('td').append('span').attr({
"class": 'predicate'
}).on('mouseover', function(d) {
return d3.select(this).select('.clipboard').style('color', '#000');
}).on('mouseout', function(d) {
return d3.select(this).select('.clipboard').style('color', '#f2f2f2');
});
predicates.append('span').attr({
"class": 'prefix',
title: function(d) {
return d.predicate.split('/').slice(0, -1).join('/');
}
}).text(function(d) {
return prefixes[d.predicate.split('/').slice(0, -1).join('/')];
});
predicates.append('span').text(function(d) {
return d.predicate.split('/').slice(-1)[0];
});
predicates_clip = predicates.append('span').attr({
"class": 'clipboard'
});
predicates_clip.append('i').attr({
"class": 'fa fa-clipboard',
'data-clipboard-text': function(d) {
return d.predicate;
},
title: 'Copy precicate to clipboard.'
}).on('click', function(d) {
return d3.select(this.parentNode).style('color', 'gray');
});
objects = triples.append('td').append('span').attr({
"class": 'object'
}).on('mouseover', function(d) {
return d3.select(this).select('.clipboard').style('color', '#000');
}).on('mouseout', function(d) {
return d3.select(this).select('.clipboard').style('color', '#f2f2f2');
}).html(function(d) {
if (d.object.indexOf('http') === 0 && (prefixes[d.object.split('/').slice(0, -1).join('/')] != null)) {
return "<span class='prefix'>" + prefixes[d.object.split('/').slice(0, -1).join('/')] + "</span><span>" + (d.object.split('/').slice(-1)[0]) + "</span><span class='clipboard'><i class='fa fa-clipboard' data-clipboard-text='" + d.object + "'></i></span>";
} else if (d.object.indexOf('http') === 0 && (prefixes[d.object.split('/').slice(0, -1).join('/')] == null)) {
return "<<span >" + d.object + "</span>><span class='clipboard'><i class='fa fa-clipboard' data-clipboard-text='" + d.object + "'></i></span>";
} else {
return "<span class='literal'>" + d.object + "</span><span class='clipboard'><i class='fa fa-clipboard' data-clipboard-text='" + d.object + "'></i></span>";
}
});
objects.selectAll('i').on('click', function(d) {
return d3.select(this.parentNode).style('color', 'gray');
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment