Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi Resource Reactor #83

Open
ccolonna opened this issue Aug 25, 2020 · 13 comments
Open

Multi Resource Reactor #83

ccolonna opened this issue Aug 25, 2020 · 13 comments

Comments

@ccolonna
Copy link

ccolonna commented Aug 25, 2020

First of all, thank you for this wonderful framework, it's a really great and useful project !

I'm working on visualization for ontology design pattern (link below for a reference) and i'm thinking on the way to get isnide ld-r framework.
I provide an example trying to be more clear:

scenario: I'm navigating using ld-r through a dataset with a list of resources. I click on a resource to examine it (it's route would than be handled as defined in routes.js by ResourceReactor, it calls loadResource with the query defined in services/resource.js and i can define a custom view component for this resource )

my problem: this resource is for example a Situation. I would like that it would be treated as a pattern: it may have a TimeInterval and Participants and participants may have Names and Location and location may have Coordinates.

For that, i would need to create a custom component to visualize as a unity multi resource data.
This VIEW coding won't be that difficult i think,

but here arise two problems:

  • how to retrieve multi resource pattern specific data (custom query)
  • how to correctly trigger the MultiResourceReactor that should handle these data (linked to a MultiResource store) etc

If i'm not wrong the ResourceReactor can handle the visualization of a resource and related nodes with a depth of 1.
( The service invoked by the loadResource action generates a query that gets a resource and all its properties (with depth 1).
Again, if i'm correct or is something escapes me ?)

My problem is that i need a more specific query to collect all the data composing the pattern.
And in the context of fluxible i would need also a new Store for the state and maybe a new Reactor etc.

Probably i got confused as you may read and there's a simpler solution :)

What i'm thinking right now would be:

  • create a MultiResourceReactor general enough to treat any kind of MultiResourcePattern
  • create a MultiResourceStore to keep the state of these ontology design patterns
  • create a multiresource route
  • create an action and a service to retrieve this data (accepting more specific queries)
  • find a way to detect at Dataset level if it should trigger the MultiResourceReactor pattern instead of the Resource one and encapsulates those resources to be treat like that with a < NavLink routes="multiresource" ... >

I opened this issues to asks for suggestion to you on how to implement this (do you think to simpler ways to do?) and maybe to propose an enhancement if it may be useful.

thank you very much !

Christian

Gangemi, Aldo. "Ontology design patterns for semantic web content." International semantic web conference. Springer, Berlin, Heidelberg, 2005.

@ali1k
Copy link
Owner

ali1k commented Aug 25, 2020

Thanks @Christian-Nja for raising this issue and enhancement.
You are right, the current ResourceReactor only works on the first level properties/resources and if you want to handle more complex Resources, you need to write your custom SPARQL query and handle the user interactions in a custom component.
The workflow you mentioned seems good to me. If you know those resources are already of a specific type (e.g. Situation), you can use the current ResourceReactor https://github.com/ali1k/ld-r/blob/master/components/reactors/ResourceReactor.js#L62 and just embed your custom component for MultiResource there. I wouldn't call this case a MultiResource though (as it is addressed by Dataset Reactor), but a NestedResource and ComplexResource.

@ccolonna
Copy link
Author

ccolonna commented Aug 26, 2020

Thank you very much @ali1k for your fast reply! Yes now that you make me note i'm agree with you, it is better a ComplexResource than a MultiResource. I know in advance it's URI so i can configure the ResourceReactor as you suggested to handle it.

Maybe i can do something like this (follow on with the example of Situation)
< Situation >
<SituationView data={data} ... >

on loading of the Situation component i can define and trigger a new action such as loadComplexResource or loadExtraProperties
and add directly to the resource service the endpoint for that (something like resources.extraProperties). Maybe i can pass the query via the action payload such that the endpoint may be reused when additional data are required also for other resources.

How does it sounds to you?

The last thing i'm not sure of is where to store the extra data collected by the second query. Do you think it may be possible pass them to the ResourceStore too? Or is there the need for another store ?

Again, thanks for your help!

@ali1k
Copy link
Owner

ali1k commented Aug 26, 2020

Your approach sounds good to me! With regards to making a new store, I think you can still reuse the current ResourceStore. You might only need to have a custom parseProperties in https://github.com/ali1k/ld-r/blob/master/services/utils/ResourceUtil.js#L29 to take care of additional resources/properties you will receive by your custom query.

@ccolonna
Copy link
Author

Great! Thank you very much @ali1k for valuable hints !

@ccolonna
Copy link
Author

ccolonna commented Sep 7, 2020

Thanks to your advice @ali1k i managed to make working the data flow. As a solution I created a new reactor in the reactor.js configuration on the PropertyReactor key. Beside that you need to specify a Viewer for the property/resource and a customQuery to retrieve additional data (i put the query in the configs to, in this way the component may be reused).
This is at the moment working just for static configuration.
May i ask you how to move or where to look to activate this possibility also with dynamic configuration?
Here are the fields i'm using in the reactor config.

    property: {
        generic: {
             ...
        },
        "<myProperty>": {
            propertyReactor: ["ComplexResource"],
            customQuery: [
                "?extraData_1 ?extraData_2",
                "  <resourceURI> <myProperty> ?extraData_1 >",
                "LIMIT 10"
            ],
            patternIViewer: "<myPropertyCustomViewer>"
        }, 

@ali1k
Copy link
Owner

ali1k commented Sep 8, 2020

good to hear that it works now with static config. For dynamic config, you need to change the queries at

https://github.com/ali1k/ld-r/blob/master/plugins/dynamicConfiguration/DynamicConfigurator.js#L949

to retrieve the additional fields you have added there. And the results of those queries are parsed in

https://github.com/ali1k/ld-r/blob/master/services/utils/Configurator.js#L151

@ccolonna
Copy link
Author

Hello @ali1k i encountered a problem while going on with the development of this functionality.
Supposed we have a resource such that:

resource hasSituation situation_1 .
resource hasMeasureCollection collection_1

situation_1 and collection_1 needs additional data and so are treated as we discussed above. A custom query to the SPARQL endpoint is performed for both. So two custom query.
My problem is that both are rendered for the same resource view.

  1. situation_1 triggers loadExtraData action cycle and the store is update.
  2. then collection_1 triggers loadExtraData action cycle and the store is update.

If the two listen to the same ResourceStore after second update (the query from collection_1) data by the two will be merged or override.

SOLUTION 1: CommonStore
All the extra Data from different pattern (or complex resource) are collected in the same store as they arrive from the queries (I just need to pay attention using different variables to avoid overriding).
When a new Resource will be loaded i will add a CLEAN_EXTRA_DATA to flush the store and preparing for new extra data coming from custom query.
CONS:
On every Store Update i will get an unnecessary rerendering of all the Components listening for the common store.
example:

resource hasComplexResource complex_1 ,
                            complex_2,
... 
                            complex_n .

complex_1 will be rerendered n time, complex_2 n times -1 ...

SOLUTION 2: a store for every complex resource pattern

As every complex component listen to a single personal store , there would be no unnecessary rerendering and no problem with data overriding.
CONS:
i would need to write a store for every component i'm going to add.
This like more classic React where every component has it's own state.

What do you think about this?

@ali1k
Copy link
Owner

ali1k commented Sep 23, 2020

It is indeed a complex situation. I was thinking maybe another variation of option 1 is to have different state variables for each case Where your component is listening to. It still doesn’t solve the re- rendering issue though.
I am thinking also for the new version of ld-r to use GraphQL to replace the fluxible state management system.

@ccolonna
Copy link
Author

In this phase i will go with option two (faster) as the work on Visualization for Ontology Design Patterns has research purpose only . In any case as LD-R is a really great framework i'm curious to see how GraphQL can expand its potential! If you need some help let me know!

@ccolonna
Copy link
Author

ccolonna commented Nov 11, 2020

Hi @ali1k, thank you very much if you would like to help me again. I keep on developing the pattern visualization application on top of LD-R. I developed a PatternNetwork visualization at dataset level, and therefore added the specific entry to DatasetReactor. In this way it is possible to view the dataset as a pattern network (node-arc view).

There are three layers here: PatternNetwork -> PatterInstancesNetwork -> SingleInstance (or ComplexResource we spoke above).

I was wondering:

  1. Once i'm in the PatternInstancesNetwork layer and i click on a pattern instance node we move down to Resource/ComplexResource level. And this would be treated with ComplexResource components. My question is which route should i trigger to re-enter in the Resource LD-R level?

I have the URI of the istance, and i know it is of tye Instance. Is it possible to define a reactor sayning all the resources of type Instance to be treated with InstanceView ?

A possible scenario is: we have a Situation pattern and situation_1 pattern instance. situation_1 may be composed by resource such as situation, time_interval, people_involved. I click on situation_1 pattern instance node and i navigate outside of PatternNetwork visualization component going back again inside ResourceReactor.

Here are config files:

Dataset level:

    config: {
        //---------depth 1------------
        dataset: {
            generic: {
                resourceFocusType: [],
                //only allow to view data -> disable edit
                readOnly: 0,
                //used for pagination in resource list
                maxNumberOfResourcesOnPage: 20,
                allowResourceNew: 1,
                allowResourceDelete: 1,
                allowResourceClone: 1,
                allowPropertyNew: 1,
                datasetReactor: ["PatternNetwork"],          <=======
                datasetViewer: ["PatternNetwork"],           <=======
            },

What i don't know is how to retrigger LD-R mechanism (NavLink, route?), i would like to do something like:

        resource: {
            "http://somenasmpace//SituationPattern": {
                resourceReactor: ["Resource"],
                resourceViewer: ["MyComplexResourceCustomComponentSituationPattern"],  
                customQuery: ["query to load other data"]                    <===== this mechanism already implmented
            },

All this is based on the assumption that KnowledgeGraph is modelled with ontology design patterns and annotated with opla vocabulary.

@ali1k
Copy link
Owner

ali1k commented Nov 12, 2020

If the problem is to redirect all resource of type "SituationPattern" to your Complex Resource component, you can use "treatAsResourceType" property.

resource: {
            "http://somenasmpace//SituationPattern": {
                resourceReactor: ["Resource"],
                resourceViewer: ["MyComplexResourceCustomComponentSituationPattern"],  
                treatAsResourceType: 1
            },

@ccolonna
Copy link
Author

ccolonna commented Nov 13, 2020

Hi @ali1k i was not quite clear with the explanation. I reread the paper explaining LD-R algo to clarify myself :) . I have a node representing a resource at Dataset visualization. Clicking on that node i'd like to trigger LD-R adaptive algorithm for the resource represented by the node. To which endpoint/href should i make request and which properties are required ? I suppose i will use a Navlink. Could you kindly point me to the right direction ? What i have is the URI of the resource and also of the dataset.

update

Well i manage to do that on route: /dataset/:did/resource/:rid

@ccolonna
Copy link
Author

Hi @ali1k , i almost manage to complete this feature! The last basic requirement i'm missing is add facets to complex resource.

Imagine we have again a bunch of complex-resource such as situation [1], i would like to filter for example all the complex resources in a specified time interval.

I saw ld-r has a wonderful faceted-browser functionality, can you point me to some docs or reference where to get inspiration?
Do you think there are some points where i can start to add a little adaptation for this use case ? (obviously you don't know what i'm doing :) but maybe you can tell me "it's better to start from 0" or "try to get some code here" )

[1]

situation : {
    location: 'some_location',
    participants: [ 'participant_1' ],
    time : {
                  startTime : "some time",
                  endTime:   "some time + interval",
              },
     geometry {
                  lat:    [x1,y1],
                  long: [x2, y2]      
                    } 
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants