Commit ec99dd68 authored by Daniel Suarez Souto's avatar Daniel Suarez Souto
Browse files

Added demo

parent ce67aa27
Pipeline #1289 failed with stages
in 1 minute and 32 seconds
bower_components
from node:7.10.0
ENV NODE_PATH=/tmp/node_modules APP_NAME=entities-chart
# Install dependencies first to use cache
RUN npm install -g http-server bower
ADD bower.json /usr/src/bower.json
RUN cd /usr/src && \
bower install --allow-root && \
cp -a /usr/src/bower_components /usr/src/app/
ADD . /usr/src/app
RUN chmod +x /usr/src/app/init.sh
WORKDIR /usr/src/app
CMD ["/usr/src/app/init.sh"]
...@@ -30,4 +30,39 @@ $ bower install entities-chart ...@@ -30,4 +30,39 @@ $ bower install entities-chart
This command will install it inside `bower_components` folder This command will install it inside `bower_components` folder
Remember to edit your `elements.html` with this component. Remember to edit your `elements.html` with this component.
\ No newline at end of file
## Development
Requirements:
* Docker
* Docker-compose
The docker-compose file can be used to test the component and to develop it.
Simply run:
```
docker compose up
```
And go to http://127.0.0.1:8080/demo/index.html
The docker-compose file mounts the current directory in the docker container, so every change you make to files locally will be reflected immediately in the browser.
If you add new dependencies to the compponent (through the `bower.json` file), you need to either run `bower install` within the container or recreate the image, like so:
```
docker compose up --build
```
Or:
```
docker exec web bower install
```
Note that the component assumes all dependencies are added in `../`.
This is the structure the component will find when installed as a dependency with bower.
To mimic that structure, the `init.sh` script automatically links the bower package.
\ No newline at end of file
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
"paper-button": "PolymerElements/paper-button#^1.0.0", "paper-button": "PolymerElements/paper-button#^1.0.0",
"polymer": "Polymer/polymer#^1.1.0" "polymer": "Polymer/polymer#^1.1.0"
}, },
"devDependencies": {
"entities-chart": "./"
},
"license": "MIT", "license": "MIT",
"homepage": "https://lab.cluster.gsi.dit.upm.es/sefarad/entities-chart" "homepage": "https://lab.cluster.gsi.dit.upm.es/sefarad/entities-chart"
} }
<html>
<head>
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../entities-chart.html">
</head>
<body>
<entities-chart
field="entities.name"
data="{}"
title="Entities"
icon="icons:list"
param="{{param}}"
id="entitieschart"
filters="{{filters}}"
legend='[{"name":"Organization","type":"schema:Organization","color":"#dd4b39"},
{"name":"Place","type":"schema:Place","color":"#ff9900"},
{"name": "Person","type":"schema:Person","color":"#00c0ef"}]'>
</entities-chart>
<script>
var data =
{"aggregations": {
"entities.name": {
"buckets": [
{
"key": "ISIL",
"entity_type":{
"hits": {
"hits": [{
"_source": {
"entities": [{
"@type": ["schema:Organization","prov:Entity"],
"schema:name": "ISIL"
}]
}
}]
}
},
"doc_count": 335
},
{
"key": "United States of America",
"entity_type":{
"hits": {
"hits": [{
"_source": {
"entities": [{
"@type": ["schema:Place","prov:Entity"],
"schema:name": "United States of America"
}]
}
}]
}
},
"doc_count": 316
},
{
"key": "Donald Trump",
"entity_type":{
"hits": {
"hits": [{
"_source": {
"entities": [{
"@type": ["schema:Person","prov:Entity"],
"schema:name": "Donald Trump"
}]
}
}]
}
},
"doc_count": 296}
]
}
}
}
var entities_chart = document.getElementById("entitieschart");
entities_chart.data = data
</script>
</body>
</html>
version: '3'
services:
web:
build: .
stdin_open: true
tty: true
ports:
- "8080:8080"
volumes:
- .:/usr/src/app
\ No newline at end of file
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
.top-bar{ .top-bar{
width: 100%; width: 100%;
background-color: var(--dark-primary-color); background-color: #449DD5;
border-radius: 5px 5px 0 0; border-radius: 5px 5px 0 0;
color: white; color: white;
text-align: center; text-align: center;
...@@ -26,4 +26,85 @@ paper-icon-button.green { ...@@ -26,4 +26,85 @@ paper-icon-button.green {
paper-icon-button.green:hover { paper-icon-button.green:hover {
background: var(--paper-green-50); background: var(--paper-green-50);
border-radius: 50%; border-radius: 50%;
}
.entities .badge.badge-secondary {
border: 1px solid ;
border-bottom-left-radius: 0;
padding-right: 0px;
cursor:pointer;
margin-bottom:5px;
margin-right: 3px;
margin-left: 3px;
font-size: 13px;
}
.entities .badge.badge-secondary:hover {
color: white !important;
}
#chart {
width: 100%;
}
.number {
color: white !important;
padding: 2px;
padding-right: 15px;
padding-left: 10px;
border-bottom-right-radius: 10px;
border-top-right-radius: 10px;
margin-right: -1px;
margin-left: 5px;
}
#tag-wrapper {
margin: 10px 10px 10px 20px;
min-height: 215px;
visibility: visible;
box-shadow: 0 0 black;
}
.content.paper-button {
padding: 0 0.57em;
}
#nodata {
position: absolute;
width: 100%;
line-height: 35px;
text-align: center;
}
#legend_list {
display: flex;
flex-direction: row;
justify-content: center;
margin-bottom: 13px;
margin-top: 13px;
}
.legend_component {
display: flex;
flex-direction: row;
}
.legend_square {
width: 7px;
height: 7px;
float: left;
margin-top: 7px;
margin-right: 3px;
margin-left: 6px
}
.badge {
display: inline-block;
min-width: 10px;
padding: 3px 7px;
font-size: 12px;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
background-color: #777;
border-radius: 10px;
} }
\ No newline at end of file
<link rel="import" href="../polymer/polymer.html"> <script
<link rel="import" href="../iron-icons/iron-icons.html"> src="https://code.jquery.com/jquery-3.3.1.min.js"
<link rel="import" href="../paper-button/paper-button.html"> ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/js/bootstrap.min.js"></script>
<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="/bower_components/iron-icons/iron-icons.html">
<link rel="import" href="/bower_components/paper-button/paper-button.html">
<dom-module id="entities-chart"> <dom-module id="entities-chart">
<style is="custom-style"> <link rel="import" type="css" href="../entities-chart.css">
@import url("../../styles/app-theme.html");
</style>
<link rel="import" type="css" href="entities-chart.css">
<template> <template>
<style type="text/css">
#chart {
width: 100%;
}
.number {
padding: 1px 3px;
border: 1px solid #9e5c26;
border-radius: 5px;
box-shadow: inset 0 1px 0 #f5bf8c;
margin-left: 7px;
color: white;
}
.active .number {
background-color: #ed943f;
background-image: linear-gradient(bottom, rgb(211,95,32) 0%, rgb(223,131,45) 100%);
background-image: -o-linear-gradient(bottom, rgb(211,95,32) 0%, rgb(223,131,45) 100%);
background-image: -moz-linear-gradient(bottom, rgb(211,95,32) 0%, rgb(223,131,45) 100%);
background-image: -webkit-linear-gradient(bottom, rgb(211,95,32) 0%, rgb(223,131,45) 100%);
background-image: -ms-linear-gradient(bottom, rgb(211,95,32) 0%, rgb(223,131,45) 100%);
}
.idle .number {
background-color: #666;
background-image: linear-gradient(bottom, rgb(102,102,102) 0%, rgb(123,123,123) 100%);
background-image: -o-linear-gradient(bottom, rgb(102,102,102) 0%, rgb(123,123,123) 100%);
background-image: -moz-linear-gradient(bottom, rgb(102,102,102) 0%, rgb(123,123,123) 100%);
background-image: -webkit-linear-gradient(bottom, rgb(102,102,102) 0%, rgb(123,123,123) 100%);
background-image: -ms-linear-gradient(bottom, rgb(102,102,102) 0%, rgb(123,123,123) 100%);
}
.tag {
display: inline-block;
margin: 0 0 7px 20px;
position: relative;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 0.9em;
font-weight: bold;
text-decoration: none;
text-shadow: 0px 2px 0px rgba(255,255,255,.4);
height: 2em;
line-height: 2em;
padding: 0 0.5em 0 1em;
border-top: 0.0625em solid #d99d38;
border-right: 0.0625em solid #d99d38;
border-bottom: 0.0625em solid #d99d38;
-webkit-border-radius: 0 0.25em 0.25em 0;
-moz-border-radius: 0 0.25em 0.25em 0;
border-radius: 0 0.25em 0.25em 0;
background-image: -webkit-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 71));
background-image: -moz-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 71));
background-image: -o-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 71));
background-image: -ms-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 71));
background-image: linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 71));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#feda71', EndColorStr='#feba47');
-webkit-box-shadow: inset 0 1px 0 #faeaba, 0 1px 1px rgba(0,0,0,.1);
-moz-box-shadow: inset 0 1px 0 #faeaba, 0 1px 1px rgba(0,0,0,.1);
box-shadow: inset 0 1px 0 #faeaba, 0 1px 1px rgba(0,0,0,.1);
}
.tag:before {
content: '';
width: 1.4584em;
height: 1.4584em;
background-image: -webkit-linear-gradient(left top, rgb(254, 218, 113), rgb(254, 186, 71));
background-image: -moz-linear-gradient(left top, rgb(254, 218, 113), rgb(254, 186, 71));
background-image: -o-linear-gradient(left top, rgb(254, 218, 113), rgb(254, 186, 71));
background-image: -ms-linear-gradient(left top, rgb(254, 218, 113), rgb(254, 186, 71));
background-image: linear-gradient(left top, rgb(254, 218, 113), rgb(254, 186, 71));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,StartColorStr='#feda71', EndColorStr='#feba47');
position: absolute;
left: 0em;
top: -0.0625em;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-o-transform-origin: 0 0;
transform-origin: 0 0;
border-left: 0.0625em solid #d99d38;
border-bottom: 0.0625em solid #d99d38;
-webkit-border-radius: 0 0 0 0.25em;
-moz-border-radius: 0 0 0 0.25em;
border-radius: 0 0 0 0.25em;
}
#tag-wrapper {
margin: 10px 10px 10px 20px;
}
.content.paper-button {
padding: 0 0.57em;
}
.tag {
padding: 0em 0em !important;
color:#000;
margin-bottom: 10px;
}
.tag span{
position: relative;
top:0px;
margin-right: 2px;
}
</style>
<!-- Shadow DOM --> <!-- Shadow DOM -->
<paper-material class="entities" elevation="1"> <paper-material class="entities" elevation="1" style="min-height: 325px; display: flex; flex-direction: column; justify-content: space-between;">
<div class="top-bar"> <div class="top-bar">
<iron-icon icon="{{icon}}"></iron-icon> <iron-icon icon="{{icon}}"></iron-icon>
<span>{{title}}</span> <span>{{title}}</span>
</div> </div>
<div id="tag-wrapper"> <div id="nodata" style="margin-top: 60px">No entries match the current filters</div>
<template is="dom-repeat" items="{{entities}}" as="entity"> <div class="content" style="text-align:center; margin: 0 auto;">
<paper-button class="tag active" on-tap="filter"><span>{{entity.0}}</span><span class="number">{{entity.1}}</span></paper-button> <div id="legend_list">
<template is="dom-repeat" items="{{legend}}" as="element">
<div class="legend_component">
<div class="legend_square" style$="background-color:{{element.color}};"></div>
{{element.name}}
</div>
</template>
</div>
</div>
<div id="tagwrapper" style="min-height: 215px; padding-left: 7px;">
<template is="dom-repeat" items="{{entities}}" as="entity">
<span class="badge badge-secondary" on-tap="filter" style$="background-color: {{getBgColour(entity.2)}}7d; color:#505050; border-color:{{getBgColour(entity.2)}}" data-color$="{{getBgColour(entity.2)}}">{{getEntity(entity.0)}}<span class="number" style$="background-color:{{getBgColour(entity.2)}}">{{entity.1}}</span></span>
</template> </template>
</div> </div>
<div style="float:right"> <div style="float: right; bottom: 10px; width: 100%; display: flex; flex-direction: row; justify-content: flex-end; align-content: center;">
<small>Clear Filters</small> <small style="align-self: center;">Clear Filters</small>
<paper-icon-button icon="delete" alt="menu" class="green" on-tap="removeFilters"></paper-icon-button> <paper-icon-button icon="delete" alt="menu" class="green" on-tap="removeFilters"></paper-icon-button>
</div> </div>
<div style="width:100%; clear: both"></div> <div style="width:100%; clear: both"></div>
...@@ -167,7 +71,12 @@ ...@@ -167,7 +71,12 @@
type: String, type: String,
value: "Entities Chart" value: "Entities Chart"
}, },
legend: {
type: Array,
},
color: {
type: String
},
query: { query: {
type: String, type: String,
observer: '_queryChanged' observer: '_queryChanged'
...@@ -206,29 +115,108 @@ ...@@ -206,29 +115,108 @@
} }
}, },
ready: function(){
},
_dataChanged: function() { _dataChanged: function() {
var that = this var that = this
var aggs = 0 var aggs = 0
//console.log(this.field)
try{ try{
var hits = this.data.aggregations[this.field].buckets; var hits = this.data.aggregations[this.field].buckets;
} }
catch(err){ catch(err){
var hits = [] var hits = []
} }
console.log(hits)
var data = []; var data = [];
hits.forEach(function(entry) { switch(this.field){
data.push([entry.key.toUpperCase(), entry.doc_count]); case "entities.name":
}); hits.forEach(function(entry) {
entry.entity_type.hits.hits[0]._source.entities.forEach(function(entity){
if(entry.key===entity['schema:name']){
data.push([entry.key, entry.doc_count,entity['@type'][0]]);
}
});
});
break;
case "categories.name":
hits.forEach(function(entry){
data.push([entry.key,entry.doc_count])
})
break;
}
if(data.length == 0 ){
this.$.tagwrapper.style.visibility = 'hidden';
this.$.nodata.style.visibility = 'visible';
} else {
this.$.tagwrapper.style.visibility = 'visible';
this.$.nodata.style.visibility = 'hidden';
}
that.entities = data; that.entities = data;
filtered = true; filtered = true;
}, },
getEntity: function(entity) {
if(entity.search("/")){
arr_category=entity.split("/")
name=arr_category[arr_category.length -1]
if(name.length<50){
return name
}
return name.substring(0,50)+"..."
}else{
return entity;
}
},
getBgColour: function(type){
var legend_elements = this.legend
if(legend_elements){
legend_elements.forEach(function(entry){
if(entry["type"]===type){
color=entry["color"]
}
})
}else { // There are other parameter to select just a color
if(this.color){
color = this.color
}else{ //Default background color
color = "#000000"
}
}
$(".entities .badge.badge-secondary").mouseover(function(){
$(this).css("background-color", $(this).attr('data-color'));
});
$(".entities .badge.badge-secondary").mouseleave(function(){
$(this).css("background-color", $(this).attr('data-color') + '7d');
});
return color;
},
removeFilters: function(){ removeFilters: function(){
this.filters = []; this.filters = [];
}, },
filter: function(e) { filter: function(e) {
this.push('filters', { term: { name: e.model.__data__.entity[0].toLowerCase()}}) var myfilters = [e.model.__data__.entity[0]]
var field =""
switch(this.field){
case "entities.name":
field = "entities.schema:name.keyword"
break;
case "categories.name":
field = "taxonomies.rdfs:label.keyword"
break;
default:
break;
}
var terms = {}
terms[field]=myfilters
this.push('filters', { terms: terms})
} }
}); });
......
#!/bin/bash
# Copy bower dependencies when using -v $PWD/:/usr/src/app
if [ -f /.dockerenv ]; then
cp -a /usr/src/bower_components /usr/src/app/;
fi
bower link --allow-root
bower link $APP_NAME --allow-root
http-server .