/* 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_series": case "echarts_line_y_series": var dimension1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","stroke"); var seriesSelectionLine=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"series_selection_line"); var seriesSelectionColumn=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"series_selection_column"); dataset=fillEchartsDataSetSeries(myRs,myRsMetaData,dimension1Fldname,seriesSelectionLine,seriesSelectionColumn); break; default: dataset=fillEchartsDataSetSimpleCopy(myRs,myRsMetaData); break; } return dataset; } function fillEchartsDataSetSeries(myRs,myRsMetaData,dimension1Fldname,seriesSelectionLine,seriesSelectionColumn) { var myDimensions=[]; var mySource=[]; var colCounter=0; var colNrOfdimension1Fldname=getColNrOfdimensionFldname(myRsMetaData,dimension1Fldname); linesWanted=getLineOrColumnNumberArray(myRs.length,seriesSelectionLine); colsWanted=getLineOrColumnNumberArray(myRsMetaData.length,seriesSelectionColumn); //zuerst Überschriftenzeile: var dataRow =[]; var rowCounter=0; myRsMetaData.forEach((row) => { rowCounter++; if(colsWanted[rowCounter] || rowCounter==colNrOfdimension1Fldname) { for (var col in row) { { if(col=="colcaption" && row[col]) { dataRow.push(row[col]); } } } } }); mySource.push(dataRow); //Dann die Daten var rowCounter=0; myRs.forEach((row) => { rowCounter++; if(linesWanted[rowCounter]) { var dataRow =[]; colCounter=0; for (var col in row) { colCounter++; if(colsWanted[colCounter] || colCounter==colNrOfdimension1Fldname) { dataRow.push(row[col]); } } mySource.push(dataRow); } }); console.log("Matrix:" + JSON.stringify(mySource)); //TODO:Sorting and filtering return {source: mySource }; } function getColNrOfdimensionFldname(myRsMetaData,dimensionFldname) { var colnr=0; var rowCounter=0; myRsMetaData.forEach((row) => { rowCounter++; for (var col in row) { if(col=="colname" && row[col]==dimensionFldname) { colnr=rowCounter; } } }); return colnr; } function getLineOrColumnNumberArray(elementcount,selectionString) { //*Übergeben wird z.B. ">1",">1 and <5" oder "2,3,6,8" //alle user-Eingaben müssen -1 genommmen werden, weil der Array schon bei 0 beginnt var myArray=new Array(elementcount); var minElement=0; if(selectionString && selectionString.indexOf(">")!=-1) { // find digit after ">": var p1=selectionString.split(">"); var p2=p1[1].split(" "); minElement=parseInt(p2[0])+2; //e.g. 2 } var maxElement=elementcount; if(selectionString && selectionString.indexOf("<")!=-1) { // find digit before "<": var p1=selectionString.split("<"); var p2=p1[1].split(" "); maxElement=parseInt(p2[0])-1; } var singleElement=[]; if(selectionString && selectionString.indexOf(",")!=-1) { singleElement=selectionString.split(","); } for(i=0;imaxElement) isElementWanted=false; if(singleElement && singleElement.length>0) { isElementWanted=false; for(j=0;j { 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("chartCodeTextArea")) document.getElementById("chartCodeTextArea").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,rs[0],rsColumnMetaData[chartElem.datasource],chartElem); break; default: alert("Unknown chart type"); break; } } return mySvg; } function makeSunburstD3(myCommonChartProperties,svg,data,metaData,chartElem) { var sorted = d3.sort(data, d => d.dim_studiengang_fb_str,d => d.dim_studiengang_abschluss_grp_str, d => d.dim_studiengang_stg_str, d => d.summe); var group = d3.group(sorted, d => d.dim_studiengang_fb_str,d => d.dim_studiengang_abschluss_grp_str, d => d.dim_studiengang_stg_str , d => d.summe ); //var sorted = d3.sort(data, d => d.dim_studiengang_fb_str,d => d.dim_studiengang_abschluss_grp_str, d => d.measure1); //var group = d3.group(sorted, d => d.sos_stg_aggr_sem_rueck_beur_ein_str); //console.log(group); //var group = d3.group(sorted, d => d.dim_studiengang_fb_str,d => d.dim_studiengang_abschluss_grp_str, d => d.measure1 ); var hierarchy = d3.hierarchy(group); var level1count=hierarchy.children.length; console.log("level1count:"+level1count); var data_str = "{\"name\":\"root\",\"children\":["; for(var i=0; i < level1count ; i++){ console.log("Zeile "+i+ ":" + hierarchy.children[i].data[0]); data_str+="{\"name\":\""+hierarchy.children[i].data[0]+"\",\"children\":["; var level2count=hierarchy.children[i].children.length; for(var j=0; j < level2count ; j++){ console.log("unterZeile "+j+ ":" + hierarchy.children[i].children[j].data[0]); data_str+="{\"name\":\""+hierarchy.children[i].children[j].data[0]+"\",\"children\":["; /*var level3count=hierarchy.children[i].children[j].children.length; console.log("level3count: "+level3count); for(var k=0; k < level3count ; k++){ console.log("unterUnterZeile "+k+ ":" + hierarchy.children[i].children[j].children[k].data[0]); data_str+="{\"name\":\""+hierarchy.children[i].children[j].children[k].data[0]+"\",\"value\":"+hierarchy.children[i].children[j].children[k].children[0].data[0] +"}"; if(k < level3count -1) data_str+=","; } */ data_str+="]}"; if(j < level2count -1) data_str+=","; } data_str+="]}"; if(i < level1count -1) data_str+=","; //console.log("Zeile "+i+ ":" + hierarchy.children[i].children[0].data); } data_str+="]}" console.log(data_str); var dataHierarchy=JSON.parse(data_str); return renderSunburst(dataHierarchy,svg); } function renderSunburst(data,svg) { // Specify the chart’s dimensions. const width = 928; const height = width; const radius = width / 6; // Create the color scale. const color = d3.scaleOrdinal(d3.quantize(d3.interpolateRainbow, data.children.length + 1)); // Compute the layout. const hierarchy = d3.hierarchy(data) .sum(d => d.value) .sort((a, b) => b.value - a.value); const root = d3.partition() .size([2 * Math.PI, hierarchy.height + 1]) (hierarchy); root.each(d => d.current = d); // Create the arc generator. const arc = d3.arc() .startAngle(d => d.x0) .endAngle(d => d.x1) .padAngle(d => Math.min((d.x1 - d.x0) / 2, 0.005)) .padRadius(radius * 1.5) .innerRadius(d => d.y0 * radius) .outerRadius(d => Math.max(d.y0 * radius, d.y1 * radius - 1)) // Create the SVG container. // Append the arcs. const path = svg.append("g") .selectAll("path") .data(root.descendants().slice(1)) .join("path") .attr("fill", d => { while (d.depth > 1) d = d.parent; return color(d.data.name); }) .attr("fill-opacity", d => arcVisible(d.current) ? (d.children ? 0.6 : 0.4) : 0) .attr("pointer-events", d => arcVisible(d.current) ? "auto" : "none") .attr("d", d => arc(d.current)); // Make them clickable if they have children. path.filter(d => d.children) .style("cursor", "pointer") .on("click", clicked); const format = d3.format(",d"); path.append("title") .text(d => `${d.ancestors().map(d => d.data.name).reverse().join("/")}\n${format(d.value)}`); const label = svg.append("g") .attr("pointer-events", "none") .attr("text-anchor", "middle") .style("user-select", "none") .selectAll("text") .data(root.descendants().slice(1)) .join("text") .attr("dy", "0.35em") .attr("fill-opacity", d => +labelVisible(d.current)) .attr("transform", d => labelTransform(d.current)) .text(d => d.data.name); const parent = svg.append("circle") .datum(root) .attr("r", radius) .attr("fill", "none") .attr("pointer-events", "all") .on("click", clicked); // Handle zoom on click. function clicked(event, p) { parent.datum(p.parent || root); root.each(d => d.target = { x0: Math.max(0, Math.min(1, (d.x0 - p.x0) / (p.x1 - p.x0))) * 2 * Math.PI, x1: Math.max(0, Math.min(1, (d.x1 - p.x0) / (p.x1 - p.x0))) * 2 * Math.PI, y0: Math.max(0, d.y0 - p.depth), y1: Math.max(0, d.y1 - p.depth) }); const t = svg.transition().duration(750); // Transition the data on all arcs, even the ones that aren’t visible, // so that if this transition is interrupted, entering arcs will start // the next transition from the desired position. path.transition(t) .tween("data", d => { const i = d3.interpolate(d.current, d.target); return t => d.current = i(t); }) .filter(function(d) { return +this.getAttribute("fill-opacity") || arcVisible(d.target); }) .attr("fill-opacity", d => arcVisible(d.target) ? (d.children ? 0.6 : 0.4) : 0) .attr("pointer-events", d => arcVisible(d.target) ? "auto" : "none") .attrTween("d", d => () => arc(d.current)); label.filter(function(d) { return +this.getAttribute("fill-opacity") || labelVisible(d.target); }).transition(t) .attr("fill-opacity", d => +labelVisible(d.target)) .attrTween("transform", d => () => labelTransform(d.current)); } function arcVisible(d) { return d.y1 <= 3 && d.y0 >= 1 && d.x1 > d.x0; } function labelVisible(d) { return d.y1 <= 3 && d.y0 >= 1 && (d.y1 - d.y0) * (d.x1 - d.x0) > 0.03; } function labelTransform(d) { const x = (d.x0 + d.x1) / 2 * 180 / Math.PI; const y = (d.y0 + d.y1) / 2 * radius; return `rotate(${x - 90}) translate(${y},0) rotate(${x < 180 ? 0 : 180})`; } return svg.node(); } 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 scheme = getChartPropertyValue(currentChartModel.chartPropertiesUsed,"schemeArray"); var singleColor = getChartPropertyValue(currentChartModel.chartPropertiesUsed,"singleColor"); var myPalette=getPaletteArray(scheme,singleColor); var chartType=chartTypes[1]; 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 subtitleText=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"subtitle"); //var measure1Fldname=getChartPropertyValue(currentChartModel.chartPropertiesUsed,measure1Axis); var seriesArray=getEchartSeriesArray(currentChartModel,chartType,orientation,dimension1Axis,measure1Axis,myPalette); //var dimension1Fldname=getChartPropertyValue(currentChartModel.chartPropertiesUsed,dimension1Axis); var option = { dataset: myDataset, /*klappt nicht, noch testen: transfxAxis: { typeorm: { type: 'sort', config: { dimension: "dim_studiengang_fb", order: 'asc' } } ,*/ legend: { show: (getChartPropertyValue(currentChartModel.chartPropertiesUsed,"legendShow")=="false")?false:true, //true type: (getChartPropertyValue(currentChartModel.chartPropertiesUsed,"legend.scroll")=="false")?"plain":"scroll", top:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"legend.top"), left:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"legend.left") }, title: { text: titleText, subtext: subtitleText, left: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"title.left"), //"center", top: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"title.top"), //"top", textStyle: { fontSize: 20 }, subtextStyle: { fontSize: 15 } }, grid: { top: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.top")+"%", bottom: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.bottom")+"%", left: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.left")+"%", right: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.right")+"%" }, tooltip: { trigger: "axis", axisPointer: { type: "shadow" }, /*valueFormatter: (value) => numberFormatter(value,"value")*/ /*valueFormatter: (value) => '$' + value.toFixed(2)*/ /*valueFormatter: (value) => value.toString().replace(",",".")*/ valueFormatter: (value) => value.toLocaleString() }, xAxis: { type:xAxisType, //horizontal oder vertikal name:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"xAxisName"), nameLocation:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"xAxisNameLocation"), //type: 'category', axisLabel: { inside: false, margin: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"padding_x"), fontSize: 12, width:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"width_x"), rotate: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"tickRotate_x"), /*formatter: function (value, index) { return numberFormatter(value,xAxisType); }*/ valueFormatter: (value) => value.toLocaleString() } }, yAxis: { //type:'value', type: yAxisType, name:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"yAxisName"), axisLabel: { inside: false, margin: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"padding_y"), fontSize: 12, width:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"width_y"), rotate: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"tickRotate_y"), distance:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"distance_y"), position:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"position_y"), formatter: (value) => value.toLocaleString() } }, series: seriesArray, color:myPalette }; return option; } function getEchartSeriesArray(currentChartModel,chartType,orientation,dimension1Axis,measure1Axis,myPalette) { var seriesArray= new Array(); for(var k=0;k < currentChartModel.chartElements.length;k++) { var measure1Fldname=getChartElementPropertyValueFromModel(currentChartModel,k+1,measure1Axis); var dimension1Fldname=getChartElementPropertyValueFromModel(currentChartModel,k+1,dimension1Axis); var encodeObj={x:dimension1Fldname,y:measure1Fldname}; var datasource=currentChartModel.dataSources[0].value; var measureCaption=getMetadataOfVizTypeProperty(rsColumnMetaData[datasource],measure1Fldname); if(orientation=="x") encodeObj={y:dimension1Fldname,x:measure1Fldname}; var mySeriesObj={ type: chartType, //bar,line, name:measureCaption, smooth: true, encode: encodeObj, stack:(getChartPropertyValue(currentChartModel.chartPropertiesUsed,"barStacked")=="false")?"":"myStack", barWidth: '30%', showBackground: true, backgroundStyle: { color: '#dfe4f2' }, margin: 50, fontSize: 14, colorBy: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"seriesColorBy"),//'series',// 'data', //color: myPalette, lineStyle: { width: 7 }, label: { show: (getChartPropertyValue(currentChartModel.chartPropertiesUsed,"valueLabelShow")=="false")?false:true, //true fontWeight:'bolder', fontSize: 14, distance:30, //offset:[30, 40], // position:"bottom", /*labelLayout:{}*/ position:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"position_valueLabel"), //"bottom", offset: getOffsetValuelabelArray(getChartPropertyValue(currentChartModel.chartPropertiesUsed,"offset_x_valueLabel"), getChartPropertyValue(currentChartModel.chartPropertiesUsed,"offset_y_valueLabel")), formatter: function (params) { return params.value[params.dimensionNames[params.encode.y[0]]].toLocaleString() } }, labelLayout(params) { return getLabelLayout(chartType,params,orientation) } }; seriesArray.push(mySeriesObj); } return seriesArray; } function getEchartOptionsBarLineSeries(currentChartModel,myDataset,chartType,titleText) { //TODO: bar_x und y abfangen' var chartTypes = chartType.split(/_/); var scheme = getChartPropertyValue(currentChartModel.chartPropertiesUsed,"schemeArray"); var singleColor = getChartPropertyValue(currentChartModel.chartPropertiesUsed,"singleColor"); var myPalette=getPaletteArray(scheme,singleColor); var subtitleText=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"subtitle"); var xAxisType="category"; var yAxisType="value"; var orientation=chartTypes[2]; var seriesFldname=getChartElementPropertyValueFromModel(currentChartModel,1,"stroke"); var seriesArray= new Array(); var i=0; myDataset.source.forEach((row) => { if(i>0) { //Das erste Element ist immer die Serien-Dimension, wird daher übersprungen var mySeriesObj={ type: chartTypes[1], //bar,line, smooth: true, seriesLayoutBy: 'row', emphasis: { focus: 'series' }, stack:"myStack", name:row[0], label: { show: (getChartPropertyValue(currentChartModel.chartPropertiesUsed,"valueLabelShow")=="false")?false:true, //true fontWeight:'bolder', fontSize: 14, distance:30, //offset:[30, 40], // position:"bottom", /*labelLayout:{}*/ position:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"position_valueLabel"), //"bottom", offset: getOffsetValuelabelArray(getChartPropertyValue(currentChartModel.chartPropertiesUsed,"offset_x_valueLabel"), getChartPropertyValue(currentChartModel.chartPropertiesUsed,"offset_y_valueLabel")), } }; seriesArray.push(mySeriesObj); } i++; }); /* var mySeriesObj2={ type: 'line', smooth: true, seriesLayoutBy: 'row', emphasis: { focus: 'series' } }; seriesArray.push(mySeriesObj2); */ var option = { dataset: myDataset, /*klappt nicht, noch testen: transfxAxis: { typeorm: { type: 'sort', config: { dimension: "dim_studiengang_fb", order: 'asc' } } ,*/ legend: { show: (getChartPropertyValue(currentChartModel.chartPropertiesUsed,"legendShow")=="false")?false:true, //true type: (getChartPropertyValue(currentChartModel.chartPropertiesUsed,"legend.scroll")=="false")?"plain":"scroll", top:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"legend.top"), left:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"legend.left") }, title: { text: titleText, subtext: subtitleText, left: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"title.left"), //"center", top: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"title.top"), //"top", textStyle: { fontSize: 20 }, subtextStyle: { fontSize: 15 } }, grid: { top: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.top")+"%", bottom: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.bottom")+"%", left: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.left")+"%", right: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.right")+"%" }, tooltip: { trigger: "axis", axisPointer: { type: "shadow" }, /*valueFormatter: (value) => numberFormatter(value,"value")*/ /*valueFormatter: (value) => '$' + value.toFixed(2)*/ /*valueFormatter: (value) => value.toString().replace(",",".")*/ valueFormatter: (value) => value.toLocaleString() }, xAxis: { type:xAxisType, //horizontal oder vertikal name:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"xAxisName"), //type: 'category', axisLabel: { inside: false, margin: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"padding_x"), fontSize: 12, width:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"width_x"), rotate: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"tickRotate_x"), /*formatter: function (value, index) { return numberFormatter(value,xAxisType); }*/ valueFormatter: (value) => value.toLocaleString() } }, yAxis: { //type:'value', type: yAxisType, name:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"yAxisName"), nameLocation:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"xAxisNameLocation"), axisLabel: { inside: false, margin: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"padding_y"), fontSize: 12, width:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"width_y"), rotate: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"tickRotate_y"), distance:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"distance_y"), position:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"position_y"), formatter: (value) => value.toLocaleString() } }, series: seriesArray, color:myPalette }; return option; } function getOffsetValuelabelArray(xOffset,yOffset) { var offsetArray= new Array(); if(xOffset!="") offsetArray[0]=+xOffset; //String to INT else offsetArray[0]=0; if(yOffset!="") offsetArray[1]=+yOffset; else offsetArray[1]=0; return offsetArray; } /* Labels bei Balkendiagramm je nach Orientierung - horizontal: rechts neben Balken - vertikal: zentriert im Balken */ function getLabelLayout(seriesType,params,orientation) { if(seriesType=="bar") {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'}; } else {//line: return {verticalAlign: 'bottom'}; } } 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 subtitleText=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"subtitle"); var scheme = getChartPropertyValue(currentChartModel.chartPropertiesUsed,"schemeArray"); var myPalette=getPaletteArray(scheme,""); var option = { dataset: { source: myDataset }, title: { text: titleText, subtext: subtitleText, left: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"title.left"), //"center", top: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"title.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 },*/ label: { show: (getChartPropertyValue(currentChartModel.chartPropertiesUsed,"valueLabelShow")=="true")?true:false, //true fontWeight:'bolder', /*distance:10,*/ /* offset:[30, 40]*/ /*labelLayout:{}*/ //distance:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"distance_valueLabel"), //10, //position:getChartPropertyValue(currentChartModel.chartPropertiesUsed,"position_valueLabel"), //"bottom", /*formatter: function (params) { return params.value.toLocaleString() }*/ formatter: '{c}' } /*, labelLayout(params) { return getLabelLayout(chartTypes[1],params,orientation) }*/, fontSize: 12, radius: [getChartPropertyValue(currentChartModel.chartPropertiesUsed,"innerRadius"),getChartPropertyValue(currentChartModel.chartPropertiesUsed,"outerRadius")],// ['30%', '80%'], //1. Parameter inside radius, macht ihn zum Donut. 2.Parameter definiert den Anteil des Kreises am ganzen Viewport" color: myPalette, itemStyle: { borderRadius: (getChartPropertyValue(currentChartModel.chartPropertiesUsed,"cornerRadiusRounded")=="true" ? [20, 5, 5, 10] :[]), //borderRadius: [20, 5, 5, 10], //abgerundete Ecken der Tortenstücke borderColor: '#fff', borderWidth: 2 } } ] }; return option; } function getChartPropertyValue(propArray,propName) { var propertyValue=""; if(propArray) { for (var i=0;i o.name === propName); if(prop && prop.defaultValue!="") { propertyValue=prop.defaultValue; } } return propertyValue; } function getChartElementPropertyValueFromModel(myChartModel,elemID,propUniquename) { //var elemID="1"; var retVal=null; var myChartElem=null; if(myChartModel.chartElements && elemID !=null) { var filtered=myChartModel.chartElements.filter(obj => 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 getPaletteArray(schemeName,singleColor) { var schemeArray=new Array(); if(singleColor=="") { if(schemeName=="") schemeName="D3_Tableau10"; //Default var srcScheme=vizColorSchemes.find(sc => sc.uniquename == schemeName); if(!srcScheme.specifier || srcScheme.specifier=="") { var counter=0; var firstColorCode=""; for (let j = 0; j < vizColorSchemeElements.length; j++) { if(vizColorSchemeElements[j].colorscheme_uniquename == schemeName) { if(firstColorCode=="") firstColorCode=vizColorSchemeElements[j].colorcode; schemeArray[counter]=vizColorSchemeElements[j].colorcode; counter++; } } //vizColorSchemeElements.find(el => el.colorscheme_uniquename == schemeName); if(schemeArray.length==0) { schemeArray[0]=firstColorCode; } } else { //D3 specifier: schemeArray=colorSpecifierToArray(srcScheme.specifier); } } else { schemeArray=[ singleColor ]; } return schemeArray; } function openDashboardTab(tabnr,maskennr,originalStylesheet,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(myForm.elements["tablestylesheet"]) { myForm.elements["tablestylesheet"].value=originalStylesheet; } if(myForm.elements["stylesheet"]) { myForm.elements["stylesheet"].value=originalStylesheet; } myForm.elements["contenttype"].value="text/html"; 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 ; } function closeModalCard(elemId) { var myModalCard=document.getElementById(elemId); myModalCard.classList.remove('is-active'); } function toggleSideBarDiv(mySidebarDivId) { //first close all divs in the sidebar except the one seleced: const allSidebarDivs = document.getElementsByClassName("sidebar"); for (let i = 0; i < allSidebarDivs.length; i++) { if(allSidebarDivs[i].id!=mySidebarDivId) allSidebarDivs[i].style.display="none"; } //now toggle: var myDiv=document.getElementById(mySidebarDivId); if(myDiv.style.display=="block") { myDiv.style.display="none"; myDiv.classList.remove("sidebar"); } else { myDiv.style.display="block"; myDiv.classList.add("sidebar"); } } function prettifyJson(srcCode) { var ret=""; ret=srcCode.replace(/],/g,"],\n"); ret=ret.replace(/},/g,"},\n"); return ret; } function pivotTable1(rsData,rsMetaData,srcColNr) { rsData.forEach((row) => { for (var col in row) { console.log(col +"-"+row[col]); } } ); } function pivotTable(rsData,rsMetaData,srcColNrStart) { var rsDataPivot=new Array(); var nrSourceRows=rsData.length; var nrSouceCols=rsMetaData.length; var rsRow=new Array(); var zs=""; var targetRownr=0; //first line will have headers: var rownr=0; zs+="Zeile|"; rsRow[rownr]="Zeile"; rownr++; rsData.forEach((row) => { var colnr=0; for (var col in row) { if(colnr==srcColNrStart) { zs+=row[col]+"|"; rsRow[rownr]=row[col]; } colnr++; } rownr++; } ); zs +="\n"; targetRownr++; rsDataPivot.push(rsRow); //now the data: var metaDataColnr=0; rsMetaData.forEach((col) => { if(metaDataColnr>srcColNrStart && col.colcaption.trim()!="") { //start a new row: var rsRow=new Array(); var colname=col.colname; zs+=col.colcaption +"|"; rsRow[0]=col.colcaption; var targetColnr=1; var rownr=0; rsData.forEach((row) => { var colnr=0; for (var col in row) { if(colnr==metaDataColnr) { zs+=row[col]+"|"; rsRow[targetColnr]=row[col]; targetColnr++; } colnr++; }; rownr++; }); zs+="\n"; rsDataPivot.push(rsRow); } metaDataColnr++; }); //alert(zs); /* for(var row=0;row < nrSourceRows;row++) { rsRow[row]=rsData[row][srcColNr]; } rsDataPivot.push(rsRow); //Now line 2 upwards: rsData.forEach((row) => { for (var col in row) { console.log(col +"-"+row[col]); } } ); } for(var col=srcColNr+1;col < nrSouceCols;col++) { var rsRow=new Array(); var srcColCounter=0; //first targetcolumn has name rsRow[0]=rsMetaData[col]; for(var row=0;row < nrSourceRows;row++) { rsRow[row+1]=rsData[row][col]; } rsDataPivot.push(rsRow); } console.log(rsDataPivot); */ return rsDataPivot; } /* color schemes from d3js */ function colorSpecifierToArray(specifier) { var n = specifier.length / 6 | 0, colors = new Array(n), i = 0; while (i < n) colors[i] = "#" + specifier.slice(i * 6, ++i * 6); return colors; }