Added Sunburst Chart (named entities)
This commit is contained in:
parent
381aa65734
commit
8a10ef9364
5 changed files with 123 additions and 4 deletions
|
@ -1,11 +1,11 @@
|
|||
package org.texttechnologylab.project.gruppe_05_1.rest;
|
||||
|
||||
import de.tudarmstadt.ukp.dkpro.core.api.syntax.type.constituent.S;
|
||||
import io.javalin.http.Context;
|
||||
import io.javalin.openapi.*;
|
||||
import org.texttechnologylab.project.gruppe_05_1.database.MongoPprUtils;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.html.HtmlSpeech;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.html.ParlamentarierDetails;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.nlp.NamedEntity;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.nlp.Token;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.nlp.Topic;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.speech.SpeechMetaData;
|
||||
|
@ -117,9 +117,49 @@ public class SpeechController {
|
|||
speech.getNlp().setPosList((List) new ArrayList<Token>()); // Ensure it's never null
|
||||
}
|
||||
|
||||
// NLP: Named Entities
|
||||
if ((speech.getNlp().getNamedEntities() != null)
|
||||
&& (speech.getNlp().getNamedEntities().size() > 0)) {
|
||||
|
||||
Map<String, Map<String, Integer>> namedEntitiesMapOfMaps = new HashMap<>();
|
||||
|
||||
for (NamedEntity ne : speech.getNlp().getNamedEntities()) {
|
||||
String type = ne.getType();
|
||||
String text = ne.getText();
|
||||
|
||||
if (namedEntitiesMapOfMaps.containsKey(type)) {
|
||||
// Named Entity Type bekannt...
|
||||
Map<String, Integer> typeAppearance = namedEntitiesMapOfMaps.get(type);
|
||||
if (typeAppearance.containsKey(text)) {
|
||||
// ... und der Text auch bekannt --> erhöhe die Anzahl um 1
|
||||
typeAppearance.replace(
|
||||
text,
|
||||
typeAppearance.get(text) + 1) ;
|
||||
} else {
|
||||
// ... aber der Text unbekannt --> erstelle einen neuen Eintrag für den Text und füge diesen dem Type-Eintrag hinzu
|
||||
// TODO: DELETE
|
||||
//Map<String, Integer> firstTextAppearance = new HashMap<>();
|
||||
//firstTextAppearance.put(type, 1);
|
||||
|
||||
typeAppearance.put(text, 1);
|
||||
//namedEntitiesMapOfMaps.put(type, firstTextAppearance);
|
||||
}
|
||||
} else {
|
||||
// Named Entity Type unbekannt: erstelle einen neuen Eintrag für Type sowie einen Eintrag für den ihm gehörigen Text
|
||||
Map<String, Integer> firstTextAppearance = new HashMap<>();
|
||||
firstTextAppearance.put(text, 1);
|
||||
namedEntitiesMapOfMaps.put(type, firstTextAppearance);
|
||||
}
|
||||
}
|
||||
|
||||
attributes.put("na_info", namedEntitiesMapOfMaps);
|
||||
} else {
|
||||
attributes.put("na_info", null);
|
||||
}
|
||||
|
||||
// TODO: Token wird momentan etwas komisch abgespeichert, da im Attribut text die POS art steht, und in pos die Anzahl dieser POS arten. Umstrukturieren damit keine Verwirrung herrscht
|
||||
|
||||
// NLP: Sentiments
|
||||
// NLP: Sentiments - TODO
|
||||
if (speech.getNlp().getSentiments() != null) {
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
<svg id="namedEntitiesSunBurstChart" width="100%" height="100%"></svg>
|
||||
|
||||
<script>
|
||||
|
||||
var namedEntitiesData = {
|
||||
"name": "Named Entities", "children": [
|
||||
|
||||
<#list neMap as neType, innerMap>
|
||||
<#include "namedEntitiesTypeEntry.ftl"> <#sep>,
|
||||
</#list>
|
||||
]
|
||||
};
|
||||
|
||||
var ne_sunburst_width = 1000;
|
||||
var ne_sunburst_height = 800;
|
||||
var ne_sunburst_radius = Math.min(ne_sunburst_width, ne_sunburst_height) / 2;
|
||||
var ne_sunburst_color = d3.scaleOrdinal(d3.schemeCategory10);
|
||||
|
||||
var g = d3.select('#namedEntitiesSunBurstChart')
|
||||
.attr('width', ne_sunburst_width)
|
||||
.attr('height', ne_sunburst_height)
|
||||
.append('g')
|
||||
.attr('transform', 'translate(' + ne_sunburst_width / 2 + ',' + ne_sunburst_height / 2 + ')');
|
||||
|
||||
var partition = d3.partition()
|
||||
.size([2 * Math.PI, ne_sunburst_radius]);
|
||||
|
||||
var root = d3.hierarchy(namedEntitiesData)
|
||||
.sum(function (d) { return d.size; });
|
||||
|
||||
partition(root);
|
||||
var arc = d3.arc()
|
||||
.startAngle(function (d) { return d.x0; })
|
||||
.endAngle(function (d) { return d.x1; })
|
||||
.innerRadius(function (d) { return d.y0; })
|
||||
.outerRadius(function (d) { return d.y1; });
|
||||
|
||||
g.selectAll('path')
|
||||
.data(root.descendants())
|
||||
.enter().append('path')
|
||||
.attr("display", function (d) { return d.depth ? null : "none"; })
|
||||
.attr("d", arc)
|
||||
.style('stroke', '#fff')
|
||||
.style("fill", function (d) { return ne_sunburst_color((d.children ? d : d.parent).data.name); });
|
||||
|
||||
g.selectAll('text')
|
||||
.data(root.descendants())
|
||||
.enter().append('text')
|
||||
.attr("transform", function (d) {
|
||||
// Calculate the angle of the text
|
||||
var angle = (d.x0 + d.x1) / 2;
|
||||
var x = (d.y0 + d.y1) / 2 * Math.sin(angle); // Calculate the x position based on the angle
|
||||
var y = (d.y0 + d.y1) / 2 * -Math.cos(angle); // Calculate the y position based on the angle
|
||||
|
||||
// If it's the root, center it perfectly
|
||||
if (d.depth === 0) {
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
return "translate(" + x + "," + y + ")";
|
||||
})
|
||||
.attr("dy", ".35em") // Adjust vertical positioning
|
||||
.style("text-anchor", "middle")
|
||||
.style("font-size", "12px") // Adjust font size if necessary
|
||||
.text(function (d) { return d.data.name; });
|
||||
</script>
|
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 2.4 KiB |
1
src/main/resources/templates/namedEntitiesTextEntry.ftl
Normal file
1
src/main/resources/templates/namedEntitiesTextEntry.ftl
Normal file
|
@ -0,0 +1 @@
|
|||
{"name": "${neText}", "size": ${count}}
|
10
src/main/resources/templates/namedEntitiesTypeEntry.ftl
Normal file
10
src/main/resources/templates/namedEntitiesTypeEntry.ftl
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
{
|
||||
"name": "${neType}",
|
||||
"children": [
|
||||
<#list innerMap as neText, count>
|
||||
<#include "namedEntitiesTextEntry.ftl"> <#sep>,
|
||||
</#list>
|
||||
]
|
||||
}
|
||||
|
|
@ -29,9 +29,9 @@
|
|||
</div>
|
||||
|
||||
<div class="chart">
|
||||
<#if s.nlp.namedEntities??>
|
||||
<#if na_info??>
|
||||
<h3>Named Entities Information (als Sunburst Chart)</h3>
|
||||
<#assign nea = s.nlp.namedEntities>
|
||||
<#assign neMap = na_info>
|
||||
<#include "namedEntitiesSunburstChart.ftl">
|
||||
<#else>
|
||||
<h3>Keine Named Entities Information für diese Rede verfügbar</h3>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue