Fachinformationsdienst Biodiversität
Biodiversität-Korpus (Nova) 2
Fachinformationsdienst Biodiversität
BIOfid stellt wissenschaftliche Literatur zur Biodiversitätsforschung – einschließlich digitalisierter historischer Werke – zentral und dauerhaft für die Forschung bereit.
Projektpartner und Förderung Universitätsbibliothek Frankfurt am Main Senckenberg Gesellschaft für Naturforschung Arbeitsgruppe Texttechnologie der Goethe-Universität Frankfurt Gefördert durch die Deutsche Forschungsgemeinschaft (DFG) Lizenzierte Ressourcen Zugang zu JSTOR Global Plants für deutsche Herbarien und botanische Gärten E-Book-Sammlung „Biology“ von Brill Zugang zu „Birds of the World“ (Cornell Lab of Ornithology) Text-Mining Entwicklung und Anwendung von Text-Mining-Methoden auf biodiversitätsbezogene Fachliteratur. Fokus auf Vögel, Schmetterlinge und Gefäßpflanzen. Werkzeuge wie TextAnnotator und DUUI werden bereitgestellt.
Digitale Sammlungen Digitalisierung umfangreicher Literaturbestände (vor allem aus dem 19. und 20. Jahrhundert) für die Forschung und das Text-Mining.
Open-Access-Publikationen Bereitstellung einer Hosting-Plattform für Zeitschriften der Biodiversitätsforschung (z. B. „Beiträge zur Entomologie“, „Kochia“).
Literaturversorgung Bereitstellung lizenzierter und digitalisierter Literatur über das BIOfid-Portal sowie vifabio.
Semantische Suche Integration taxonomischer und anatomischer Ontologien zur semantischen Annotation und Suche. Weiterentwicklung des BIOfid-Portals mit Ontologie-gestützter Recherche nach Arten, Merkmalen und Synonymen.
Perspektiven Erweiterung der digitalen Sammlungen und Text-Mining-Korpora Ausbau der semantischen Suche und Annotation Stärkere Community-Einbindung und Open-Science-Ansatz Dieses Webportal wurde durch den Unified Corpus Explorer bereitgestellt und stellt den digitalen Zugang zu gesammelten Daten und Technologien dar. Mehr zum BIOfid-Projekt unter:
Zur Projektwebseite
Corpora
Biodiversität-Korpus (Nova) 2
Fachinformationsdienst Biodiversitätsforschung (BIOfid)
Im Aufbau! Im Rahmen des Fachinformationsdienstes (FID) Biodiversitätsforschung digitalisiert die Universitätsbibliothek Johann Christian Senckenberg (Frankfurt am Main) Literatur zur Biodiversität mit Schwerpunkt auf Zeitschriften des 20. Jahrhunderts . Zu geringen Anteilen umfasst die Sammlung Biodiversität auch Teile der älteren, urheberrechtsfreien Literatur , die bislang noch nirgends digitalisiert wurde. Ein wesentlicher Zweck der Digitalisierung im FID ist – neben einer besseren Verfügbarkeit der Inhalte – die Schaffung eines Korpus für ein Pilotvorhaben zum Text-Mining in Biodiversitäts-Literatur. Dabei steht Literatur zur Diversität von Gefäßpflanzen, Schmetterlingen und Vögeln in Mitteleuropa im Vordergrund. Der FID Biodiversitätsforschung wird durch die Universitätsbibliothek Johann Christian Senckenberg gemeinsam mit der Senckenberg Gesellschaft für Naturforschung und der AG Texttechnologie am Institut für Informatik der Goethe-Universität in den Jahren 2017 bis 2020 aufgebaut. Der FID einschließlich der Digitalisierung von Biodiversitäts-Literatur wird von der Deutschen Forschungsgemeinschaft (DFG) gefördert.
Team
Das aktive Team hinter dem BIOfid-Suchportal. Das vollständige BIOfid-Team finden Sie hier .
Prof. Alexander Mehler
(Supervisor)
Professor Mehler ist Teilprojektleiter des BIOfid-Projekts und Aufseher des Unified Corpus Explorers.
Mail
Website
Robert-Mayer-Straße 10 60325 Frankfurt am Main
Kevin Bönisch
(Lead Developer)
Herr Bönisch is verantwortlich für die Entwicklung und technische Leitung des Unified Corpus Explorers (UCE).
Mail
Website
Robert-Mayer-Straße 10 60325 Frankfurt am Main
Manuel Schaaf
(Developer)
Doktorand, Teil des Text Technology Labs und Developer von UCE.
Mail
Website
Robert-Mayer-Straße 10 60325 Frankfurt am Main
Dr. Gerwin Kasperek
(Biologe)
Teilprojektleiter des BIOfid-Projekts.
Katrin Peikert
(Entwicklung)
Wissenschaftliche Mitarbeiterin an der Universitätsbibliothek J.C. Senckenberg.
Dr. Martha Kandziora
(Biologin)
Wissenschaftliche Mitarbeiterin am Senckenberg Institut Frankfurt.
Pedro Henrique dos Santos Dias, PhD
(Biologe)
Wissenschaftlicher Mitarbeiter am Senckenberg Institut Frankfurt.
Click on one of the annotations, documents or other wiki elements.
Depending on the selected model and how frequently it is used, the response time may vary. For less frequently used models, there may be an initial delay as the model needs to be loaded. Additionally, larger models may require more resources, which can result in longer response times compared to smaller ones.
Model
Gemma3 (4.3B - Google)
Gemma2 (27B - Google)
DeepSeek-R1 (7.6B - DeepSeek)
Llama (3.2B - Meta)
Start a new chat
Contact
Prof. Dr. Alexander Mehler
Mail
Website
Robert-Mayer-Straße 10 60325 Frankfurt am Main
Imprint
Version 0.0.5
-->
import {ChartJS} from '/js/visualization/chartjs.js';
import {UCEMap} from '/js/visualization/uceMap.js';
import {D3JS} from '/js/visualization/d3js.js';
import {ECharts} from '/js/visualization/echarts.js';
var GraphVizHandler = (function () {
GraphVizHandler.prototype.activeCharts = {};
function GraphVizHandler() {
console.log('Created GraphViz Handler.');
}
GraphVizHandler.prototype.createUceMap = function (target, readonly = false) {
const chartId = generateUUID();
const uceMap = new UCEMap(target, readonly);
this.activeCharts[chartId] = uceMap;
activatePopovers();
return uceMap;
}
/**
* [CHARTJS] -> Creates a pie chart into the given $target (jquery object)
*/
GraphVizHandler.prototype.createBasicChart = async function (target, title, data, type = null) {
const chartId = generateUUID();
let wrapper = document.createElement('div');
wrapper.classList.add('chart-container');
wrapper.setAttribute('data-id', chartId);
const canvas = document.createElement('canvas');
const canvasContainer = document.createElement('div');
canvasContainer.classList.add('canvas-container');
canvasContainer.appendChild(canvas);
wrapper.appendChild(canvasContainer);
const menu = `
`;
wrapper.insertAdjacentHTML('beforeend', menu);
target.appendChild(wrapper);
const jsChart = new ChartJS(canvas, title);
jsChart.setData(data);
if (type) {
jsChart.setType(type);
}
this.activeCharts[chartId] = jsChart;
return jsChart;
}
GraphVizHandler.prototype.createWordCloud = async function (target, title, wordData) {
if (!wordData || !Array.isArray(wordData) || wordData.length === 0) {
console.error('Invalid data provided to drawTopicWordCloud:', wordData);
return;
}
target.innerHTML = '';
const cloudContainer = document.createElement('div');
cloudContainer.className = 'word-cloud-container';
if (title) {
const titleElement = document.createElement('h5');
titleElement.className = 'word-cloud-title text-center';
titleElement.textContent = title;
target.insertBefore(titleElement, target.firstChild);
}
const maxWeight = Math.max(...wordData.map(item => item.weight));
const minWeight = Math.min(...wordData.map(item => item.weight));
const weightRange = maxWeight - minWeight;
wordData.forEach(item => {
const word = document.createElement('div');
word.className = 'word-cloud-item';
word.textContent = item.term;
const normalizedWeight = weightRange === 0 ? 1 : (item.weight - minWeight) / weightRange;
const fontSize = 12 + (normalizedWeight * 24);
word.style.fontSize = fontSize + "px";
word.style.cursor = 'default';
word.style.color = getColorForWeight(normalizedWeight);
word.addEventListener('mouseover', () => {
word.classList.add('hovered');
const tooltip = document.createElement('div');
tooltip.className = 'word-tooltip';
tooltip.textContent = "Weight: " + item.weight.toFixed(4);
document.body.appendChild(tooltip);
const rect = word.getBoundingClientRect();
tooltip.style.top = (rect.top + word.offsetHeight + 50) + "px";
tooltip.style.left = (rect.left + (word.offsetWidth / 5)) + "px";
tooltip.style.transform = 'translateX(-50%)';
word._tooltip = tooltip;
});
word.addEventListener('mouseout', () => {
word.classList.remove('hovered');
if (word._tooltip) {
word._tooltip.remove();
word._tooltip = null;
}
});
cloudContainer.appendChild(word);
});
target.appendChild(cloudContainer);
}
GraphVizHandler.prototype.getColorForWeight = function (weight, start = { r: 0, g: 0, b: 0 }, end = { r: 255, g: 255, b: 255 }) {
return getColorForWeight(weight, start, end);
}
GraphVizHandler.prototype.createSankeyChart = async function (target, title, linksData, nodesData,onClick = null) {
const chartId = generateUUID();
const option = {
title: {
text: title,
top: 'bottom',
left: 'right'
},
tooltip: {
trigger: 'item',
triggerOn: 'mousemove',
formatter: function (params) {
if (params.dataType === 'edge') {
return params.data.source + ' → ' + params.data.target + ': ' + params.data.value + ' ';
} else {
return params.name;
}
}
},
series: {
type: 'sankey',
layout: 'none',
data: nodesData,
links: linksData,
emphasis: {
focus: 'adjacency',
label: {
show: true,
color: '#000'
}
},
lineStyle: {
color: 'gradient',
curveness: 0.5
},
label: {
//color: '#000'
show: false
}
}
};
const echart = new ECharts(target, option); // Pass full option
this.activeCharts[chartId] = echart;
echart.getInstance().on('click', function (params) {
if (onClick && typeof onClick === 'function') {
onClick(params);
}
if (params.dataType === 'node') {
const clickedNode = params.name;
const connectedNodes = new Set([clickedNode]);
const connectedLinks = new Set();
linksData.forEach(link => {
if (link.source === clickedNode || link.target === clickedNode) {
connectedNodes.add(link.source);
connectedNodes.add(link.target);
connectedLinks.add(link.source + '->' + link.target);
}
});
const updatedNodes = nodesData.map(node => ({
...node,
label: {
show: connectedNodes.has(node.name)
},
itemStyle: {
...(node.itemStyle || {}),
opacity: connectedNodes.has(node.name) ? 1 : 0.2
}
}));
const updatedLinks = linksData.map(link => ({
...link,
lineStyle: {
...(link.lineStyle || {}),
opacity: connectedLinks.has(link.source + '->' + link.target) ? 1 : 0.1
}
}));
echart.getInstance().setOption({
series: [{
data: updatedNodes,
links: updatedLinks
}]
});
}
else {
const resetNodes = nodesData.map(node => ({
...node,
label: { show: false },
// itemStyle: {
// ...(node.itemStyle || {}),
// opacity: 0.5
// }
}));
const resetLinks = linksData.map(link => ({
...link,
lineStyle: {
color: 'gradient',
curveness: 0.5
},
}));
echart.getInstance().setOption({
series: [{
data: resetNodes,
links: resetLinks
}]
});
}
});
return echart;
};
GraphVizHandler.prototype.createMiniBarChart = function ({
data = [], // Array of [label, value]
title = '', // Chart title
labelPrefix = '', // Optional prefix for title like "Topics for"
labelHighlight = '', // The highlighted part (e.g., entity/topic name)
primaryColor = '#5470C6', // Default bar color
secondaryColor = '#91CC75', // Alternate bar color
usePrimaryForEntity = false, // Toggle color logic
barHeight = 10, // Height of bars in px
maxBarWidth = 100, // Max bar width in px
minLabelWidth = 70, // Width of label column in px
fontSize = 10 // Font size for values
} = {}) {
// This function creates a simple mini bar chart in HTML which can be used in tooltips or small displays as hover actions.
const maxVal = Math.max(...data.map(([_, v]) => v)) || 1;
const barsHtml = data.map(([label, value]) => {
const width = Math.round((value / maxVal) * maxBarWidth);
return (
'
' +
'' + label + ' ' +
' ' +
'' + value + ' ' +
'
'
);
}).join('');
const fullTitle = '' + labelPrefix + ' ';
return (
'
' +
'
' + (title || fullTitle) + '
' +
(barsHtml || '
No associations
') +
'
'
);
}
GraphVizHandler.prototype.createBarLineChart = async function (
target,
title,
config,
tooltipFormatter,
onClick = null
) {
const chartId = generateUUID();
const {
xData,
seriesData,
yLabel = 'Count'
} = config;
const option = {
tooltip: {
trigger: 'axis',
enterable: true,
backgroundColor: '#fff',
borderColor: '#ccc',
borderWidth: 1,
textStyle: {
color: '#000',
fontSize: 12
},
formatter: tooltipFormatter
},
title: {
text: title,
left: 'center'
},
legend: {
data: seriesData.map(s => s.name),
top: 'auto'
},
xAxis: {
type: 'category',
name: 'X',
data: xData
},
yAxis: {
type: 'value',
name: yLabel
},
dataZoom: [
{
type: 'slider',
show: true,
xAxisIndex: 0,
},
{
type: 'inside',
xAxisIndex: 0
}
],
series: []
};
seriesData.forEach(s => {
option.series.push({
name: s.name,
type: 'bar',
data: s.data,
itemStyle: {
color: s.color,
opacity: 0.15
},
barGap: '-100%',
z: 1
});
option.series.push({
name: s.name,
type: 'line',
data: s.data,
symbol: 'circle',
symbolSize: 10,
lineStyle: { width: 3, color: s.color },
itemStyle: { color: s.color },
z: 2
});
});
const echart = new ECharts(target, option);
this.activeCharts[chartId] = echart;
if (onClick && typeof onClick === 'function') {
echart.getInstance().on('click', onClick);
}
return echart;
};
GraphVizHandler.prototype.createChordChart = async function (
target,
title,
data,
tooltipFormatter = null,
onClick = null
) {
const chartId = generateUUID();
const hasGraphData = data.nodes && data.links && data.categories;
const option = {
title: { text: title, left: 'center' },
tooltip: {
trigger: 'item',
enterable: hasGraphData,
formatter: hasGraphData
? tooltipFormatter
: function (params) {
if (params.dataType === 'edge') {
return params.data.source + ' → ' + params.data.target + ': ' + params.data.value + ' ';
}
return params.name;
}
},
legend: hasGraphData ? {
data: data.categories.map(c => c.name),
left: '10px',
orient: 'vertical',
position: 'right'
} : undefined,
series: hasGraphData ? [{
type: 'graph',
layout: 'circular',
circular: { rotateLabel: true },
data: data.nodes,
links: data.links,
categories: data.categories,
roam: true,
label: { rotate: 90, show: true },
itemStyle: { borderWidth: 1, borderColor: '#aaa' },
lineStyle: { opacity: 0.5, width: 2, curveness: 0.3 },
emphasis: { focus: 'adjacency', label: { show: true } }
}] : {
type: 'chord',
data: data.nodes,
links: data.links,
emphasis: {
focus: 'adjacency',
label: {
show: true,
color: '#000'
}
},
itemStyle: {
borderWidth: 1,
borderColor: '#fff'
}
}
};
const echart = new ECharts(target, option);
this.activeCharts[chartId] = echart;
echart.getInstance().on('click', function (params) {
if (onClick && typeof onClick === 'function') {
onClick(params);
}
});
return echart;
};
GraphVizHandler.prototype.createHeatMap = async function (
target,
title,
matrix,
labels,
series_name= null,
tooltipFormatter = null,
onClick = null
) {
const chartId = generateUUID();
const option = {
title: {
text: title,
left: 'center'
},
tooltip: {
position: 'top',
formatter: tooltipFormatter,
},
grid: {
left: '15%',
bottom: '15%',
containLabel: true
},
xAxis: {
type: 'category',
data: labels,
splitArea: {
show: true
},
axisLabel: {
rotate: 45
}
},
yAxis: {
type: 'category',
data: labels,
splitArea: {
show: true
}
},
visualMap: {
min: 0,
max: Math.max(...matrix.map(d => d[2])),
calculable: true,
orient: 'horizontal',
left: 'center',
bottom: '5%'
},
series: [{
name: series_name || 'Heatmap',
type: 'heatmap',
data: matrix,
roam: true,
label: {
show: false
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
const echart = new ECharts(target, option);
this.activeCharts[chartId] = echart;
echart.getInstance().on('click', function (params) {
if (onClick && typeof onClick === 'function') {
onClick(params);
}
});
return echart;
};
GraphVizHandler.prototype.createNetworkGraph = async function (
target,
title,
nodes,
links,
tooltipFormatter = null,
onClick = null
) {
const chartId = generateUUID();
const option = {
title: { text: '', left: 'center' },
tooltip: {},
xAxis: { show: false, min: 'dataMin', max: 'dataMax' },
yAxis: { show: false, min: 'dataMin', max: 'dataMax' },
animationDuration: 1500,
animationEasingUpdate: 'quinticInOut',
series: [{
type: 'graph',
layout: 'force',
draggable: true,
force: {
edgeLength: 5,
repulsion: 10,
gravity: 0.5
},
data: nodes,
edges: links,
roam: true,
symbolSize: 10,
label: { show: false },
emphasis: {
focus: 'adjacency',
lineStyle: {
width: 10
}
},
itemStyle: { borderColor: '#fff', borderWidth: 1 }
}]
};
const echart = new ECharts(target, option);
this.activeCharts[chartId] = echart;
echart.getInstance().on('click', function (params) {
if (onClick && typeof onClick === 'function') {
onClick(params);
}
});
return echart;
};
return GraphVizHandler;
}());
function getNewGraphVizHandler() {
return new GraphVizHandler();
}
function getColorForWeight(weight, start, end) {
if (!start || !end) return '#000000';
const r = Math.round(start.r + (end.r - start.r) * weight);
const g = Math.round(start.g + (end.g - start.g) * weight);
const b = Math.round(start.b + (end.b - start.b) * weight);
return 'rgba(' + r + ', ' + g + ', ' + b + ', 0.5)';
}
window.graphVizHandler = getNewGraphVizHandler();
import {DrawflowJS} from '/js/visualization/drawflowjs.js';
var FlowVizHandler = (function () {
FlowVizHandler.prototype.activeFlows = {};
function FlowVizHandler() {
console.log('Created FlowVizHandler Handler.');
}
FlowVizHandler.prototype.createFlowChart = async function (target, initialNode) {
const flowId = generateUUID();
const flow = new DrawflowJS(target);
flow.init(initialNode);
this.activeFlows[flowId] = flow;
activatePopovers();
}
FlowVizHandler.prototype.createNewFromLinkableNode = async function (unique, target) {
let container = undefined;
if (target === undefined || target === '') {
container = document.getElementById('full-flow-container');
$(container).parent('#flow-chart-modal').show();
container.innerHTML = ''; // reset the last chart
} else {
container = target;
container.innerHTML = ''; // reset the last chart
// Add a loader
$(container).append(`
`);
}
$.ajax({
url: '/api/wiki/linkable/node',
type: "POST",
data: JSON.stringify({
unique: unique,
}),
contentType: "application/json",
success: function (response) {
const node = response;
window.flowVizHandler.createFlowChart(container, node);
$(container).find('.full-loader').fadeOut(125);
},
error: (xhr, status, error) => {
showMessageModal("Unknown Error", "There was an unknown error loading the linkable node.");
}
}).always(() => {
$(container).find('.full-loader').fadeOut(125);
});
}
return FlowVizHandler;
}());
function getNewFlowVizHandler() {
return new FlowVizHandler();
}
window.flowVizHandler = getNewFlowVizHandler();
/**
* This triggers whenever a button to
*/
$('body').on('click', '.open-linkable-node', function () {
const unique = $(this).data('unique');
const target = $(this).data('target');
window.flowVizHandler.createNewFromLinkableNode(unique, target);
})