import {
D3GraphCanvas,
SparqlEndpointResponseProvider,
SparqlQueryWindow,
Table,
} from '@ud-viz/widget_sparql';
/**
* The SPARQL Versioning query window class which provides the user interface for querying
* a Versioning compatible SPARQL endpoint and displaying the endpoint response.
*/
export class SparqlVersioningQueryWindow extends SparqlQueryWindow {
/**
* Creates a SPARQL query window.
*
* @param {SparqlEndpointResponseProvider} sparqlProvider The Versioning compatible SPARQL Endpoint Response Provider.
* @param {object} configSparqlWidget The sparqlModule view configuration.
* @param {object} configSparqlWidget.queries Query configurations
* @param {object} configSparqlWidget.queries.title The query title
* @param {object} configSparqlWidget.queries.filepath The path to the file which contains the query text
* @param {object} configSparqlWidget.queries.formats Configuration for which visualizations are allowed
* with this query. Should be an object of key, value
* pairs. The keys of these pairs should correspond
* with the cases in the updateDataView() function.
*/
constructor(sparqlProvider, configSparqlWidget) {
super(sparqlProvider, configSparqlWidget);
/**
* Contains the D3 graph views to display versioned RDF data.
*
* @type {Array<D3GraphCanvas>}
*/
this.d3Graphs = [];
this.resetButton.onclick = () => {
this.d3Graph.clearCanvas();
this.d3Graph.data.clear();
this.d3Graphs.forEach((d3G) => {
d3G.clearCanvas();
d3G.data.clear();
});
};
}
/**
* Given the uri of a node, return the node object.
*
* @param {number} graphId id of the graph
* @param {number} id of the node
* @returns {object|null} return
*/
getNodesByIdGraphAndIdNode(graphId, id) {
const d3Graph = this.d3Graphs.find((d3G) => d3G.id == graphId);
if (d3Graph) {
console.log(d3Graph.data);
const memberNode = d3Graph.data.nodes[id];
if (memberNode) {
return memberNode.id;
}
} else {
console.log(this.d3Graph.data);
const memberNode = this.d3Graph.data.nodes[id];
if (memberNode) {
return memberNode.id;
}
}
console.warn(`No nodes found for node with id: ${id}`);
return null;
}
/**
* Update the DataView.
*
* @param {object} response A JSON object returned by a SparqlEndpointResponseProvider.EVENT_ENDPOINT_RESPONSE_UPDATED event
* @param {string} view_type The selected semantic data view type.
*/
updateDataView(response, view_type) {
console.debug(response);
this.clearDataView();
switch (view_type) {
case 'versioning': {
const distinctVersion = Array.from(
new Set(response.results.bindings.map(({ version }) => version.value))
);
const distinctGraph = Array.from(
new Set(response.results.bindings.map(({ graph }) => graph.value))
);
const groupByVersionedGraph = Object.groupBy(
response.results.bindings,
({ versionedgraph }) => versionedgraph.value
);
const matrix = Array.from(Array(distinctGraph.length), () =>
Array.from(Array(distinctVersion.length))
);
Object.entries(groupByVersionedGraph).forEach(([, elements]) => {
const d3Graph = new D3GraphCanvas(
this.configSparqlWidget,
null,
null
);
d3Graph.svg
.attr('width', this.configSparqlWidget.width)
.attr('height', this.configSparqlWidget.height);
Object.entries(this.eventListeners).forEach(([event, listener]) => {
d3Graph.addEventListener(event, listener);
});
d3Graph.init({
head: response.head,
results: { bindings: elements },
});
this.d3Graphs.push(d3Graph);
if (elements.length > 0) {
matrix[
distinctGraph.findIndex((g) => g === elements[0].graph.value)
][
distinctVersion.findIndex((v) => v === elements[0].version.value)
] = d3Graph.canvas;
}
});
const table = this.buildVersioningTable();
const thead = document.createElement('thead');
const tr = document.createElement('tr');
const empty = document.createElement('th');
empty.setAttribute(
'style',
'border:1px solid;word-wrap: break-word;max-width: 150px;'
);
tr.appendChild(empty);
distinctVersion.forEach((version) => {
const th = document.createElement('th');
th.setAttribute('style', 'border:1px solid;');
th.innerText = 'vers:' + version.split('#').pop();
tr.appendChild(th);
});
thead.appendChild(tr);
table.appendChild(thead);
const tbody = document.createElement('tbody');
matrix.forEach((row, i) => {
const tr = document.createElement('tr');
const td = document.createElement('td');
td.setAttribute(
'style',
'border:1px solid;word-wrap: break-word;max-width: 150px;'
);
td.innerText = distinctGraph[i];
tr.appendChild(td);
row.forEach((cell) => {
if (cell) {
const td = document.createElement('td');
td.setAttribute('style', 'border:1px solid;');
td.appendChild(cell);
tr.appendChild(td);
}
});
tbody.appendChild(tr);
});
table.appendChild(tbody);
this.dataView.append(table);
break;
}
case 'graph':
Object.entries(this.eventListeners).forEach(([event, listener]) => {
this.d3Graph.addEventListener(event, listener);
});
this.d3Graph.init(response);
this.dataView.append(this.d3Graph.canvas);
break;
case 'json':
this.jsonRenderer.renderjson.set_icons('▶', '▼');
this.jsonRenderer.renderjson.set_max_string_length(40);
this.dataView.append(this.jsonRenderer.renderjson(response));
break;
case 'table':
this.dataView.append(this.table.domElement);
this.table.dataAsTable(response.results.bindings, response.head.vars);
this.table.filterInput.addEventListener('change', (e) =>
Table.update(this.table, e)
);
this.dataView.style['height'] = '500px';
this.dataView.style['width'] = '800px';
break;
default:
console.error('This result format is not supported: ' + view_type);
}
}
/**
* Create a table element to display versioned graphs
*
* @returns {HTMLTableElement} A table element
*/
buildVersioningTable() {
const table = document.createElement('table');
table.setAttribute('style', 'border-collapse:collapse;border:1px solid;');
const caption = document.createElement('caption');
caption.innerText =
'Prefix: vers = https://github.com/VCityTeam/ConVer-G/Version#';
table.appendChild(caption);
return table;
}
}