Skip to content
Snippets Groups Projects
Commit 6c47c57a authored by esikkala's avatar esikkala
Browse files

Add network actions from AcademySampo

parent 97625180
No related branches found
No related tags found
No related merge requests found
......@@ -16,8 +16,11 @@ export const FETCH_BY_URI = 'FETCH_BY_URI'
export const FETCH_BY_URI_FAILED = 'FETCH_BY_URI_FAILED'
export const FETCH_SIMILAR_DOCUMENTS_BY_ID = 'FETCH_SIMILAR_DOCUMENTS_BY_ID'
export const FETCH_SIMILAR_DOCUMENTS_BY_ID_FAILED = 'FETCH_SIMILAR_DOCUMENTS_BY_ID_FAILED'
export const FETCH_NETWORK_BY_ID = 'FETCH_NETWORK_BY_ID'
export const FETCH_NETWORK_BY_ID_FAILED = 'FETCH_NETWORK_BY_ID_FAILED'
export const UPDATE_INSTANCE = 'UPDATE_INSTANCE'
export const UPDATE_INSTANCE_RELATED_DATA = 'UPDATE_INSTANCE_RELATED_DATA'
export const UPDATE_INSTANCE_NETWORK_DATA = 'UPDATE_INSTANCE_NETWORK_DATA'
export const FETCH_FACET = 'FETCH_FACET'
export const FETCH_FACET_CONSTRAIN_SELF = 'FETCH_FACET_CONSTRAIN_SELF'
export const FETCH_FACET_FAILED = 'FETCH_FACET_FAILED'
......@@ -61,10 +64,12 @@ export const fetchPaginatedResultsFailed = (resultClass, error, message) => ({
error,
message
})
export const fetchResults = ({ resultClass, facetClass }) => ({
export const fetchResults = ({ resultClass, facetClass, limit = null, optimize = null }) => ({
type: FETCH_RESULTS,
resultClass,
facetClass
facetClass,
limit,
optimize
})
export const fetchResultCount = ({ resultClass, facetClass }) => ({
type: FETCH_RESULT_COUNT,
......@@ -148,6 +153,19 @@ export const fetchSimilarDocumentsById = ({ resultClass, id, modelName, resultSi
modelName,
resultSize
})
export const fetchNetworkById = ({ resultClass, id, limit = null, optimize = null }) => ({
type: FETCH_NETWORK_BY_ID,
resultClass,
id,
limit,
optimize
})
export const fetchNetworkByIdFailed = ({ resultClass, id, error, message }) => ({
type: FETCH_NETWORK_BY_ID_FAILED,
resultClass,
error,
message
})
export const fetchSimilarDocumentsByIdFailed = (resultClass, id, error, message) => ({
type: FETCH_SIMILAR_DOCUMENTS_BY_ID_FAILED,
resultClass,
......@@ -166,6 +184,11 @@ export const updateInstanceRelatedData = ({ resultClass, data }) => ({
resultClass,
data
})
export const updateInstanceNetworkData = ({ resultClass, data }) => ({
type: UPDATE_INSTANCE_NETWORK_DATA,
resultClass,
data
})
export const fetchFacet = ({ facetClass, facetID }) => ({
type: FETCH_FACET,
facetClass,
......
import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from '@material-ui/core/styles'
import history from '../../History'
import cytoscape from 'cytoscape'
const styles = theme => ({
root: {
height: 400,
[theme.breakpoints.up('md')]: {
height: 'calc(100% - 72px)'
height: 'calc(100% - 21px)'
}
},
cyContainer: {
......@@ -29,7 +30,7 @@ const layout = {
edgeElasticity: 100,
nestingFactor: 5,
gravity: 80,
numIter: 1000,
numIter: 1347,
initialTemp: 200,
coolingFactor: 0.95,
minTemp: 1.0
......@@ -42,10 +43,21 @@ class Network extends React.Component {
}
componentDidMount = () => {
this.props.fetchResults({
resultClass: this.props.resultClass,
facetClass: this.props.facetClass
})
if (this.props.pageType === 'instancePage') {
this.props.fetchNetworkById({
resultClass: this.props.resultClass,
id: this.props.id,
limit: this.props.limit,
optimize: this.props.optimize
})
} else {
this.props.fetchResults({
resultClass: this.props.resultClass,
facetClass: this.props.facetClass,
limit: this.props.limit,
optimize: this.props.optimize
})
}
this.cy = cytoscape({
container: this.cyRef.current,
......@@ -53,37 +65,53 @@ class Network extends React.Component {
{
selector: 'node',
style: {
'background-color': ele => ele.data('class') === 'http://erlangen-crm.org/efrbroo/F4_Manifestation_Singleton'
? '#666' : '#000',
label: 'data(prefLabel)'
shape: 'ellipse',
'font-size': '12',
'background-color': ele => ele.data('color') || '#666',
label: ' data(prefLabel)',
height: ele => (ele.data('size') || 16 / (ele.data('distance') + 1) || '16px'),
width: ele => (ele.data('size') || 16 / (ele.data('distance') + 1) || '16px')
}
},
{
selector: 'edge',
style: {
// 'width': 'data(weight)',
'line-color': '#999',
width: ele => ele.data('weight') || 1,
'line-color': ele => ele.data('color') || '#BBB',
'curve-style': 'bezier',
content: 'data(prefLabel)',
content: ' data(prefLabel) ',
'target-arrow-shape': 'triangle',
'target-arrow-color': '#999',
color: '#555',
'font-size': '9',
'font-size': '6',
'text-valign': 'top',
'text-halign': 'center',
'edge-text-rotation': 'autorotate',
'text-background-opacity': 1,
'text-background-color': '#FFF',
'text-background-color': 'white',
'text-background-shape': 'roundrectangle'
}
}
]
})
this.cy.on('tap', 'node', function () {
try {
if (this.data('href')) {
// console.log(this.data('href'))
history.push(this.data('href'))
}
} catch (e) { // fall back on url change
console.log('Fail', e)
console.log(this.data())
}
})
}
componentDidUpdate = prevProps => {
if (prevProps.resultUpdateID !== this.props.resultUpdateID) {
// console.log(this.props.results.elements);
this.cy.elements().remove()
this.cy.add(this.props.results.elements)
this.cy.layout(layout).run()
}
......@@ -108,11 +136,14 @@ class Network extends React.Component {
Network.propTypes = {
classes: PropTypes.object.isRequired,
results: PropTypes.object,
fetchResults: PropTypes.func.isRequired,
fetchResults: PropTypes.func,
fetchNetworkById: PropTypes.func,
resultClass: PropTypes.string.isRequired,
facetClass: PropTypes.string.isRequired,
facetUpdateID: PropTypes.number.isRequired,
resultUpdateID: PropTypes.number.isRequired
facetClass: PropTypes.string,
facetUpdateID: PropTypes.number,
resultUpdateID: PropTypes.number.isRequired,
limit: PropTypes.number.isRequired,
optimize: PropTypes.number.isRequired
}
export default withStyles(styles)(Network)
......@@ -42,6 +42,7 @@ import {
fetchFullTextResults,
clearResults,
fetchByURI,
fetchNetworkById,
fetchFacet,
fetchFacetConstrainSelf,
clearFacet,
......@@ -417,10 +418,13 @@ const SemanticPortal = props => {
<InstanceHomePage
rootUrl={rootUrlWithLang}
fetchByURI={props.fetchByURI}
fetchNetworkById={props.fetchNetworkById}
resultClass={perspective.id}
resultUpdateID={props[perspective.id].resultUpdateID}
properties={props[perspective.id].properties}
tabs={perspective.instancePageTabs}
data={props[perspective.id].instance}
networkData={props[perspective.id].instanceNetworkData}
sparqlQuery={props[perspective.id].instanceSparqlQuery}
isLoading={props[perspective.id].fetching}
routeProps={routeProps}
......@@ -441,7 +445,7 @@ const SemanticPortal = props => {
{perspectiveConfigOnlyInfoPages.map(perspective =>
<Switch key={perspective.id}>
<Redirect
from={`/${perspective.id}/page/:id`}
from={`${rootUrl}/${perspective.id}/page/:id`}
to={`${rootUrlWithLang}/${perspective.id}/page/:id`}
/>
<Route
......@@ -466,10 +470,13 @@ const SemanticPortal = props => {
<InstanceHomePage
rootUrl={rootUrlWithLang}
fetchByURI={props.fetchByURI}
fetchNetworkById={props.fetchNetworkById}
resultClass={perspective.id}
resultUpdateID={props[perspective.id].resultUpdateID}
properties={props[perspective.id].properties}
tabs={perspective.instancePageTabs}
data={props[perspective.id].instance}
networkData={props[perspective.id].instanceNetworkData}
sparqlQuery={props[perspective.id].instanceSparqlQuery}
isLoading={props[perspective.id].fetching}
routeProps={routeProps}
......@@ -597,6 +604,7 @@ const mapDispatchToProps = ({
fetchFacetConstrainSelf,
clearFacet,
fetchGeoJSONLayers,
fetchNetworkById,
fetchGeoJSONLayersBackend,
clearGeoJSONLayers,
sortResults,
......@@ -686,6 +694,10 @@ SemanticPortal.propTypes = {
* Redux action for fetching information about a single entity.
*/
fetchByURI: PropTypes.func.isRequired,
/**
* Redux action for fetching network of a single entity.
*/
fetchNetworkById: PropTypes.func.isRequired,
/**
* Redux action for loading external GeoJSON layers.
*/
......
......@@ -36,6 +36,7 @@ export const INITIAL_STATE = {
paginatedResults: [],
paginatedResultsSparqlQuery: null,
instance: null,
instanceNetworkData: null,
instanceSparqlQuery: null,
resultCount: 0,
page: -1,
......
......@@ -35,6 +35,7 @@ export const INITIAL_STATE = {
paginatedResults: [],
paginatedResultsSparqlQuery: null,
instance: null,
instanceNetworkData: null,
instanceSparqlQuery: null,
resultCount: 0,
page: -1,
......
......@@ -35,6 +35,7 @@ export const INITIAL_STATE = {
paginatedResults: [],
paginatedResultsSparqlQuery: null,
instance: null,
instanceNetworkData: null,
instanceSparqlQuery: null,
resultCount: 0,
page: -1,
......
......@@ -168,6 +168,24 @@ new OpenApiValidator({
}
})
app.get(`${apiPath}/:resultClass/network/:id`, async (req, res, next) => {
const { params, query } = req
try {
const data = await getByURI({
backendSearchConfig,
resultClass: params.resultClass,
uri: params.id,
limit: query.limit,
optimize: query.optimize,
constraints: null,
resultFormat: 'json'
})
res.json(data)
} catch (error) {
next(error)
}
})
app.post(`${apiPath}/faceted-search/:facetClass/facet/:id`, async (req, res, next) => {
const { params, body } = req
try {
......
......@@ -118,15 +118,6 @@ paths:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
description: Results as an array of objects
sparqlQuery:
type: string
description: The SPARQL query that was used for the results
get:
summary: Return all search results as a CSV file
responses:
......@@ -292,6 +283,29 @@ paths:
sparqlQuery:
type: string
description: The SPARQL query that was used for retrieving the metadata
/{resultClass}/network/{id}:
get:
summary: Return a network of a single resource
parameters:
- in: path
name: resultClass
schema:
type: string
required: true
description: The class of the resource
- in: path
name: id
schema:
type: string
required: true
description: The URI of the resource
responses:
'200':
description: Network data
content:
application/json:
schema:
type: object
/full-text-search:
get:
summary: Full text search
......
......@@ -4,17 +4,22 @@ export const runNetworkQuery = async ({
endpoint,
prefixes,
links,
nodes
limit,
nodes,
id,
optimize
}) => {
const payload = {
endpoint,
prefixes,
links,
nodes,
limit: 500
// id: 'http://ldf.fi/mmm/actor/bodley_person_51697938'
limit,
id,
optimize,
customHttpHeaders: { Authorization: `Basic ${process.env.SPARQL_ENDPOINT_BASIC_AUTH}` }
}
const url = 'http://127.0.0.1:5000/query'
const url = 'https://sparql-network.demo.seco.cs.aalto.fi/query' // 'http://127.0.0.1:5000/query'
const config = {
headers: {
'Content-Type': 'application/json'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment