Trying to integrate vis-timeline

This commit is contained in:
Francesco Mangiacrapa 2022-11-02 18:05:38 +01:00
parent 819032fb13
commit ed4f9bd204
10 changed files with 571 additions and 6 deletions

View File

@ -42,6 +42,7 @@ import org.gcube.portlets.user.geoportaldataviewer.client.gis.ExtentWrapped;
import org.gcube.portlets.user.geoportaldataviewer.client.gis.MapUtils;
import org.gcube.portlets.user.geoportaldataviewer.client.gis.OpenLayerMap;
import org.gcube.portlets.user.geoportaldataviewer.client.ui.GeonaDataViewMainPanel;
import org.gcube.portlets.user.geoportaldataviewer.client.ui.cms.project.relation.TimelineRelationPanel;
import org.gcube.portlets.user.geoportaldataviewer.client.util.ControlledCallBack;
import org.gcube.portlets.user.geoportaldataviewer.client.util.LoaderIcon;
import org.gcube.portlets.user.geoportaldataviewer.shared.GCubeCollection;
@ -153,7 +154,6 @@ public class GeoportalDataViewer implements EntryPoint {
RootPanel.get(APP_DIV).add(mainPanel);
initApplication();
}
});
@ -203,7 +203,7 @@ public class GeoportalDataViewer implements EntryPoint {
ScriptInjector.fromUrl(
"//cdnjs.cloudflare.com/ajax/libs/nanogallery2/3.0.5/jquery.nanogallery2.min.js")
.setWindow(ScriptInjector.TOP_WINDOW).inject();
GWT.log("Loading collections, count " + result.getAvailableCollections().size());
mainPanel.setAvailableCollections(result.getAvailableCollections().values());
@ -224,6 +224,7 @@ public class GeoportalDataViewer implements EntryPoint {
// TODO LOAD INITIAL LAYERS
GWT.log("DONE INIT LOAD");
}
});
@ -240,6 +241,25 @@ public class GeoportalDataViewer implements EntryPoint {
bindEvents();
RootPanel.get(APP_DIV).add(attributionDiv);
new Timer() {
@Override
public void run() {
GWT.log("Instancing timeline");
TimelineRelationPanel timeline = new TimelineRelationPanel("concessione", "projectid");
RootPanel.get("timeline-data").add(timeline);
}
}.schedule(5000);
// Modal modal = new Modal(true, true);
// modal.setWidth(400);
//
// modal.add(timeline);
// modal.show();
}

View File

@ -203,4 +203,6 @@ public interface GeoportalDataViewerService extends RemoteService {
*/
LinkedHashMap<String, Object> getEntrySetsDocumentForProjectID(String profileID, String projectID, int limit);
List<String> getRelationshipsForTimeline(String profileID, String projectID) throws Exception;
}

View File

@ -81,4 +81,6 @@ public interface GeoportalDataViewerServiceAsync {
void getEntrySetsDocumentForProjectID(String profileID, String projectID, int limit,
AsyncCallback<LinkedHashMap<String, Object>> callback);
void getRelationshipsForTimeline(String profileID, String projectID, AsyncCallback<List<String>> callback);
}

View File

@ -0,0 +1,90 @@
package org.gcube.portlets.user.geoportaldataviewer.client.ui.cms.project.relation;
import java.util.List;
import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerServiceAsync;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
public class TimelineRelationPanel extends Composite {
@UiField
ScrollPanel timelineContainer;
private static TimelineRelationPanelUiBinder uiBinder = GWT.create(TimelineRelationPanelUiBinder.class);
interface TimelineRelationPanelUiBinder extends UiBinder<Widget, TimelineRelationPanel> {
}
public TimelineRelationPanel(String profileID, String projectID) {
initWidget(uiBinder.createAndBindUi(this));
timelineContainer.getElement().setId("visualization");
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
public void execute() {
GeoportalDataViewerServiceAsync.Util.getInstance().getRelationshipsForTimeline(profileID, projectID,
new AsyncCallback<List<String>>() {
@Override
public void onSuccess(List<String> result) {
JSONArray toJsonArr = new JSONArray();
for (int i = 0; i < result.size(); i++) {
toJsonArr.set(i, JSONParser.parseStrict(result.get(i)));
}
instanceTimeline(timelineContainer.getElement().getId(), toJsonArr);
}
@Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
});
};
});
}
public static native String instanceTimeline(String idDivContainer, JSONArray jsonItems) /*-{
console.log('showTimeline_instanceTimeline for json items: '
+ jsonItems);
console.log("showTimeline_template: " + $wnd.templateHandlebars);
// DOM element where the Timeline will be attached
var container = $doc.getElementById(idDivContainer);
console.log("showTimeline_container: " + container);
var myArray = $wnd.JSON.parse(jsonItems);
console.log("showTimeline_jsonItems: " + myArray);
var container = $doc.getElementById(idDivContainer);
// Create a DataSet (allows two way data-binding)
var items = new $wnd.vis.DataSet(myArray);
// Create a Timeline
var timeline = new $wnd.vis.Timeline(container, items,
$wnd.optionsTimeline);
}-*/;
}

View File

@ -0,0 +1,18 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:style>
.important {
font-weight: bold;
}
.timeline {
border: 1px solid lightgray;
max-height: 400px;
}
</ui:style>
<g:HTMLPanel>
<g:ScrollPanel ui:field="timelineContainer"
addStyleNames="{style.timeline}"></g:ScrollPanel>
</g:HTMLPanel>
</ui:UiBinder>

View File

@ -76,6 +76,7 @@ import org.gcube.spatial.data.geoutility.bean.LayerStyles;
import org.gcube.spatial.data.geoutility.bean.LayerZAxis;
import org.gcube.spatial.data.geoutility.bean.WmsParameters;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -246,7 +247,7 @@ public class GeoportalDataViewerServiceImpl extends RemoteServiceServlet impleme
throws Exception {
LOG.info("getUploadedImagesForId [itemId: " + itemId + ", itemType: " + itemType + "] called");
return getUploadedImagesForId(this.getThreadLocalRequest(), itemType, itemId, maxImages);
throw new Exception("getUploadedImagesForId must be removed!");
}
/**
@ -1249,4 +1250,36 @@ public class GeoportalDataViewerServiceImpl extends RemoteServiceServlet impleme
return documentAsMap;
}
@Override
public List<String> getRelationshipsForTimeline(String profileID, String projectID) throws Exception {
if (profileID == null || projectID == null)
throw new Exception("Invalid parameter. Either profileID or projectID is null");
try {
LOG.info("Trying to getRelationshipChain for id " + profileID);
List<String> listJSON = new ArrayList<String>();
for (int i = 0; i < 5; i++) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", i);
jsonObject.put("title", "title " + i);
jsonObject.put("start", "201" + i + "-04-1");
jsonObject.put("end", "201" + i + "-09-1");
if (i < 3)
jsonObject.put("image_url",
"https://data-pre.d4science.org/shub/E_ck5hN0hBcGljR3oySm5KOWJxOUMyRkRaWkZ4WnhmWXJjWVlLeWxGcW9FMWQraitOWStmQXREQklNUlMydzNFTw==");
listJSON.add(jsonObject.toString());
}
return listJSON;
} catch (Exception e) {
String erroMsg = "Error occurred on reading relatioships for id: " + projectID;
LOG.error(erroMsg, e);
throw new Exception(erroMsg);
}
}
}

View File

@ -534,4 +534,51 @@ body {
.my-html-table td:last-child {
text-align: justify;
}
/**
VIS TIMELINE CSS
**/
.vis.timeline .item {
border-color: #acacac;
background-color: #efefef;
box-shadow: 2px 2px 5px rgba(128, 128, 128, 0.3);
}
.vis-item-content table {
font-size: 12px;
background: white;
}
.vis-item-content table code {
color: gray;
}
.vis-item-content table span {
color: blue;
font-weight: bold;
font-size: 10px;
background: white;
padding: 3px;
text-align: left !important;
border-radius: 5px;
font-style: italic;
}
.vis-item-content table img {
max-width: 100px;
max-height: 100px;
}
#timeline-data {
width: 800px;
position: absolute;
bottom: 2px;
z-index: 10000;
background: white;
opacity: 0.9;
margin: 0;
left: 50%;
transform: translate(-50%);
}

View File

