Commit c17c3ed0 authored by Thibault Ehrhart's avatar Thibault Ehrhart

Add annotations and sources highlighting

parent 8bf87ba7
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
import { TranslateModule } from '@ngx-translate/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
......@@ -18,7 +18,7 @@ import { SearchService } from './services/search/search.service';
imports: [
BrowserModule,
FormsModule,
HttpModule,
HttpClientModule,
TranslateModule.forRoot(),
NgbModule.forRoot(),
CoreModule,
......
......@@ -24,7 +24,7 @@
<li class="infobox-item">Date: {{ selectedItem.dateCreated | date: 'dd/MM/yyyy' }}</li>
<li *ngIf="selectedItem.annotations.length > 0">
<div class="infobox-item" *ngFor="let annotation of selectedItem.annotations">
<span>{{ getAnnotationName(annotation.type) }}:</span>
<span [ngClass]="['colorize', 'color-' + getAnnotationColor(annotation.type)]">{{ getAnnotationName(annotation.type) }}:</span>
<span *ngFor="let value of annotation.values; let last = last">
<a [href]="value.source" target="_blank" [ngStyle]="{ 'font-weight': value.source === search.searchParams.annotations[annotation.type] ? 'bold' : 'normal' }">{{ value.label }}</a><span *ngIf="!last">,</span>
</span>
......@@ -32,7 +32,7 @@
</li>
</ul>
</div>
<div class="text" *ngIf="selectedItem.description" [innerHTML]="selectedItem.description | highlight : search.searchParams.keywords"></div>
<div class="text" *ngIf="selectedItem.description" [innerHTML]="selectedItem.description | colorize : selectedItem.annotations | highlight : search.searchParams.keywords | underline : selectedItem.sources"></div>
</div>
</div>
</div>
......@@ -35,6 +35,17 @@ export class HomeDetailsComponent implements OnInit {
if (id) {
this.newsService.getNewsByUri('http://asrael.eurecom.fr/news/' + id).subscribe((data: any) => {
this.selectedItem = data[0];
this.newsService.getSources(this.selectedItem.identifier).subscribe((sources: any) => {
this.selectedItem.sources = [];
if (sources) {
sources.source_sentences.forEach((sentence: any) => {
this.selectedItem.sources.push(sentence.text);
});
}
}, (error: any) => {
this.selectedItem.sources = [];
});
});
}
});
......@@ -70,4 +81,14 @@ export class HomeDetailsComponent implements OnInit {
return annotationType;
}
getAnnotationColor(annotationType: string) {
switch (annotationType) {
case 'http://adel.eurecom.fr/Stanford/PERSON': return 'person';
case 'http://adel.eurecom.fr/Stanford/LOCATION': return 'location';
case 'http://adel.eurecom.fr/Stanford/MISC': return 'misc';
case 'http://adel.eurecom.fr/Stanford/ORGANIZATION': return 'organization';
}
return 'default';
}
}
......@@ -10,6 +10,8 @@ import { HomeDetailsComponent } from './home-details.component';
import { NewsService } from '../../services/news/news.service';
import { HighlightPipe } from '../../pipes/highlight/highlight.pipe';
import { UnderlinePipe } from '../../pipes/underline/underline.pipe';
import { ColorizePipe } from '../../pipes/colorize/colorize.pipe';
import { NgSelectModule } from '@ng-select/ng-select';
import { TruncateModule } from 'ng2-truncate';
import { DecodeURIPipe } from 'angular-pipes/src/string/decode-uri.pipe';
......@@ -27,6 +29,8 @@ import { DecodeURIPipe } from 'angular-pipes/src/string/decode-uri.pipe';
],
declarations: [
HighlightPipe,
UnderlinePipe,
ColorizePipe,
DecodeURIPipe,
HomeComponent,
HomeDetailsComponent
......
......@@ -12,11 +12,9 @@ export class HighlightPipe implements PipeTransform {
return t.length > 0;
}).join('|');
const regex = new RegExp(pattern, 'gi');
return this.sanitizer.bypassSecurityTrustHtml(
text.replace(regex, (match) => `<span class="search-highlight">${match}</span>`)
);
return text.replace(regex, (match) => `<span class="search-highlight">${match}</span>`);
} else {
return this.sanitizer.bypassSecurityTrustHtml(text);
return text;
}
}
}
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { HttpClient } from '@angular/common/http';
import { Observable, Observer } from 'rxjs/Rx';
import 'rxjs/add/observable/fromPromise';
import { of } from 'rxjs/observable/of';
......@@ -22,7 +22,7 @@ export interface NewsContext {
@Injectable()
export class NewsService {
constructor(private http: Http) { }
constructor(private http: HttpClient) {}
getAnnotations(): Observable<any> {
let client = new Client(environment.virtuosoAddress);
......@@ -129,9 +129,11 @@ export class NewsService {
GRAPH <http://asrael.eurecom.fr/agencefrancepresse/news> { ?sp a nif:Phrase . }
?sp nif:referenceContext ?refContext .
?sp nif:anchorOf ?anchorOf .
?sp nif:beginIndex ?beginIndex .
?sp nif:endIndex ?endIndex .
?sp itsrdf:taClassRef ?classRef .
?sp itsrdf:taIdentRef ?identRef .
BIND(CONCAT(ENCODE_FOR_URI(?anchorOf), "=", ENCODE_FOR_URI(?classRef), "=", ENCODE_FOR_URI(?identRef)) AS ?annotations)
BIND(CONCAT(ENCODE_FOR_URI(?anchorOf), "=", ENCODE_FOR_URI(?classRef), "=", ENCODE_FOR_URI(?identRef), "=", ENCODE_FOR_URI(STR(?beginIndex)), "=", ENCODE_FOR_URI(STR(?endIndex))) AS ?annotations)
}
}
FILTER (?context = ?refContext)
......@@ -156,7 +158,7 @@ export class NewsService {
// Split and decode the values
binding.annotations = binding.annotations.split('|').map((annotation: string) => {
let keyvalue = annotation.split('=');
return { label: decodeURIComponent(keyvalue[0]), type: decodeURIComponent(keyvalue[1]), source: decodeURIComponent(keyvalue[2]) };
return { label: decodeURIComponent(keyvalue[0]), type: decodeURIComponent(keyvalue[1]), source: decodeURIComponent(keyvalue[2]), start: parseInt(decodeURIComponent(keyvalue[3])), end: parseInt(decodeURIComponent(keyvalue[4])) };
});
// Group them by type
binding.annotations = binding.annotations.reduce((acc: any, val: any) => {
......@@ -273,4 +275,8 @@ export class NewsService {
return Observable.fromPromise(client.query(query));
}
getSources(identifier: string): Observable<any> {
return this.http.get('assets/' + identifier.replace(/:/g, '_') + '.json');
}
}
......@@ -242,3 +242,22 @@ form {
line-height: 2;
border-radius: 2px;
}
.underline {
text-decoration: underline;
}
.colorize {
&.color-person {
color: #c0504d;
}
&.color-misc {
color: #9bbb59;
}
&.color-location {
color: #4f81bd;
}
&.color-organization {
color: #f79646;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment