/*
function chartSkeleton(nr,
title,
subtitle,
dimension1Fldname,
dimension1Caption,
hasDimension2,
dimension2Fldname,
dimension2Caption,
measure1Fldname,
measure1Caption,
hasMeasure2,
measure2Fldname,
measure2Caption
)
{
this.nr=nr;
this.title=title;
this.subtitle=subtitle;
this.dimension1Fldname=dimension1Fldname;
this.dimension1Caption=dimension1Caption;
this.dimension2Fldname=dimension2Fldname;
this.dimension2Caption=dimension2Caption;
this.measure1Fldname=measure1Fldname;
this.measure1Caption=measure1Caption;
this.measure2Fldname=measure2Fldname;
this.measure2Caption=measure2Caption;
this.hasDimension2 = function () {
if(dimension2Fldname && dimension2Fldname !="")
return true;
else
return false;
}
}*/
function d3dataRow(nr,dimension1,dimension2,measure1 )
{
this.nr=nr;
this.dimension1=dimension1;
this.dimension2=dimension2;
this.measure1=measure1;
}
function commonChartProperty(name,
caption,
isMandatory,
inputType,
staticValues,
range_from,
range_to,
defaultValue,
propUnit,
explanation,
groupCaption,
groupUniquename,
rendererUniquename,
groupVariableName,
variableName,
propValueType,
isGeneric
)
{
this.name=name;
this.caption=caption;
this.staticValues=staticValues;
this.range_from=range_from;
this.range_to=range_from;
this.isMandatory=isMandatory;
this.inputType=inputType;
this.defaultValue=defaultValue;
this.propUnit=propUnit;
this.explanation=explanation;
this.groupCaption=groupCaption;
this.groupUniquename=groupUniquename;
this.rendererUniquename=rendererUniquename;
this.groupVariableName=groupVariableName;
this.variableName=variableName;
this.propValueType=propValueType;
this.isGeneric=isGeneric;
this.getValueResultset = function () {
var valueOptions=[];
var optionCounter=0;
var staticValueArray = staticValues.split(/\|/);
for(var j=0;j < staticValueArray.length;j++)
{
var isDefault=false;
if(staticValueArray[j])
{
if(staticValueArray[j]==this.defaultValue)
isDefault=true;
var o=new selectionPropertyValue(optionCounter,staticValueArray[j],staticValueArray[j],isDefault);
valueOptions[optionCounter]=o;
optionCounter++;
}
}
return valueOptions;
}
}
function commonChartPropertyGroup(caption,groupUniquename,groupVariableName)
{
this.caption=caption;
this.groupUniquename=groupUniquename;
this.groupVariableName=groupVariableName;
}
function renderEChart(chartCode,chartDiv,ergebniselementOrdnr)
{
/*obsolete*/
// Initialize the echarts instance based on the prepared dom
var myChart = echarts.init(document.getElementById(chartDiv),null, { renderer: 'svg' });
var datasetSourceRow=new Array();
var datasetSourceCol=new Array();
//first header row:
var columnCount=rsColumnMetaData[ergebniselementOrdnr].length;
var rowCount=rs[ergebniselementOrdnr].length;
datasetSourceCol=['Fakultät (Schlüssel)','Fakultät','Anzahl der Studierenden','Anteil der Studierenden (in %)'];
datasetSourceRow.push(datasetSourceCol);
//now the data:
for(var i=0;i < rowCount;i++)
{
var datasetSourceCol=new Array();
datasetSourceCol.push(rs[ergebniselementOrdnr][i].dim_studiengang_fb);
datasetSourceCol.push(rs[ergebniselementOrdnr][i].dim_studiengang_fb_str);
datasetSourceCol.push(rs[ergebniselementOrdnr][i].summe);
datasetSourceCol.push(rs[ergebniselementOrdnr][i].anteil);
datasetSourceRow.push(datasetSourceCol);
}
// Specify the configuration items and data for the chart
var datasetObj={dataset: {
source: datasetSourceRow
}
};
//var chartCodeObj = JSON.parse(chartCode);
let optionsObj = {
...datasetObj,
...chartCode
};
// Display the chart using the configuration items and data just specified.
myChart.setOption(optionsObj);
}
function openModalCardDetail(ergebniselementOrdnr)
{
var myModalCard=document.getElementById("modalCardDetail"+ergebniselementOrdnr);
myModalCard.classList.add('is-active');
renderEChart("modalCardDetailImage"+ergebniselementOrdnr,ergebniselementOrdnr);
}
function fillEchartsDataSet(myRs,myRsMetaData,currentChartModel)
{
var dataset =new Array();
var chartType=currentChartModel.chartElements[0].vizTypeUniquename;
//Identify dimensions and measures:
switch (chartType) {
case "echarts_pie":
var measure1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","measure1");
var dimension1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","dimension1");
dataset=fillEchartsDataSetNameValue(myRs,myRsMetaData,dimension1Fldname,measure1Fldname);
break;
case "echarts_bar_y_stack":
//TODO klappt nich tnicht)
var measure1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","measure1");
var dimension1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","dimension1");
var dimension2Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","dimension2");
dataset=fillEchartsDataSetCrosstab(myRs,myRsMetaData,dimension1Fldname,dimension2Fldname,measure1Fldname);
break;
default:
dataset=fillEchartsDataSetSimpleCopy(myRs,myRsMetaData);
break;
}
return dataset;
}
function fillEchartsDataSetSimpleCopy(myRs,myRsMetaData)
{
var myDimensions=[];
var mySource=[];
myRsMetaData.forEach((row) => {
for (var col in row) {
console.log(col +"-"+row[col]);
if(col=="colname" && row[col])
{
myDimensions.push(row[col]);
}
}
});
var rowcount=myRs.length;
var rownr=1;
console.log("Zeilenanzahl " +rowcount);
myRs.forEach((row) => {
mySource.push(row);
rownr++;
}
);
//TODO:Sorting and filtering
return {dimensions:myDimensions, source: mySource };
}
function fillEchartsDataSetCrosstab(myRs,myRsMetaData,dimension1Fldname,dimension2Fldname,measure1Fldname)
{
//TODO, klappt noch nicht
var datasetSourceRow=new Array();
var datasetSourceCol=new Array();
var columnCount=myRsMetaData.length;
var rowCount=myRs.length;
//zuerst die Überschrift:
//erste Spalte enthält Dimension 1, die weiteren Spalten dann die Ausprägungen von Dimension 2:
var dimension1Value;
var dimension2Value;
var previousDimension1Value="";
var previousDimension2Value="";
var measure1Value;
var isFirstTargetRow=true;
myRs.forEach((row) => {
for (var col in row) {
//console.log(col +"-"+row[col]);
if(col==dimension1Fldname)
dimension1Value=row[col];
if(col==dimension2Fldname)
dimension2Value=row[col];
if(col==measure1Fldname)
measure1Value=row[col];
if(dimension1Value!=previousDimension1Value)
{
var datasetSourceRow=new Array();
var datasetSourceCol=new Array();
datasetSourceCol.push(dimension1Value);
if(dimension2Value!=previousDimension2Value)
datasetSourceCol.push(dimension2Value);
}
var datasetSourceCol=new Array();
datasetSourceCol.push(dimension1Value);
datasetSourceCol.push(measure1Value);
datasetSourceRow.push(datasetSourceCol);
}
});
//datasetSourceCol=[dimension1Fldname,dimension2Fldname,measure1Fldname];
//datasetSourceRow.push(datasetSourceCol);
//now the data:
//bei pie chartdimensions:myDimensionss ist die erste Spalte der Name, die zweite der Wert:
/*
for(var i=0;i < rowCount;i++)
{
var datasetSourceCol=new Array();
datasetSourceCol.push(myRs[i].dim_studiengang_fb);
datasetSourceCol.push(myRs[i].summe);
datasetSourceRow.push(datasetSourceCol);
}*/
return datasetSourceRow;
}
function fillEchartsDataSetNameValue(myRs,myRsMetaData,dimension1Fldname,measure1Fldname)
{
var datasetSourceRow=new Array();
var datasetSourceCol=new Array();
var columnCount=myRsMetaData.length;
var rowCount=myRs.length;
datasetSourceCol=[dimension1Fldname,measure1Fldname];
datasetSourceRow.push(datasetSourceCol);
//now the data:
//bei pie chartdimensions:myDimensionss ist die erste Spalte der Name, die zweite der Wert:
var dimension1Value;
var measure1Value;
myRs.forEach((row) => {
for (var col in row) {
//console.log(col +"-"+row[col]);
if(col==dimension1Fldname)
dimension1Value=row[col];
if(col==measure1Fldname)
measure1Value=row[col];
}
var datasetSourceCol=new Array();
datasetSourceCol.push(dimension1Value);
datasetSourceCol.push(measure1Value);
datasetSourceRow.push(datasetSourceCol);
});
/*
for(var i=0;i < rowCount;i++)
{
var datasetSourceCol=new Array();
datasetSourceCol.push(myRs[i].dim_studiengang_fb);
datasetSourceCol.push(myRs[i].summe);
datasetSourceRow.push(datasetSourceCol);
}*/
return datasetSourceRow;
}
/* plot and d3 start:*/
function renderPlotD3Chart(chartDiv,currentChartModel,ergebniselementOrdnr)
{
/*if(document.getElementById("chartName").value=="")
document.getElementById("chartName").value=vizInitialName;*/
if(currentChartModel.chartElements.length>0 && currentChartModel.chartElements[0])
{
renderChartSVGFromModel(currentChartModel,chartDiv,ergebniselementOrdnr);
}
else
document.getElementById(chartDiv).innerHTML="";
//
}
/* Render Model:*/
function renderChartSVGFromModel(currentChartModel,targetDiv,ergebniselementOrdnr,title) {
//first update data if function is defined:
if(currentChartModel.dataTransformation.length>0)
{
for(var k=0;k< currentChartModel.dataTransformation.length;k++)
{
var myFunc=currentChartModel.dataTransformation[k];
for(var row=0;row < rs[ergebniselementOrdnr].length;row++)
{
rs[ergebniselementOrdnr][row][myFunc.colname]=applyFunction(rs[ergebniselementOrdnr][row][myFunc.colname],myFunc.colfunction);
}
}
}
switch (currentChartModel.renderer) {
case "plot":
renderChartSVGfromModelWithPlot(currentChartModel,targetDiv,ergebniselementOrdnr);
break;
case "d3js":
renderChartSVGWithD3(currentChartModel,targetDiv,ergebniselementOrdnr);
break;
case "echarts":
renderEChart2(currentChartModel,targetDiv,ergebniselementOrdnr,title);
break;
default:
alert("No renderer");
break;
}
return true;
}
function renderChartSVGfromModelWithPlot (currentChartModel,targetDiv,ergebniselementOrdnr)
{
console.log("using Plot");
var myOptions=new Object;
//myOptions.marks=new Array();
//myOptions.sort=new Array();
myOptions=getPlotOptionsObj(currentChartModel.chartPropertiesUsed,currentChartModel);
var marksArray=new Array();
/*for(var k=0;k< myChartModel.chartPropertiesUsed.length;k++)
{
}*/
//first empty marks:
for(var k=0;k< myOptions["marks"].length;k++)
{
myOptions["marks"][k].pop();
}
//copy ChartElements to marks:
for(var k=0;k< currentChartModel.chartElements.length;k++)
{
marksArray[k]=renderChartElementWithPlot(currentChartModel.chartElements[k],ergebniselementOrdnr);
/*Plot.barX(rs_table0,
{
x: "gesamt",
y: "eintrag",
fill: "blue"
}
*/
}
myOptions["marks"].push(marksArray);
var svgPlot=Plot.plot(myOptions);
var srcPlot=JSON.stringify(myOptions);
if(document.getElementById("plotCodeTextArea"))
document.getElementById("plotCodeTextArea").innerHTML=srcPlot;
document.getElementById(targetDiv).innerHTML="";
document.getElementById(targetDiv).appendChild(svgPlot);
//return svgPlot;
}
function renderChartSVGWithD3 (currentChartModel,targetDiv,ergebniselementOrdnr)
{
console.log("using D3JS");
var svgD3=new Object;
for(var k=0;k< currentChartModel.chartElements.length;k++)
{
svgD3=renderChartElementWithD3(currentChartModel,k,targetDiv,ergebniselementOrdnr);
}
//document.getElementById(targetDiv).innerHTML="";
//document.getElementById(targetDiv).appendChild(svgD3);
}
function renderChartElementWithD3(currentChartModel,chartElemNr,targetDiv,ergebniselementOrdnr)
{
// append the svg canvas to the page
var margin = { top: 10, right: 20, bottom: 10, left: 20 };
//var margin = { top: 0, right: 50, bottom: 0, left: 0 },
var width = Number(getChartPropertyFromModel(currentChartModel.chartPropertiesUsed,"width")) ;//margin.left - margin.right;
var height = Number(getChartPropertyFromModel(currentChartModel.chartPropertiesUsed,"height"));//margin.top - margin.bottom;
if(width <20)
width=630;
if(height <20)
height=430;
var clearCanvas=document.getElementById(targetDiv);
while (clearCanvas.firstChild) {
clearCanvas.removeChild(clearCanvas.firstChild);
}
//targetDiv
chartElem=currentChartModel.chartElements[chartElemNr];
if(chartElem)
{
var chartType=chartElem.vizTypeUniquename;
var rsIndexNr=ergebniselementOrdnr;
/*if(rs.length==1)
{
//if only 1 datasource is given, the indexNr is ignored
//this way a chartModel can be used in a macro *and* a single view
rsIndexNr=0;
}*/
var myDatasourceRs=rs[rsIndexNr];
var data=filld3data(rs[rsIndexNr],rsColumnMetaData[rsIndexNr],chartElem);
console.log("Mark-option for "+chartType);
switch (chartType)
{
case "sankey":
var mySvg = d3.select("#"+targetDiv).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("viewBox", [0,0, width+ margin.left + margin.right, height+ margin.top + margin.bottom])
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")")
;
mySvg=makeSankeyD3(currentChartModel.chartPropertiesUsed,mySvg,data,rsColumnMetaData[chartElem.datasource],chartElem);
break;
case "worldmap":
var mySvg = d3.select("#"+targetDiv).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("viewBox", [0,0, width+ margin.left + margin.right, height+ margin.top + margin.bottom])
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")")
;
mySvg=makeWorldmapD3(currentChartModel.chartPropertiesUsed,mySvg,data,rsColumnMetaData[chartElem.datasource],chartElem);
break;
case "pie":
var backgroundColorSelected=getChartPropertyFromModel(currentChartModel.chartPropertiesUsed,"backgroundColor",false);
var mySvg = d3.select("#"+targetDiv).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("viewBox", [-(width+ margin.left + margin.right) / 2, -(height+ margin.top + margin.bottom) / 2, width+ margin.left + margin.right, height+ margin.top + margin.bottom])
.style("background-color", backgroundColorSelected)
.append("g")
;
mySvg=makePie_d3(currentChartModel.chartPropertiesUsed,mySvg,data,chartElem,width,height);
break;
case "sunburst":
width = 928;
height = width;
var mySvg = d3.select("#"+targetDiv).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("viewBox", [-(width+ margin.left + margin.right) / 2, -(height+ margin.top + margin.bottom) / 2, width+ margin.left + margin.right, height+ margin.top + margin.bottom])
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")")
;
mySvg=makeSunburstD3(currentChartModel.chartPropertiesUsed,mySvg,data,rsColumnMetaData[chartElem.datasource],chartElem);
break;
default:
alert("Unknown chart type");
break;
}
}
return mySvg;
}
function makePie_d3(myCommonChartProperties,svg,data,chartElem,width,height)
{
//const width = 928;
//const height = Math.min(width, 500);
// Create the color scale.
const radius = Math.min(width, height) / 2;
var innerRadiusPercent = parseFloat(getChartPropertyFromModel(myCommonChartProperties,"innerRadius"),false);
var innnerRadiusComputed= radius * innerRadiusPercent / 100;
var myPalette=getChartPropertyFromModel(myCommonChartProperties,"scheme",false);
var textColor=getChartPropertyFromModel(myCommonChartProperties,"stroke",false);
var cornerRadius=getChartPropertyFromModel(myCommonChartProperties,"cornerRadius",false);
var labelRadiusFactor=parseFloat(getChartPropertyFromModel(myCommonChartProperties,"labelRadiusFactor",false))/100;
if(textColor=="")
textColor="black";
/*const color = d3.scaleOrdinal()
.domain(data.map(d => d.dimension1))
.range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1), data.length).reverse())
const color = d3.scaleOrdinal()
.domain(data.map(d => d.dimension1))
.range(["#8cc277","#78a767","#1d71b8","#5b89c7","#2fac66"]); //Palette HMS
*/
//const color = d3.scaleOrdinal(d3.schemeAccent);
const color = d3.scaleOrdinal(getD3ColorScheme(myPalette));
/*const color = d3.scaleOrdinal()
.domain(data.map(d => d.dimension1))
.range(d3.schemePastel2)
;
*/
// Create the pie layout and arc generator.
const pie = d3.pie()
.sort(null)
.value(d => d.measure1);
const arc = d3.arc()
.innerRadius(innnerRadiusComputed )
.outerRadius(radius - 1)
.cornerRadius(cornerRadius);
const labelRadius = arc.outerRadius()() * labelRadiusFactor;
// A separate arc generator for labels.
const arcLabel = d3.arc()
.innerRadius(labelRadius)
.outerRadius(labelRadius+200);
const arcs = pie(data);
//svg.width=width;
//svg.height=width;
//d3.select(svg).attr("viewBox",[-width / 2, -height / 2, width, height]);
//svg.style="max-width: 100%; height: auto; font: 10px sans-serif;";
/*const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("style", "max-width: 100%; height: auto; font: 10px sans-serif;");
*/
// Add a sector path for each value.
svg.append("g")
.attr("stroke", "white")
.selectAll()
.data(arcs)
.join("path")
.attr("fill", d => color(d.data.dimension1))
.attr("d", arc)
.append("title")
.text(d => `${d.data.dimension1}: ${d.data.measure1.toLocaleString("de-DE")}`);
// Create a new arc generator to place a label close to the edge.
// The label shows the value if there is enough room.
svg.append("g")
.attr("text-anchor", "middle")
.selectAll()
.data(arcs)
.join("text")
.attr("transform", d => `translate(${arcLabel.centroid(d)})`)
.call(text => text.append("tspan")
.attr("y", "-0.4em")
//.attr("font-weight", "bold")
.attr("stroke", textColor)
.attr("fill", textColor)
.text(d => d.data.dimension1))
.call(text => text.filter(d => (d.endAngle - d.startAngle) > 0.25).append("tspan")
.attr("x", 0)
.attr("y", "0.7em")
.attr("fill-opacity", 0.7)
.text(d => d.data.measure1.toLocaleString("de-DE")));
//return svg.node();
return svg.node();
}
function makeWorldmapD3(myCommonChartProperties,mySvg,data,metaData,chartElem)
{
// load the data
var captionEmptyTarget=getChartPropertyFromModel(myCommonChartProperties,"null_value_mask");
renderWorldMap(myCommonChartProperties,mySvg,data);
}
function renderWorldMap(myCommonChartProperties,mySvg,data)
{
const worldWidth = 670;
const worldHeight = 450;
const worldTooltip = d3.select(".vizTooltip");
const worldColor = d3.scaleSequential(d3.interpolateBlues)
.domain([0, 1]); // Domain matches the output of logColor
const worldLogColor = d3.scaleLog()
.domain([1, 41227]) // Adjust this domain to fit your data range
.range([0, 1]);
const worldSvg = d3.select("#world-map")
.attr("width", worldWidth)
.attr("height", worldHeight);
const worldProjection = d3.geoMercator()
.scale(100)
.translate([worldWidth / 2, worldHeight / 1.5]);
const worldPath = d3.geoPath().projection(worldProjection);
var d=getWorldMapData(data);
// Load the world data files
Promise.all([
/*d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson"),*/
/*d3.csv("/superx/viz_worldmap/data.csv", d => ({
iso3: d.iso3,
value: +d.value
}))*/
d3.json("../xml/js/viz/world.geojson"),
/*getLocalJson("/superx/xml/js/viz/world_superx2.geojson"),*/
d
]).then(([worldGeojson, worldData]) => {
const worldDataMap = new Map(worldData.map(d => [d.iso3, d.value]));
mySvg.append("g")
.selectAll("path")
.data(worldGeojson.features)
.enter().append("path")
.attr("d", worldPath)
.attr("fill", d => {
const value = worldDataMap.get(d.id); // Use `d.id` to access ISO 3 codes
if (value === 0) return "#ccc"; // Handle zero values separately
return value ? worldColor(worldLogColor(value)) : "#ccc";
})
.on("mouseover", function (event, d) {
const value = worldDataMap.get(d.id);
worldTooltip.transition()
.duration(200)
.style("opacity", .9);
worldTooltip.html(d.properties.name + "
" + (value ? value : "No data"))
.style("left", (event.pageX) + "px")
.style("top", (event.pageY - 28) + "px");
})
.on("mouseout", function () {
worldTooltip.transition()
.duration(500)
.style("opacity", 0);
});
}).catch(error => {
console.error('Error loading or parsing data:', error);
});
async function getLocalJson(url)
{
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Serverantwort: ${response.status}`);
}
const myJson = await response.json();
return myJson;
} catch (error) {
console.log(error.message);
}
}
function getWorldMapData(data)
{
var myData=[];
var zs="";
for (var i = 0; i < data.length; i++)
{
myData[i] = { "iso3": data[i].dimension1, "value": data[i].measure1 };
}
return myData;
}
}
function makeSankeyD3(myCommonChartProperties,mySvg,data,metaData,chartElem)
{
// load the data
var captionEmptyTarget=getChartPropertyFromModel(myCommonChartProperties,"null_value_mask");
if(captionEmptyTarget=="")
captionEmptyTarget="Leer";
var sNodes=getSankeyNodes(data,captionEmptyTarget); //graph.nodes;
var sLinks=getSankeyLinks(sNodes,data); //graph.links;
renderSankey(myCommonChartProperties,mySvg,sNodes,sLinks);
//var myChartSVG = SankeyChart(sNodes,sLinks);
}
function getSankeyNodes(data,captionEmptyTarget)
{
var myNodes=[];
var distinctSource = [];
var zs="";
for (var i = 0; i < data.length; i++)
{
if(zs.indexOf("_" + data[i].dimension1 +"_")<0)
{
distinctSource.push(data[i].dimension1);
zs+="_" + data[i].dimension1 +"_";
}
}
for (var i = 0; i < data.length; i++)
{
if(zs.indexOf("_" + data[i].dimension2 +"_")<0)
{
distinctSource.push(data[i].dimension2);
zs+="_" + data[i].dimension2 +"_";
}
}
for (var i = 0; i < distinctSource.length; i++)
{
myNodes[i] = { "node": i, "name": distinctSource[i] };
console.log("Abschluss: "+distinctSource[i]);
}
//Kein Abschluss:
myNodes[i] = { "node": i, "name": captionEmptyTarget };
return myNodes;
}
function getSankeyLinks(myNodes,data)
{
var myLinks=[];
var linkIndex=0;
for (var i = 0; i < data.length; i++)
{
if(data[i].dimension2 !="")
{
myLinks[linkIndex]={ "source": getSankeyNodeIndex(myNodes,data[i].dimension1),
"target": getSankeyNodeIndex(myNodes,data[i].dimension2), "value":data[i].measure1 };
linkIndex++;
}
else
{
myLinks[linkIndex]={ "source": getSankeyNodeIndex(myNodes,data[i].dimension1),
"target": myNodes.length-1, "value":data[i].measure1 };
linkIndex++;
}
}
return myLinks;
}
function getSankeyNodeIndex(myNodes,name)
{
var myIndex=0;
for (var i = 0; i < myNodes.length; i++)
{
if(myNodes[i].name==name)
myIndex=i
}
return myIndex;
}
function getMeasureCaption(chartElem,metaData)
{
var measureCaption="";
for(var k=0;k o.vizTypePropertyUniquename == "dimension1");
var dimension1Caption=dimension1Prop.caption;
var dimension1Fldname=dimension1Prop.propertyValue;
var dimension2Prop = "";
var dimension2Caption="";
var dimension2Fldname="";
var dimension2Prop=dsChartElement.elementTypeProperties.find(o => o.vizTypePropertyUniquename == "dimension2");
if(dimension2Prop)
{
dimension2Caption=dimension2Prop.caption;
dimension2Fldname=dimension2Prop.propertyValue;
}
var measure1Prop = dsChartElement.elementTypeProperties.find(o => o.vizTypePropertyUniquename == "measure1");
var measure1Caption=measure1Prop.caption;
var measure1Fldname=measure1Prop.propertyValue;
var skel= new chartSkeleton(ergebniselementOrdnr,
title,
subtitle,
dimension1Fldname,
dimension1Caption,
dimension2Fldname,
dimension2Caption,
measure1Fldname,
measure1Caption,
measure2Fldname,
measure2Caption
);
chartSkeleton(nr,
title,
subtitle,
dimension1Fldname,
dimension1Caption,
hasDimension2,
dimension2Fldname,
dimension2Caption,
measure1Fldname,
measure1Caption,
hasMeasure2,
measure2Fldname,
measure2Caption
} */
function closeModalCardDetail(ergebniselementOrdnr)
{
var myModalCard=document.getElementById("modalCardDetail"+ergebniselementOrdnr);
myModalCard.classList.remove('is-active');
}
function getEchartOptionsBarLine(currentChartModel,myDataset,chartType,titleText)
{
//TODO: bar_x und y abfangen'
var chartTypes = chartType.split(/_/);
var orientation=chartTypes[2];
var measure1Axis="y";
var dimension1Axis="x";
var xAxisType="category";
var yAxisType="value";
if(orientation=="x")
{
measure1Axis="x";
dimension1Axis="y";
yAxisType="category";
xAxisType="value";
}
//var measure1Fldname=getChartPropertyValue(currentChartModel.chartPropertiesUsed,measure1Axis);
var measure1Fldname=getChartElementPropertyValueFromModel(currentChartModel,1,measure1Axis);
var dimension1Fldname=getChartElementPropertyValueFromModel(currentChartModel,1,dimension1Axis);
//var dimension1Fldname=getChartPropertyValue(currentChartModel.chartPropertiesUsed,dimension1Axis);
var subtitleText=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"subtitle");
var scheme = getChartPropertyValue(currentChartModel.chartPropertiesUsed,"scheme");
var myPalette=getSchemeArray(scheme);
var encodeObj={x:dimension1Fldname,y:measure1Fldname};
if(orientation=="x")
encodeObj={y:dimension1Fldname,x:measure1Fldname};
var option = {
dataset: myDataset,
/*klappt nicht, noch testen: transfxAxis: {
typeorm: {
type: 'sort',
config: { dimension: "dim_studiengang_fb", order: 'asc' }
}
,*/
title: {
text: titleText,
subtext: subtitleText,
left: "center",
top: "top",
textStyle: {
fontSize: 20
},
subtextStyle: {
fontSize: 15
}
},
grid: {
top: "16%",
left: "20%"
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
},/*
formatter: function (value, index) {
return numberFormatter(value,"value");
}*/
valueFormatter: (value) => numberFormatter(value,"value")
},
xAxis: {
type:xAxisType, //horizontal oder vertikal
//type: 'category',
axisLabel: {
inside: false,
margin: 15,
fontSize: 12,
width:"100px",
rotate: 30,
formatter: function (value, index) {
return numberFormatter(value,xAxisType);
}
}
},
yAxis: {
//type:'value',
type: yAxisType,
axisLabel: {
inside: false,
margin: 5,
fontSize: 12,
width:"50px",
formatter: function (value, index) {
return numberFormatter(value,yAxisType);
}
}
},
series: [
{
type: chartTypes[1], //bar,line
encode: encodeObj,
barWidth: '30%',
showBackground: true,
backgroundStyle: {
color: '#dfe4f2'
},
margin: 50,
fontSize: 14,
colorBy: 'data',
lineStyle: {
width: 7
},
label: {
show: true
},
labelLayout(params) {
return getLabelLayout(params,orientation)
}
}
],
color:myPalette
};
return option;
}
/* Labels bei Balkendiagramm je nach Orientierung
- horizontal: rechts neben Balken
- vertikal: zentriert im Balken
*/
function getLabelLayout(params,orientation)
{
if(orientation=="x")
{
return {
x: params.rect.x +params.rect.width+ 30,
y: params.rect.y + params.rect.height / 2,
verticalAlign: 'middle',
align: 'right'
};
}
else
return {verticalAlign: 'middle'};
}
function getEchartOptionsNative(currentChartModel,myDataset)
{
var options=currentChartModel.chartElements[0].sourceCode;
options.dataset=myDataset;
//var dataset ={dataset};
//dataset.source=myDataset;
//options=Object.assign(myDataset,options);
return options;
}
function getEchartOptionsPie(currentChartModel,myDataset)
{
var measure1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","measure1");
var dimension1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","dimension1");
var titleText=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"caption");
var scheme = getChartPropertyValue(currentChartModel.chartPropertiesUsed,"scheme");
var myPalette=getSchemeArray(scheme);
var option = {
dataset: {
source: myDataset
},
title: {
text: titleText,
subtext: "",
left: "left",
top: "top",
textStyle: {
fontSize: 20
},
subtextStyle: {
fontSize: 15
}
},
series: [
{
type: 'pie',// sunburst
/*encode: {
value: measure1Fldname,
name: dimension1Fldname
},*/
tooltip: {
trigger: "item"
},
stillShowZeroSum: false,
label: {
show: true,
formatter: '{c}',
width:200
},
fontSize: 12,
radius: ['30%', '80%'], //1. Parameter inside radius, macht ihn zum Donut. 2.Parameter definiert den Anteil des Kreises am ganzen Viewport"
color: myPalette,
itemStyle: {
//borderRadius: [20, 5, 5, 10], //abgerundete Ecken der Tortenstücke
borderColor: '#fff',
borderWidth: 2
}
}
]
};
return option;
}
function getChartPropertyValue(propArray,propName)
{
var propertyValue="";
for (var i=0;i obj.elemID == elemID);
var myChartElem=filtered[0];
if(myChartElem.elementTypeProperties && myChartElem.elementTypeProperties.length)
{
for(var k=0;k < myChartElem.elementTypeProperties.length;k++)
{
myVizTypeProperty=myChartElem.elementTypeProperties[k];
if(myVizTypeProperty.vizTypePropertyUniquename==propUniquename)
{
retVal=myVizTypeProperty.propertyValue;
}
}
}
}
return retVal;
}
function getChartPropertyFromModel(myChartProperties,name,isCommon)
{
var propertyValue="";
if(myChartProperties && myChartProperties.length>0)
{
let prop = myChartProperties.find(o => o.name === name);
if(!prop)
prop = myChartProperties.find(o => o.vizTypePropertyUniquename == name);
if(prop)
propertyValue=prop.propertyValue;
}
//if no value is set from model, retrieve the default value:
if(propertyValue=="" && isCommon)
propertyValue=getCommonChartProperty(name);
return propertyValue;
}
function getCommonChartProperty(name)
{
var propertyValue="";
if(document.forms["chartPropertiesForm"] && document.forms["chartPropertiesForm"].elements[name])
{
propertyValue=document.forms["chartPropertiesForm"].elements[name].value;
}
if(propertyValue=="")
{
let prop = commonChartProperties.find(o => o.name === name);
if(prop.defaultValue!="")
{
propertyValue=prop.defaultValue;
}
}
/*for (var i=0;i {
for (var col in row) {
console.log(col +"-"+row[col]);
if(col==dimension1)
dimension1Value=row[col];
if(col==dimension2)
dimension2Value=row[col];
if(col==measure1)
measure1Value=row[col];
}
data.push(new d3dataRow(rownr,dimension1Value,dimension2Value,measure1Value));
rownr++;
}
);
/*
console.log(rownr +"-" + dimension1Value +"-" +dimension2Value +"-" +measureDimValue);
selectionRs.push(new d3dataRow(rownr,dimension1Value,dimension2Value,measureDimValue));
//identify max String length to compute x axis size
if(dimension1Value.length >maxLenDimension1)
maxLenDimension1=dimension1Value.length;
//the same for values:
if(measureDimValue >maxMeasure)
maxMeasure=measureDimValue;
}
//TODO:Sorting and filtering
*/
return data;
}
function isChartPropertyValidForChartelements(prop,currentChartModel)
{
var propValid=false;
if(prop.isGeneric==1)
return true;
var nrOfChartElements=currentChartModel.chartElements.length;
for(var k=0;k < nrOfChartElements;k++)
{
var usedVizTypeUniquename=currentChartModel.chartElements[k].vizTypeUniquename;
for(var i=0;i < vizTypeProperties.length;i++)
{
if(vizTypeProperties[i].propUniquename==prop.name
&& vizTypeProperties[i].typeUniquename==usedVizTypeUniquename)
propValid=true;
}
}
return propValid;
}
function getD3ColorScheme(name,size)
{
//blues|greens|greys|oranges|purples|reds|paired|set1|pastel1|pastel2|tableau10|category10|accent|dark2
if(size==null || size==0)
size=9;
switch (name) {
case "blues":
return d3.schemeBlues[size];
break;
case "greens":
return d3.schemeGreens[size];
break;
case "greys":
return d3.schemeGreys[size];
break;
case "oranges":
return d3.schemeOranges[size];
break;
case "purples":
return d3.schemePurples[size];
break;
case "reds":
return d3.schemeReds[size];
break;
case "accent":
return d3.schemeAccent;
break;
case "paired":
return d3.schemePaired;
break;
case "set1":
return d3.schemeSet1;
break;
case "category10":
return d3.schemeCategory10;
break;
case "dark2":
return d3.schemeDark2;
break;
case "pastel1":
return d3.schemePastel1;
break;
case "pastel2":
return d3.schemePastel2;
break;
case "tableau10":
return d3.schemeTableau10;
break;
case "custom1":
return ["#5b89c7","#2fac66","#8cc277","#78a767","#1d71b8"];
break;
default:
return d3.schemePastel2;
break;
}
}
function vizTabelleComboOderSichtLaden(maskentid,fname, caption,fnameEscaped,zeilenanzahl,feldart,referrerForm) {
Feldname = fname;
var callurl = '/superx/servlet/SuperXmlMaske';
callurl += "?tid=" + maskentid + "&getJSON_" + getEncoded(Feldname) +
'=xxxxxx-xxxxxx@';
var params = "";
var myElements= new Array();
myElements=document.forms["Weiterverarbeitung"].elements;
var e=document.forms["Weiterverarbeitung"].elements[fname];
for (var i = 1; i < felder.length; i++)
{
e = myElements[felder[i]["htmlname"]];
if (e) {
var t = e.type;
var name = felder[i]["name"];
if (t == 'text')
{
//todo bei startsWith select_ label_ auch überspringen
if (e.value != '') //leere Felder müssen auch übergeben werden MB!!
// 1/2016 MB dies geht nicht weil ISO kodiert
//params+="&"+felder[i]["cb_name"]+"="+encodeURIComponent(e.value);
params += "&" + getEncoded(felder[i]["htmlname"]) + "=" + getEncoded(e.value);
else
params += "&" + getEncoded(felder[i]["htmlname"]) + "=--leer--";
}
}
}
console.log("PARAMS:"+params);
//return false;
var currentFieldValue=document.forms['Weiterverarbeitung'].elements[Feldname].value;
/*var splitchar=",";
if(currentFieldValue.indexOf("|")>-1)
splitchar="\|";
var currentFieldValueArray = currentFieldValue.split(splitchar);
var currentFieldValueCount=currentFieldValueArray.length;
*/
params=encodeURIComponent(params);
//alert(params);
var jspPage="maske_combo_laden.jsp";
if(feldart==12)
jspPage="maske_sicht_laden.jsp";
var editurl="/superx/edit/kern/"+jspPage+"?tid="+maskentid+ "&Feldname="+getEncoded(fname)+"&previousValue="+currentFieldValue;
editurl +="&zeilenanzahl="+zeilenanzahl+"&referrerForm=Weiterverarbeitung¶ms="+params;
neu2=window.open(editurl,"_blank","directories=no,location=no,menubar=no,scrollbars=yes,resizable=yes,toolbar=no,width=800,height=660");
}
function applyFunction(theValue,theFunction)
{
switch (theFunction) {
case "switchWord1and2ff":
var ret=switchWord1and2ff(theValue);
break;
case "justWord1":
var ret=justWord1(theValue);
break;
case "abbreviate":
var ret=abbreviate(theValue,20);
break;
default:
var ret=theValue;
break;
}
return ret;
}
function switchWord1and2ff(theString)
{
//erzeugt z.B. aus "WiSe 2020/2021" den Wert "2020/2021", zum Sortieren
var theWords = theString.split(/ /);
var word1=theWords[0];
var word2="";
var ret="";
if(theWords.length >1)
{
for(var k=1;k < theWords.length;k++)
{
word2+= theWords[k];
}
ret +=word2;
}
ret+=" "+ word1;
return ret.trim();
}
function justWord1(theString)
{
//nur erstes Wort, zum Sortieren
var word1End=-1;
var i=0;
var endFound=false;
do{
var myChar=theString.substr(i,1);
if(myChar=="|" || myChar==" "|| myChar=="-")
{
endFound=true;
word1End=i;
}
else
i++;
}
while (endFound==false && i<=theString.length);
if(word1End==-1)
word1End=theString.length;
return theString.substr(0,word1End);
}
function abbreviate(theString,theMaxLength)
{
//nur erste x Zeichen
if(theString.length > theMaxLength)
{
var theCut = theString.substr(0,theMaxLength-3)+"...";
return theCut;
}
else return theString.trim();
}
function getColumnCaption(columnName)
{
let rsMetaDataLen = rsMetaData.length;
var colCaption=columnName;
for (let i = 0; i < rsMetaDataLen; i++) {
if(rsMetaData[i].colname ==columnName)
colCaption=rsMetaData[i].colcaption;
}
return colCaption;
}
function getSchemeArray(schemeName)
{
var schemeArray=new Array();
switch (schemeName) {
case "abgrp":
/*Bachelor: BA blau #374ca und 80 % , LA BA #5e70ba
Master: #64a6d9 #8cb7e1
Promotion: #7aa2ba
Sonstige: #98b4c9*/
schemeArray=['#374ca','#5e70ba','#64a6d9','#8cb7e1','#7aa2ba','#98b4c9','#ff933e'];
break;
case "fak":
schemeArray=['#488a7c','#374ca9','#ffd705','#a68eca','#e84035','#64a6d9','#ff933e','#ee79ad','#7aa2ba','#c3df35','#9bceab','#782f88','#96BFFF'];
break;
case "unique":
schemeArray=['#004c93'];
break;
case "dichotom":
schemeArray=['rgb(97,162,124)','#c3df35','#9d96f5','#e7bcf3'];
break;
case "quadroColor":
schemeArray=['#374ca9','#5e70ba','#8794cb','#afb7dc'];
break;
case "blandLocalized":
myBland=9;
for(var j=0;j < 17;j++)
{
if(j==myBland)
schemeArray[j]='#004c93';
else
schemeArray[j]='#666666';
}
break;
case "colorGrades":
//cooles Tool:https://mdigi.tools/lighten-color/ in 7% Schritten heller
schemeArray=['#374ca9','#3c53b8','#455cc3','#556ac8','##6477cc','#7384d1','#8291d6','#919fdb','#a0ace0','#afb9e5','#bec6ea','#cdd4ef','#dce1f4','#eceef9','#f4f6fb','#f6f7fc'];
break;
default:
schemeArray=[
'#ec7206',
'#61a27c',
'#b8103b',
'#feca00',
'#FFDB5C',
'#ff9f7f',
'#fb7293',
'#E062AE',
'#E690D1',
'#e7bcf3',
'#9d96f5',
'#8378EA',
'#96BFFF'
];
break;
}
return schemeArray;
}
function openDashboardTab(tabnr,maskennr,optional_filter_name,optional_filter_value,myOptionalFilters)
{
var myForm=document.forms["Weiterverarbeitung"];
myForm.elements["tid"].value=maskennr;
myForm.elements["Tabnr."].value=tabnr;
myForm.elements["reuseresult"].value="false";
//zuerst alle Filter resetten:
if(myForm.elements["Booklet-Stylesheet"])
{
myForm.elements["Booklet-Stylesheet"].value="";
}
if(myOptionalFilters.length>0)
{
for(var j=0;j < myOptionalFilters.length;j++)
{
var optionalFilterFldName=myOptionalFilters[j+1];
console.log("Resetting "+optionalFilterFldName);
if(myForm.elements[optionalFilterFldName])
{
myForm.elements[optionalFilterFldName].value="";
}
}
}
if(optional_filter_name != "")
{
myForm.elements[optional_filter_name].value=optional_filter_value;
}
myForm.submit();
}
function openKachelDetails(ergebniselementOrdnr,formName,maskeninfoTID,grafikUniquename,tablestylesheet,reuseResults)
{
document.forms[formName].elements["tid"].value=maskeninfoTID;
document.forms[formName].elements["Grafik"].value=grafikUniquename;
document.forms[formName].elements["tablestylesheet"].value=tablestylesheet;
if(document.forms[formName].elements["##line##"])
{
document.forms[formName].elements["##line##"].value="";
}
if(!reuseResults)
{
document.forms[formName].elements["reuseresult"].value="false";
}
document.forms[formName].target="_blank";
document.forms[formName].submit();
}
function exportVizBooklet(contenttype,stylesheet)
{
document.forms['Weiterverarbeitung'].stylesheet.value = stylesheet;
//document.forms['Weiterverarbeitung'].tablestylesheet.value = stylesheet;
document.forms['Weiterverarbeitung'].contenttype.value = contenttype;
document.forms['Weiterverarbeitung'].target = '_blank';
document.forms['Weiterverarbeitung'].submit();
}
function numberFormatter(value,axisType,digits,usedLocale)
{
//TODO: digits auswerten
if(axisType=="value")
{
var myusedLocale="de-DE"; //default
if(!usedLocale || usedLocale=="")
myusedLocale=usedLocale;
return new Intl.NumberFormat(myusedLocale).format(value);
}
else
return value ;
}