@ -21,9 +21,87 @@
rel="stylesheet" type="text/css">
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.3.1/jspdf.umd.min.js"
src="//cdnjs.cloudflare.com/ajax/libs/jspdf/2.3.1/jspdf.umd.min.js"
type="text/javascript"></script>
<script
src="//unpkg.com/vis-timeline@7.7.0/standalone/umd/vis-timeline-graph2d.min.js"
type="text/javascript"></script>
<link
href="https://unpkg.com/vis-timeline@7.7.0/styles/vis-timeline-graph2d.min.css"
rel="stylesheet" type="text/css">
<script
src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"
type="text/javascript"></script>
<script id="item-template" type="text/x-handlebars-template">
<table>
{{#if relation}}
<tr><td>
<span id="relation-style">{{relation}}</span>
</tr></td>
{{/if}}
{{#if image_url}}
<tr><td>
<img src="{{image_url}}"></img>
</tr></td>
{{/if}}
<tr>
<th colspan="3" class="description" title="{{content}}">{{truncate title}}</th>
</tr>
<tr>
<td><code>{{dateformat start}} / {{dateformat end}}</code></td>
</tr>
</table>
</script>
<script type="text/javascript">
Handlebars
.registerHelper('dateformat',
function(date) {
try {
if (date) {
var d = new Date(date), month = ''
+ (d.getMonth() + 1), day = ''
+ d.getDate(), year = d.getFullYear();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
return [ year, month, day ].join('-');
}
return "";
} catch (err) {
return date + "";
}
});
Handlebars.registerHelper("truncate", function(input, max_lenght) {
if (!max_lenght)
max_lenght = 10;
if (input.length > max_lenght) {
return input.substring(0, max_lenght) + '...';
}
return input;
});
var templateHandlebars = Handlebars.compile(document
.getElementById('item-template').innerHTML);
var optionsTimeline = {
// specify a template for the items
template : templateHandlebars,
type : 'box'
};
</script>
<!-- -->
<!-- Consider inlining CSS to reduce the number of requested files -->
<!-- -->
@ -61,5 +139,8 @@
application to display correctly.</div>
</noscript>
<div id="geoportal-data-viewer"></div>
<div class="timeline-container">
<div id="timeline-data"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,191 @@
<!doctype html>
<!-- The DOCTYPE declaration above will set the -->
<!-- browser's rendering engine into -->
<!-- "Standards Mode". Replacing this declaration -->
<!-- with a "Quirks Mode" doctype may lead to some -->
<!-- differences in layout. -->
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link
href="//cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@main/dist/en/v6.4.3/css/ol.css"
rel="stylesheet" type="text/css">
<script
src="//cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@main/dist/en/v6.4.3/build/ol.js"
type="text/javascript"></script>
<link
href="//cdnjs.cloudflare.com/ajax/libs/nanogallery2/3.0.5/css/nanogallery2.min.css"
rel="stylesheet" type="text/css">
<script
src="//cdnjs.cloudflare.com/ajax/libs/jspdf/2.3.1/jspdf.umd.min.js"
type="text/javascript"></script>
<script
src="//unpkg.com/vis-timeline@7.7.0/standalone/umd/vis-timeline-graph2d.min.js"
type="text/javascript"></script>
<link
href="https://unpkg.com/vis-timeline@7.7.0/styles/vis-timeline-graph2d.min.css"
rel="stylesheet" type="text/css">
<script
src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"
type="text/javascript"></script>
<script id="item-template" type="text/x-handlebars-template">
<table>
{{#if relation}}
<tr><td>
<span id="relation-style">{{relation}}</span>
</tr></td>
{{/if}}
{{#if image_url}}
<tr><td>
<img src="{{image_url}}"></img>
</tr></td>
{{/if}}
<tr>
<th colspan="3" class="description" title="{{content}}">{{truncate title}}</th>
</tr>
<tr>
<td><code>{{dateformat start}} / {{dateformat end}}</code></td>
</tr>
</table>
</script>
<script type="text/javascript">
Handlebars.registerHelper('dateformat', function(date) {
try {
if (date) {
var d = new Date(date),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
return [year, month, day].join('-');
}
return "";
} catch (err) {
return date + "";
}
});
Handlebars.registerHelper("truncate", function(input, max_lenght) {
if (!max_lenght)
max_lenght = 10;
if (input.length > max_lenght) {
return input.substring(0, max_lenght) + '...';
}
return input;
});
var templateHandlebars = Handlebars.compile(document.getElementById('item-template').innerHTML);
</script>
<!-- -->
<!-- Consider inlining CSS to reduce the number of requested files -->
<!-- -->
<link type="text/css" rel="stylesheet" href="GeoportalDataViewer.css">
<!-- -->
<!-- Any title is fine -->
<!-- -->
<title>GNA Data Viewer Application</title>
<!-- -->
<!-- This script loads your compiled module. -->
<!-- If you add any GWT meta tags, they must -->
<!-- be added before this line. -->
<!-- -->
<script type="text/javascript" language="javascript"
src="GeoportalDataViewer/GeoportalDataViewer.nocache.js"></script>
</head>
<!-- -->
<!-- The body can have arbitrary html, or -->
<!-- you can leave the body empty if you want -->
<!-- to create a completely dynamic UI. -->
<!-- -->
<body>
<!-- OPTIONAL: include this if you want history support -->
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
style="position: absolute; width: 0; height: 0; border: 0"></iframe>
<!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
<noscript>
<div
style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
Your web browser must have JavaScript enabled in order for this
application to display correctly.</div>
</noscript>
<div id="timeline-data" style="width: 600px; height: 400px;"></div>
<div id="geoportal-data-viewer"></div>
<script type="text/javascript">
// DOM element where the Timeline will be attached
var container = document.getElementById('timeline-data');
// Create a DataSet (allows two way data-binding)
var items = new vis.DataSet([{
id: 1,
title: 'item 1',
relation: 'follows',
start: '2014-04-1',
end: '2014-05-30',
image_url: 'https://data-pre.d4science.org/shub/E_ck5hN0hBcGljR3oySm5KOWJxOUMyRkRaWkZ4WnhmWXJjWVlLeWxGcW9FMWQraitOWStmQXREQklNUlMydzNFTw=='
},
{
id: 2,
title: 'item 2',
start: '2015-04-1',
end: '2015-05-30',
},
{
id: 3,
title: 'item 3',
description: 'this is the description',
start: '2016-03-1',
end: '2016-06-30'
},
{
id: 4,
title: 'item 4',
start: '2017-04-16',
end: '2017-05-30'
},
{
id: 6,
title: 'item 6',
start: '2018-04-27',
}
]);
// Configuration for the Timeline
// var options = {};
// Configuration for the Timeline
var options = {
// specify a template for the items
template: templateHandlebars,
type: 'box'
};
// Create a Timeline
var timeline = new vis.Timeline(container, items, options);
</script>
</body>
</html>

View File

@ -26,6 +26,18 @@
href="//cdnjs.cloudflare.com/ajax/libs/nanogallery2/3.0.5/css/nanogallery2.min.css"
rel="stylesheet" type="text/css">
<script
src="//unpkg.com/vis-timeline@7.7.0/standalone/umd/vis-timeline-graph2d.min.js"
type="text/javascript"></script>
<script
src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"
type="text/javascript"></script>
<link
href="//unpkg.com/vis-timeline@7.7.0/styles/vis-timeline-graph2d.min.css"
rel="stylesheet" type="text/css">
<link rel="stylesheet"
href="<%=request.getContextPath()%>/GeoportalDataViewer.css"
type="text/css">
@ -33,5 +45,74 @@
<script type="text/javascript"
src="<%=request.getContextPath()%>/GeoportalDataViewer/GeoportalDataViewer.nocache.js"></script>
<script id="item-template" type="text/x-handlebars-template">
<table>
{{#if relation}}
<tr><td>
<span id="relation-style">{{relation}}</span>
</tr></td>
{{/if}}
{{#if image_url}}
<tr><td>
<img src="{{image_url}}"></img>
</tr></td>
{{/if}}
<tr>
<th colspan="3" class="description" title="{{content}}">{{truncate title}}</th>
</tr>
<tr>
<td><code>{{dateformat start}} / {{dateformat end}}</code></td>
</tr>
</table>
</script>
<div id="geoportal-data-viewer"></div>
<script type="text/javascript">
Handlebars
.registerHelper('dateformat',
function(date) {
try {
if (date) {
var d = new Date(date), month = ''
+ (d.getMonth() + 1), day = ''
+ d.getDate(), year = d.getFullYear();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
return [ year, month, day ].join('-');
}
return "";
} catch (err) {
return date + "";
}
});
Handlebars.registerHelper("truncate", function(input, max_lenght) {
if (!max_lenght)
max_lenght = 10;
if (input.length > max_lenght) {
return input.substring(0, max_lenght) + '...';
}
return input;
});
var templateHandlebars = Handlebars.compile(document
.getElementById('item-template').innerHTML);
var optionsTimeline = {
// specify a template for the items
template : templateHandlebars,
type : 'box'
};
</script>
<div id="geoportal-data-viewer"></div>
<div class="timeline-container">
<div id="timeline-data"></div>
</div>