|
|
/* SuperX-VIZ Modul (c) 2023 Daniel Quathamer */ |
|
|
|
|
|
function chartModel(id,name,renderer,datasources) |
|
|
{ |
|
|
this.version="0.2b"; |
|
|
this.id=id; |
|
|
this.name=name; |
|
|
this.renderer=renderer; |
|
|
this.dataSources=datasources; |
|
|
//this.globalProperties=globalproperties; |
|
|
this.targetDiv=""; //only for d3 |
|
|
this.chartElements=new Array(); |
|
|
this.chartPropertiesUsed=new Array(); |
|
|
this.dataTransformation=new Array(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
function possibleVizType(nr,value,name,explanation,isDefault ) |
|
|
{ |
|
|
this.nr=nr; |
|
|
this.value=value; |
|
|
this.name=name; |
|
|
this.explanation=explanation; |
|
|
this.isDefault=isDefault; |
|
|
|
|
|
} |
|
|
|
|
|
function usedVizType(nr,vizTypeUniquename,caption,datasource ) |
|
|
{ |
|
|
this.nr=nr; |
|
|
this.vizTypeUniquename=vizTypeUniquename; |
|
|
this.caption=caption; |
|
|
this.datasource=datasource; |
|
|
this.elementTypeProperties=new Array(); |
|
|
} |
|
|
|
|
|
function usedVizProperty(name,vizPropertyVariablename,propertyValue,propUnit ) |
|
|
{ |
|
|
this.name=name; |
|
|
this.vizPropertyVariablename=vizPropertyVariablename; |
|
|
this.propertyValue=propertyValue; |
|
|
this.propUnit=propUnit; |
|
|
|
|
|
} |
|
|
function usedVizTypeProperty(nr,vizTypePropertyUniquename,caption,propertyValue ) |
|
|
{ |
|
|
this.nr=nr; |
|
|
this.vizTypePropertyUniquename=vizTypePropertyUniquename; |
|
|
this.caption=caption; |
|
|
this.propertyValue=propertyValue; |
|
|
|
|
|
} |
|
|
function dataTransformationCol(tableId,colname,colfunction) |
|
|
{ |
|
|
this.tableId=tableId; |
|
|
this.colname=colname; |
|
|
this.colfunction=colfunction; |
|
|
|
|
|
} |
|
|
function d3dataRow(nr,dimension1,dimension2,measure1 ) |
|
|
{ |
|
|
this.nr=nr; |
|
|
this.dimension1=dimension1; |
|
|
this.dimension2=dimension2; |
|
|
this.measure1=measure1; |
|
|
|
|
|
} |
|
|
|
|
|
function selectionRowMetaData(nr,targetColumn,colname,colcaption,coltype,colfunction) |
|
|
{ |
|
|
this.nr=nr; |
|
|
this.targetColumn=targetColumn; |
|
|
this.colname=colname; |
|
|
this.colcaption=colcaption; |
|
|
this.coltype=coltype; |
|
|
this.colfunction=colfunction; |
|
|
} |
|
|
|
|
|
function selectionPropertyValue(nr,name,value,isDefault ) |
|
|
{ |
|
|
this.nr=nr; |
|
|
this.name=name; |
|
|
this.value=value; |
|
|
this.isDefault=isDefault; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function dimFunction(nr,name,value,isDefault ) |
|
|
{ |
|
|
this.nr=nr; |
|
|
this.name=name; |
|
|
this.value=value; |
|
|
this.isDefault=isDefault; |
|
|
|
|
|
} |
|
|
function dimensionProperty(name,caption,explanation,isMeasure,isMandatory,datasource) |
|
|
{ |
|
|
this.name=name; |
|
|
this.caption=caption; |
|
|
this.isMeasure=isMeasure; |
|
|
this.isMandatory=isMandatory; |
|
|
this.explanation=explanation; |
|
|
this.datasource=datasource; |
|
|
this.getValueResultset = function () { |
|
|
var valueOptions=[]; |
|
|
var optionCounter=0; |
|
|
//selectionRsMetaData=fillSelectionResultMetaData(); |
|
|
//console.log("felder"+selectionRsMetaData.length); |
|
|
var isDefault=false; |
|
|
for(var j=0;j < rsColumnMetaData[datasource].length;j++) |
|
|
{ |
|
|
if(rsColumnMetaData[datasource][j].colcaption.trim() !="" |
|
|
//&& ( |
|
|
// isMeasure==false || rsColumnMetaData[datasource][j].coltype == 4 || rsColumnMetaData[datasource][j].coltype == 3) |
|
|
// |
|
|
) |
|
|
{ |
|
|
//console.log("feld "+rsColumnMetaData[j].nr+selectionRsMetaData[j].targetColumn); |
|
|
var o=new selectionPropertyValue(rsColumnMetaData[datasource][j].nr,rsColumnMetaData[datasource][j].colcaption,rsColumnMetaData[datasource][j].colname,isDefault); |
|
|
valueOptions[optionCounter]=o; |
|
|
optionCounter++; |
|
|
if(isDefault) |
|
|
isDefault=false; |
|
|
} |
|
|
} |
|
|
return valueOptions; |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
function selectionProperty(name,caption,isDynamic,isMeasure,isMandatory,staticValues,defaultValue,optionalFunction) |
|
|
{ |
|
|
/*OBSOLETE*/ |
|
|
this.name=name; |
|
|
this.caption=caption; |
|
|
this.isDynamic=isDynamic; |
|
|
this.isMeasure=isMeasure; |
|
|
this.staticValues=staticValues; |
|
|
this.isMandatory=isMandatory; |
|
|
this.defaultValue=defaultValue; |
|
|
this.optionalFunction=optionalFunction; |
|
|
this.getValueResultset = function () { |
|
|
var valueOptions=[]; |
|
|
var optionCounter=0; |
|
|
if(isDynamic) |
|
|
{ |
|
|
for(var j=0;j < rsMetaData.length;j++) |
|
|
{ |
|
|
var isDefault=false; |
|
|
if(rsMetaData[j].colcaption.trim() !="" && |
|
|
(isMeasure==false || rsMetaData[j].coltype == 4 || rsMetaData[j].coltype == 3) |
|
|
) |
|
|
{ |
|
|
if(rsMetaData[j].colcaption==defaultValue) |
|
|
isDefault=true; |
|
|
var o=new selectionPropertyValue(rsMetaData[j].nr,rsMetaData[j].colcaption,rsMetaData[j].colname,isDefault); |
|
|
valueOptions[optionCounter]=o; |
|
|
optionCounter++; |
|
|
} |
|
|
} |
|
|
} |
|
|
else |
|
|
{ |
|
|
var staticValuesArray = staticValues.split(/\|/); |
|
|
for(var k=0;k < staticValuesArray.length;k++) |
|
|
{ |
|
|
var isDefault=false; |
|
|
if(rsMetaData[j].colcaption==defaultValue) |
|
|
isDefault=true; |
|
|
var o=new selectionPropertyValue(k,staticValuesArray[k],staticValuesArray[k],isDefault); |
|
|
valueOptions[k]=o; |
|
|
} |
|
|
} |
|
|
return valueOptions; |
|
|
} |
|
|
} |
|
|
|
|
|
/* Render Model:*/ |
|
|
function renderChartSVGFromModel(currentChartModel,targetDiv) { |
|
|
//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[myFunc.tableId].length;row++) |
|
|
{ |
|
|
rs[myFunc.tableId][row][myFunc.colname]=applyFunction(rs[myFunc.tableId][row][myFunc.colname],myFunc.colfunction); |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
switch (currentChartModel.renderer) { |
|
|
case "plot": |
|
|
renderChartSVGfromModelWithPlot(currentChartModel,targetDiv); |
|
|
break; |
|
|
case "d3js": |
|
|
renderChartSVGWithD3(currentChartModel,targetDiv); |
|
|
break; |
|
|
default: |
|
|
alert("No renderer"); |
|
|
break; |
|
|
} |
|
|
return true; |
|
|
} |
|
|
function renderChartSVGfromModelWithPlot (currentChartModel,targetDiv) |
|
|
{ |
|
|
console.log("using Plot"); |
|
|
var myOptions=new Object; |
|
|
//myOptions.marks=new Array(); |
|
|
//myOptions.sort=new Array(); |
|
|
|
|
|
myOptions=getPlotOptionsObj(currentChartModel.chartPropertiesUsed); |
|
|
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]); |
|
|
/*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) |
|
|
{ |
|
|
console.log("using D3JS"); |
|
|
var svgD3=new Object; |
|
|
for(var k=0;k< currentChartModel.chartElements.length;k++) |
|
|
{ |
|
|
svgD3=renderChartElementWithD3(currentChartModel,k,targetDiv); |
|
|
} |
|
|
|
|
|
|
|
|
//document.getElementById(targetDiv).innerHTML=""; |
|
|
//document.getElementById(targetDiv).appendChild(svgD3); |
|
|
} |
|
|
|
|
|
/*Transfer form to model: */ |
|
|
function updateChartModel() |
|
|
{ |
|
|
|
|
|
var myChartPropertiesUsed=new Array(); |
|
|
//first empty properties: |
|
|
/*for(var k=0;k< myChartModel.chartPropertiesUsed.length;k++) |
|
|
{ |
|
|
myChartModel.chartPropertiesUsed[k].pop(); |
|
|
}*/ |
|
|
|
|
|
if(document.getElementById("chartName").value=="") |
|
|
document.getElementById("chartName").value=vizInitialName; |
|
|
var chartName=document.getElementById("chartName").value; |
|
|
//myChartModel.options.caption=chartName; |
|
|
if(myChartModel.renderer=="") |
|
|
myChartModel.renderer=document.getElementById("fldVizRenderer").value; |
|
|
var myCaption=new usedVizProperty("caption","caption",chartName); |
|
|
myChartPropertiesUsed.push(myCaption); |
|
|
//var myForm=document.forms["chartPropertiesForm"]; |
|
|
for(var k=0;k < commonChartProperties.length;k++) |
|
|
{ |
|
|
if(getCommonChartProperty(commonChartProperties[k].name)!="") |
|
|
{ |
|
|
var myProp=new usedVizProperty(commonChartProperties[k].name,commonChartProperties[k].variableName,getCommonChartProperty(commonChartProperties[k].name),commonChartProperties[k].propUnit); |
|
|
myChartPropertiesUsed.push(myProp); |
|
|
} |
|
|
} |
|
|
|
|
|
//first Collect all groups: |
|
|
|
|
|
myChartModel.chartPropertiesUsed=myChartPropertiesUsed; |
|
|
|
|
|
//Update the source Code TEXTAREA: |
|
|
updateChartModelCode(myChartModel); |
|
|
return myChartModel; |
|
|
|
|
|
} |
|
|
function getPlotOptionsObj(chartPropertiesUsed) |
|
|
{ |
|
|
var commonChartPropertyGroups=[]; |
|
|
var previousGroup=""; |
|
|
var optionsString="{"; |
|
|
optionsString+="\"caption\":\""+getChartPropertyValue(chartPropertiesUsed,"caption")+"\""; |
|
|
|
|
|
for(var k=0;k < commonChartProperties.length;k++) |
|
|
{ |
|
|
var groupVariableName=commonChartProperties[k].groupVariableName; |
|
|
if(groupVariableName!="" |
|
|
&& groupVariableName != previousGroup) |
|
|
{ |
|
|
var newcommonChartPropertyGroup = new commonChartPropertyGroup(commonChartProperties[k].groupCaption,commonChartProperties[k].groupUniquename,groupVariableName); |
|
|
commonChartPropertyGroups.push(newcommonChartPropertyGroup); |
|
|
} |
|
|
previousGroup=groupVariableName; |
|
|
} |
|
|
//Now create options Str with all groups: |
|
|
var textDelim=""; |
|
|
for(var i=0;i < commonChartPropertyGroups.length;i++) |
|
|
{ |
|
|
if(commonChartPropertyGroups[i].groupVariableName!="layout") |
|
|
optionsString+=",\""+commonChartPropertyGroups[i].groupVariableName+"\":{\"dummy1\":1"; |
|
|
for(var k=0;k < commonChartProperties.length;k++) |
|
|
{ |
|
|
|
|
|
if(commonChartProperties[k].groupVariableName==commonChartPropertyGroups[i].groupVariableName |
|
|
&& commonChartProperties[k].variableName!="" |
|
|
&& getChartPropertyValue(chartPropertiesUsed,commonChartProperties[k].name)!="") |
|
|
{ |
|
|
textDelim=(commonChartProperties[k].propValueType=="string" || commonChartProperties[k].propUnit!="")?"\"":""; |
|
|
optionsString+=",\""+commonChartProperties[k].variableName+"\":"+textDelim+getChartPropertyValue(chartPropertiesUsed,commonChartProperties[k].name)+textDelim; |
|
|
} |
|
|
} |
|
|
if(commonChartPropertyGroups[i].groupVariableName!="layout") |
|
|
optionsString+=" }"; //close tag |
|
|
} |
|
|
|
|
|
optionsString+= ", \"marks\":[]"; |
|
|
optionsString+=" }"; //close tag |
|
|
var chartOptions=JSON.parse(optionsString); |
|
|
return chartOptions; |
|
|
|
|
|
} |
|
|
function renderChart(chartDiv,currentChartModel) |
|
|
{ |
|
|
|
|
|
/*if(document.getElementById("chartName").value=="") |
|
|
document.getElementById("chartName").value=vizInitialName;*/ |
|
|
if(currentChartModel.chartElements.length>0 && currentChartModel.chartElements[0]) |
|
|
{ |
|
|
renderChartSVGFromModel(currentChartModel,chartDiv); |
|
|
} |
|
|
else |
|
|
document.getElementById(chartDiv).innerHTML="<svg style=\"width:100%;height: auto;\" viewBox=\"0 0 800 600\" width=\"800\" height=\"600\">"+ |
|
|
"<rect x=\"0\" y=\"0\" width=\"800\" height=\"450\" fill=\"#cccccc\"></rect></svg>"; |
|
|
// |
|
|
|
|
|
} |
|
|
|
|
|
function prepareSelectionForm() |
|
|
{ |
|
|
var selectionProperties=[]; |
|
|
|
|
|
var myProp= new selectionProperty("dimension1","Dimension 1",true,false,true,null,null,true); |
|
|
selectionProperties[0]=myProp; |
|
|
var myProp= new selectionProperty("dimension2","Dimension 2",true,false,false,null,null,true); |
|
|
selectionProperties[1]=myProp; |
|
|
var myProp= new selectionProperty("measure1","Maß",true,true,true,null,null,true); |
|
|
selectionProperties[2]=myProp; |
|
|
|
|
|
return selectionProperties; |
|
|
} |
|
|
|
|
|
function createChartElementConfig1Form(renderer,elemID) |
|
|
{ |
|
|
//first empty form: |
|
|
var formChartElementConfig1=document.getElementById("ChartElementConfig1Div"); |
|
|
while (formChartElementConfig1.firstChild) { |
|
|
formChartElementConfig1.removeChild(formChartElementConfig1.firstChild); |
|
|
} |
|
|
|
|
|
//First Datasource: |
|
|
const elementDatasourceDiv=document.createElement("div"); |
|
|
const fieldDatasourceElem = document.createElement("div"); |
|
|
fieldDatasourceElem.classList.add("field"); |
|
|
fieldDatasourceElem.classList.add("is-grouped"); |
|
|
//label: |
|
|
const labelDatasourceElem = document.createElement("div"); |
|
|
labelDatasourceElem.classList.add("label-container"); |
|
|
const labelDatasource = document.createElement("label"); |
|
|
labelDatasource.classList.add("label"); |
|
|
labelDatasource.classList.add("is-required"); |
|
|
labelDatasource.classList.add("is-small"); |
|
|
labelDatasource.classList.add("has-tooltip-right"); |
|
|
labelDatasource.setAttribute("data-tooltip","Datenquelle für das Diagrammelement"); |
|
|
|
|
|
const textnode = document.createTextNode("Datenquelle"); |
|
|
labelDatasource.appendChild(textnode); |
|
|
labelDatasourceElem.appendChild(labelDatasource); |
|
|
fieldDatasourceElem.appendChild(labelDatasourceElem); |
|
|
const inpElemId = document.createElement("input"); |
|
|
inpElemId.name="chartElementID"; |
|
|
inpElemId.id="chartElementID"; |
|
|
inpElemId.type="hidden"; |
|
|
|
|
|
|
|
|
const selDatasourceElem = document.createElement("select"); |
|
|
selDatasourceElem.name="chartElementDatasource"; |
|
|
selDatasourceElem.id="chartElementDatasource"; |
|
|
selDatasourceElem.classList.add("select"); |
|
|
selDatasourceElem.classList.add("is-small"); |
|
|
|
|
|
selDatasourceElem.onchange= function () { |
|
|
createChartElementsConfig2Form(renderer); |
|
|
}; |
|
|
fillSelectOptions(selDatasourceElem,rsTableMetaData,true); |
|
|
fieldDatasourceElem.appendChild(selDatasourceElem); |
|
|
fieldDatasourceElem.appendChild(inpElemId); |
|
|
|
|
|
elementDatasourceDiv.appendChild(fieldDatasourceElem); |
|
|
formChartElementConfig1.appendChild(elementDatasourceDiv); |
|
|
|
|
|
//Then vizType: |
|
|
const elementVizTypeDiv=document.createElement("div"); |
|
|
const fieldVizTypeElem = document.createElement("div"); |
|
|
fieldVizTypeElem.classList.add("field"); |
|
|
fieldVizTypeElem.classList.add("is-grouped"); |
|
|
//label: |
|
|
const labelVizTypeElem = document.createElement("div"); |
|
|
labelVizTypeElem.classList.add("label-container"); |
|
|
const labelVizType = document.createElement("label"); |
|
|
labelVizType.classList.add("label"); |
|
|
labelVizType.classList.add("is-required"); |
|
|
labelVizType.classList.add("is-small"); |
|
|
labelVizType.classList.add("has-tooltip-right"); |
|
|
labelVizType.setAttribute("data-tooltip","Art des Grafikelements"); |
|
|
|
|
|
const textnodeVizType = document.createTextNode("Grafikelement-Typ"); |
|
|
labelVizType.appendChild(textnodeVizType); |
|
|
labelVizTypeElem.appendChild(labelVizType); |
|
|
fieldVizTypeElem.appendChild(labelVizTypeElem); |
|
|
|
|
|
const selVizTypeElem = document.createElement("select"); |
|
|
selVizTypeElem.name="chartElementVizType"; |
|
|
selVizTypeElem.id="chartElementVizType"; |
|
|
selVizTypeElem.classList.add("select"); |
|
|
selVizTypeElem.classList.add("is-small"); |
|
|
selVizTypeElem.onchange= function () { |
|
|
createChartElementsConfig2Form(renderer); |
|
|
}; |
|
|
fillSelectOptions(selVizTypeElem,getPossibleVizTypes(renderer),false); |
|
|
fieldVizTypeElem.appendChild(selVizTypeElem); |
|
|
elementVizTypeDiv.appendChild(fieldVizTypeElem); |
|
|
|
|
|
formChartElementConfig1.appendChild(elementVizTypeDiv); |
|
|
|
|
|
} |
|
|
function createChartElementsConfig2Form(renderer) |
|
|
{ |
|
|
var dataSource=document.getElementById("chartElementDatasource").value; |
|
|
var vizType=document.getElementById("chartElementVizType").value; |
|
|
//now Elements: |
|
|
var formChartElementConfig2Div=document.getElementById("ChartElementConfig2Div"); |
|
|
while (formChartElementConfig2Div.firstChild) { |
|
|
formChartElementConfig2Div.removeChild(formChartElementConfig2Div.firstChild); |
|
|
} |
|
|
|
|
|
const elementDivBox = document.createElement("div"); |
|
|
//first only Dimensions and measures: |
|
|
for(var k=0;k < vizTypeProperties.length;k++) |
|
|
{ |
|
|
if(vizType==vizTypeProperties[k].typeUniquename && |
|
|
(vizTypeProperties[k].groupUniquename=="CATEGORY" |
|
|
|| vizTypeProperties[k].groupUniquename=="MEASURE" |
|
|
) |
|
|
) |
|
|
elementDivBox.appendChild(renderDimensionField(vizTypeProperties[k],dataSource)); |
|
|
} |
|
|
const saveBtnDiv = document.createElement("div"); |
|
|
const saveBtn = document.createElement("input"); |
|
|
saveBtn.type="BUTTON"; |
|
|
saveBtn.value="Übernehmen"; |
|
|
saveBtn.classList.add("button"); |
|
|
saveBtn.classList.add("is-small"); |
|
|
|
|
|
saveBtn.onclick =function() { |
|
|
saveChartElementConfig() |
|
|
} |
|
|
saveBtnDiv.appendChild(saveBtn); |
|
|
elementDivBox.appendChild(saveBtnDiv); |
|
|
|
|
|
formChartElementConfig2Div.appendChild(elementDivBox); |
|
|
|
|
|
/*columnsDiv.appendChild(columnDiv); |
|
|
//title |
|
|
const columnDivTitle = document.createElement("div"); |
|
|
columnDivTitle.classList.add("column"); |
|
|
columnDivTitle.classList.add("is-narrow"); |
|
|
const columnDivBoxTitle = document.createElement("div"); |
|
|
columnDivBoxTitle.classList.add("box"); |
|
|
columnDivBoxTitle.style="width: 500px"; |
|
|
for(var k=0;k < myCommonChartProperties.length;k++) |
|
|
{ |
|
|
if(myCommonChartProperties[k].name=="caption") |
|
|
columnDivBoxTitle.appendChild(renderChartPropertyField(myCommonChartProperties[k])); |
|
|
} |
|
|
|
|
|
columnDivTitle.appendChild(columnDivBoxTitle); |
|
|
columnsDiv.appendChild(columnDivTitle); |
|
|
myForm.appendChild(columnsDiv); |
|
|
*/ |
|
|
} |
|
|
|
|
|
function saveChartElementConfig() |
|
|
{ |
|
|
var elemID=document.getElementById("chartElementID").value; |
|
|
var vizTypeUniquename=document.getElementById("chartElementVizType").value; |
|
|
var datasource=document.getElementById("chartElementDatasource").value; |
|
|
|
|
|
if(elemID=="") |
|
|
elemID=0; |
|
|
|
|
|
var myVizType=new usedVizType(elemID,vizTypeUniquename,vizTypeUniquename,datasource); //nr,vizTypeUniquename,caption,datasource |
|
|
var propertyCounter=0; |
|
|
for(var k=0;k < vizTypeProperties.length;k++) |
|
|
{ |
|
|
if(vizTypeUniquename==vizTypeProperties[k].typeUniquename |
|
|
&& document.getElementById(vizTypeProperties[k].propUniquename) |
|
|
&& document.getElementById(vizTypeProperties[k].propUniquename).value !="") |
|
|
{ |
|
|
var myUsedVizTypeProperty=new usedVizTypeProperty(propertyCounter,vizTypeProperties[k].propUniquename, vizTypeProperties[k].caption,document.getElementById(vizTypeProperties[k].propUniquename).value); //))nr,vizTypePropertyUniquename,caption,propertyValue ) |
|
|
myVizType.elementTypeProperties.push(myUsedVizTypeProperty); |
|
|
} |
|
|
} |
|
|
//myVizType.elementTypeProperties=null; |
|
|
//TODO: Existenz abfangen, hier wird einfach hinzugefügt: |
|
|
myChartModel.chartElements.push(myVizType); |
|
|
//Reset Elements Form |
|
|
elemID++; |
|
|
document.getElementById("chartElementID").value=elemID; |
|
|
document.getElementById("chartElementVizType").value=""; |
|
|
var formChartElementConfig2Div=document.getElementById("ChartElementConfig2Div"); |
|
|
while (formChartElementConfig2Div.firstChild) { |
|
|
formChartElementConfig2Div.removeChild(formChartElementConfig2Div.firstChild); |
|
|
} |
|
|
document.getElementById("vizElementCounter").value=myChartModel.chartElements.length; |
|
|
renderChart('chartDiv',myChartModel); |
|
|
|
|
|
/*var marksArray=new Array(); |
|
|
marksArray[elemID]=Plot.barX(rs_table0, |
|
|
{ |
|
|
x: "gesamt", |
|
|
y: "eintrag", |
|
|
fill: "blue" |
|
|
} |
|
|
); |
|
|
chartOptions["marks"].push(marksArray);*/ |
|
|
|
|
|
} |
|
|
function removeChartElementConfig() |
|
|
{ |
|
|
|
|
|
var propertyCounter=myChartModel.chartElements.length; |
|
|
if(propertyCounter>0) |
|
|
{ |
|
|
var elemID=myChartModel.chartElements[propertyCounter-1].nr; |
|
|
|
|
|
/*var filtered=myChartModel.chartElements.filter(obj => obj.nr !== propertyCounter-1); |
|
|
myChartModel.chartElements=filtered;*/ |
|
|
myChartModel.chartElements.pop(); |
|
|
elemID--; |
|
|
if(document.getElementById("chartElementID")) |
|
|
document.getElementById("chartElementID").value=elemID; |
|
|
document.getElementById("vizElementCounter").value=myChartModel.chartElements.length; |
|
|
renderChart('chartDiv',myChartModel); |
|
|
} |
|
|
} |
|
|
|
|
|
function resetChartPropertiesForm(chosenRenderer) |
|
|
{ |
|
|
myChartModel=new chartModel(1,"",document.getElementById("fldVizRenderer").value,rsTableMetaData); |
|
|
renderChart('chartDiv',myChartModel); |
|
|
//Show Plot Code if renderer =plot: |
|
|
var myDiv=document.getElementById("plotCodeDiv"); |
|
|
if(chosenRenderer=="plot") |
|
|
myDiv.style.display="block"; |
|
|
else |
|
|
myDiv.style.display="none"; |
|
|
|
|
|
return true; |
|
|
} |
|
|
function getPossibleVizTypes(renderer) |
|
|
{ |
|
|
|
|
|
var possibleVizTypes=new Array(); |
|
|
for(var k=0;k < vizTypes.length;k++) |
|
|
{ |
|
|
if(vizTypes[k].rendererUniquename==renderer) |
|
|
{ |
|
|
var newVizType = new possibleVizType( //nr,value,name,explanation,isDefault |
|
|
k,vizTypes[k].uniquename,vizTypes[k].caption,'',false); |
|
|
possibleVizTypes.push(newVizType); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
return possibleVizTypes; |
|
|
} |
|
|
function fillDimensionProperty(vizTypeProperty,datasource) |
|
|
{ |
|
|
var isMeasure=(vizTypeProperty.groupUniquename=="MEASURE")?true:false; |
|
|
var myProp= new dimensionProperty(vizTypeProperty.propUniquename,vizTypeProperty.caption,vizTypeProperty.explanation,isMeasure,vizTypeProperty.isMandatory,datasource); |
|
|
|
|
|
return myProp; |
|
|
} |
|
|
function showChartPropertiesFormDiv(formDiv,formElementsDiv,renderer) |
|
|
{ |
|
|
var myDiv=document.getElementById(formDiv); |
|
|
switch (formDiv) |
|
|
{ |
|
|
case "generalChartPropertiesFormDiv": |
|
|
renderGeneralChartPropertiesForm(formElementsDiv,commonChartProperties,renderer); |
|
|
break; |
|
|
case "ChartElementDiv": |
|
|
break; |
|
|
default: |
|
|
//do nothing |
|
|
break; |
|
|
} |
|
|
|
|
|
|
|
|
if(myDiv.style.display=="block") |
|
|
myDiv.style.display="none"; |
|
|
else |
|
|
myDiv.style.display="block"; |
|
|
|
|
|
} |
|
|
|
|
|
function showSaveChartFormDiv(formDiv,renderer) |
|
|
{ |
|
|
var myDiv=document.getElementById(formDiv); |
|
|
|
|
|
if(myDiv.style.display=="block") |
|
|
myDiv.style.display="none"; |
|
|
else |
|
|
myDiv.style.display="block"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
function prepareForm(vizTypeUniquename,vizTypeProperties) |
|
|
{ |
|
|
var chartProperties=[]; |
|
|
var propertyCounter=0; |
|
|
for(var k=0;k < vizTypeProperties.length;k++) |
|
|
{ |
|
|
if(vizTypeUniquename==vizTypeProperties[k].typeUniquename) |
|
|
{ |
|
|
var isMeasure=(vizTypeProperties[k].groupUniquename=="MEASURE")?true:false; |
|
|
var myProp= new dimensionProperty(vizTypeProperties[k].propUniquename,vizTypeProperties[k].caption,vizTypeProperties[k].explanation,isMeasure,vizTypeProperties[k].isMandatory); |
|
|
chartProperties.push(myProp); |
|
|
propertyCounter++; |
|
|
} |
|
|
} |
|
|
return chartProperties; |
|
|
} |
|
|
/* |
|
|
function prepareBarXForm() |
|
|
{ |
|
|
var chartProperties=[]; |
|
|
var propertyCounter=0; |
|
|
var myProp= new dimensionProperty("viz_dimension1","Kategorie-Dimension",false,true); |
|
|
chartProperties[0]=myProp; |
|
|
var myProp= new dimensionProperty("viz_measure1","Maß",true,true); |
|
|
chartProperties[1]=myProp; |
|
|
|
|
|
return chartProperties; |
|
|
} |
|
|
|
|
|
function prepareBarYForm() |
|
|
{ |
|
|
var chartProperties=[]; |
|
|
var propertyCounter=0; |
|
|
var myProp= new dimensionProperty("viz_dimension1","Kategorie-Dimension",true,false,true,null,null,true); |
|
|
chartProperties[0]=myProp; |
|
|
var myProp= new dimensionProperty("viz_dimension2","Serien-Dimension",true,false,false,null,null,true); |
|
|
chartProperties[1]=myProp; |
|
|
var myProp= new dimensionProperty("viz_measure1","Maß",true,true,true,null,null,true); |
|
|
chartProperties[2]=myProp; |
|
|
|
|
|
return chartProperties; |
|
|
} |
|
|
|
|
|
function prepareLineForm() |
|
|
{ |
|
|
var chartProperties=[]; |
|
|
var propertyCounter=0; |
|
|
var myProp= new dimensionProperty("viz_dimension1","Kategorie-Dimension",true,false,true,null,null,true); |
|
|
chartProperties[0]=myProp; |
|
|
var myProp= new dimensionProperty("viz_dimension2","Serien-Dimension",true,false,false,null,null,true); |
|
|
chartProperties[1]=myProp; |
|
|
var myProp= new dimensionProperty("viz_measure1","Maß",true,true,true,null,null,true); |
|
|
chartProperties[2]=myProp; |
|
|
|
|
|
return chartProperties; |
|
|
} |
|
|
|
|
|
function prepareLineForm_alt() |
|
|
{ |
|
|
var chartProperties=[]; |
|
|
var propertyCounter=0; |
|
|
var myProp= new dimensionProperty("dimension1","X-Achse",true,false,true,null,null,true); |
|
|
chartProperties[0]=myProp; |
|
|
var myProp= new dimensionProperty("measure1","Y-Achse",true,true,true,null,null,true); |
|
|
chartProperties[1]=myProp; |
|
|
|
|
|
return chartProperties; |
|
|
} |
|
|
*/ |
|
|
function fillDataTransformationForm(formDiv,tableId) |
|
|
{ |
|
|
/* OBSOLETE*/ |
|
|
formDivElem=document.getElementById(formDiv); |
|
|
if(formDivElem.style.display=="none") |
|
|
{ |
|
|
while (formDivElem.firstChild) { |
|
|
formDivElem.removeChild(formDivElem.firstChild); |
|
|
} |
|
|
|
|
|
const elementDivBox = document.createElement("div"); |
|
|
|
|
|
for(var k=0;k < rsColumnMetaData[tableId].length;k++) |
|
|
{ |
|
|
const fieldElem = document.createElement("div"); |
|
|
fieldElem.classList.add("field"); |
|
|
fieldElem.classList.add("is-grouped"); |
|
|
//label: |
|
|
const labelElem = document.createElement("div"); |
|
|
labelElem.classList.add("label-container"); |
|
|
const label = document.createElement("label"); |
|
|
label.classList.add("label"); |
|
|
label.classList.add("is-required"); |
|
|
label.classList.add("is-small"); |
|
|
label.classList.add("has-tooltip-right"); |
|
|
//label.setAttribute("data-tooltip",dimensionProperty.explanation); |
|
|
|
|
|
const textnode = document.createTextNode(rsColumnMetaData[tableId][k].colcaption); |
|
|
label.appendChild(textnode); |
|
|
labelElem.appendChild(label); |
|
|
fieldElem.appendChild(labelElem); |
|
|
//TODO: Funktionen |
|
|
//input: |
|
|
const inputFieldElem = document.createElement("div"); |
|
|
inputFieldElem.classList.add("field"); |
|
|
inputFieldElem.classList.add("is-active"); |
|
|
const inputSelectElem = document.createElement("div"); |
|
|
inputSelectElem.classList.add("select"); |
|
|
inputSelectElem.classList.add("is-small"); |
|
|
//inputSelectElem.classList.add("is-fullwidth"); |
|
|
|
|
|
const selElem = document.createElement("select"); |
|
|
selElem.name=rsColumnMetaData[tableId][k].name+"_fn"; |
|
|
selElem.id=rsColumnMetaData[tableId][k].name+"_fn"; |
|
|
var dimFunctions=[]; |
|
|
var myFunction= new dimFunction(0,"Wort 1 ans Ende","switchWord1and2ff",false); |
|
|
dimFunctions[0]=myFunction; |
|
|
var myFunction= new dimFunction(1,"Nur Wort 1","justWord1",false); |
|
|
dimFunctions[1]=myFunction; |
|
|
var myFunction= new dimFunction(2,"Abkürzen (20)","abbreviate",false); |
|
|
dimFunctions[2]=myFunction; |
|
|
|
|
|
fillSelectOptions(selElem,dimFunctions,false); |
|
|
inputSelectElem.appendChild(selElem); |
|
|
inputFieldElem.appendChild(inputSelectElem); |
|
|
fieldElem.appendChild(inputFieldElem); |
|
|
elementDivBox.appendChild(fieldElem); |
|
|
|
|
|
} |
|
|
formDivElem.appendChild(elementDivBox); |
|
|
formDivElem.style.display="block"; |
|
|
} |
|
|
else |
|
|
formDivElem.style.display="none"; |
|
|
|
|
|
} |
|
|
|
|
|
function fillDataSelectionForm(formDiv,tableId) |
|
|
{ |
|
|
/* OBSOLETE*/ |
|
|
formDivElem=document.getElementById(formDiv); |
|
|
if(formDivElem.style.display=="none") |
|
|
{ |
|
|
var selectionProperties=[]; |
|
|
var dimFunctions=[]; |
|
|
var myFunction= new dimFunction(0,"Wort 1 ans Ende","switchWord1and2ff",false); |
|
|
dimFunctions[0]=myFunction; |
|
|
var myFunction= new dimFunction(1,"Nur Wort 1","justWord1",false); |
|
|
dimFunctions[1]=myFunction; |
|
|
var myFunction= new dimFunction(2,"Abkürzen (20)","abbreviate",false); |
|
|
dimFunctions[2]=myFunction; |
|
|
|
|
|
selectionProperties=prepareSelectionForm(); |
|
|
for(var k=0;k < selectionProperties.length;k++) |
|
|
{ |
|
|
fillSelectOptions(document.getElementById(selectionProperties[k].name),selectionProperties[k].getValueResultset(),selectionProperties[k].isMandatory); |
|
|
if(selectionProperties[k].optionalFunction) |
|
|
{ |
|
|
var fnSelElem = document.getElementById(selectionProperties[k].name+"_fn"); |
|
|
fillSelectOptions(fnSelElem,dimFunctions,false); |
|
|
} |
|
|
} |
|
|
formDivElem.style.display="block"; |
|
|
} |
|
|
else |
|
|
formDivElem.style.display="none"; |
|
|
|
|
|
} |
|
|
|
|
|
function selectionResultPreview(myDiv) |
|
|
{ |
|
|
myDivElem=document.getElementById(myDiv); |
|
|
if(myDivElem.style.display=="none") |
|
|
{ |
|
|
var selectionRs=[]; |
|
|
var selectionRsMetaData=[]; |
|
|
var rowcount=rs.length; |
|
|
var maxLenCategoryDim=0; |
|
|
var maxMeasure=0; |
|
|
selectionRsMetaData=fillSelectionResultMetaData(); |
|
|
//alert(selectionRsMetaData[0].colname); |
|
|
selectionRs=fillSelectionResult(selectionRsMetaData); |
|
|
|
|
|
showSelectionTable("selectionResultPreviewTable",selectionRs,selectionRsMetaData,10); |
|
|
myDivElem.style.display="block"; |
|
|
} |
|
|
else |
|
|
myDivElem.style.display="none"; |
|
|
} |
|
|
function fillSelectionResultMetaData() |
|
|
{ |
|
|
var selectionRsMetaData=[]; |
|
|
var dimension1=document.getElementById("dimension1").value; |
|
|
var dimension2=document.getElementById("dimension2").value; |
|
|
var measure=document.getElementById("measure1").value; |
|
|
|
|
|
var functionOfDimension1=document.getElementById("dimension1_fn").value; |
|
|
var functionOfDimension2=document.getElementById("dimension2_fn").value; |
|
|
var functionOfMeasureDim=document.getElementById("measure1_fn").value; |
|
|
|
|
|
//first fill metadata: |
|
|
|
|
|
var counter=1; |
|
|
selectionRsMetaData.push(new selectionRowMetaData(counter,"dimension1",dimension1,getColumnCaption(dimension1),0,functionOfDimension1)); |
|
|
if(dimension2!="") |
|
|
{ |
|
|
counter++; |
|
|
var dim2=new selectionRowMetaData(counter,"dimension2",dimension2,getColumnCaption(dimension2),0,functionOfDimension2); |
|
|
selectionRsMetaData.push(dim2 ); |
|
|
} |
|
|
counter++; |
|
|
selectionRsMetaData.push(new selectionRowMetaData(counter,"measure",measure,getColumnCaption(measure),0),functionOfMeasureDim); |
|
|
|
|
|
return selectionRsMetaData; |
|
|
} |
|
|
|
|
|
function filld3data(myRs,MyRsMetaData,chartElem) |
|
|
{ |
|
|
//Identify dimensions and measures: |
|
|
var dimension1,dimension2,measure1; |
|
|
var data=[]; |
|
|
|
|
|
for(var k=0;k<chartElem.elementTypeProperties.length;k++) |
|
|
{ |
|
|
if(chartElem.elementTypeProperties[k].propertyValue!="") |
|
|
{ |
|
|
switch (chartElem.elementTypeProperties[k].vizTypePropertyUniquename) |
|
|
{ |
|
|
case "dimension1": |
|
|
dimension1=chartElem.elementTypeProperties[k].propertyValue; |
|
|
case "dimension2": |
|
|
dimension2=chartElem.elementTypeProperties[k].propertyValue; |
|
|
break; |
|
|
case "measure1": |
|
|
measure1=chartElem.elementTypeProperties[k].propertyValue; |
|
|
break; |
|
|
default: |
|
|
break; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
//get MetaData: |
|
|
|
|
|
|
|
|
//alert(dimension1+"-"+dimension2+"-"+measure+"-"+ functionOfCategoryDim+"-"+functionOfDimension2+"-"+functionOfMeasureDim); |
|
|
//get and transform Data: |
|
|
var maxLenDimension1=0; |
|
|
var maxMeasure=0; |
|
|
var rowcount=myRs.length; |
|
|
var rownr=1; |
|
|
console.log("Zeilenanzahl " +rowcount); |
|
|
myRs.forEach((row) => { |
|
|
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 fillSelectionResult(selectionRsMetaData) |
|
|
{ |
|
|
//OBSOLETE: |
|
|
var selectionRs=[]; |
|
|
//get MetaData: |
|
|
var dimension1,dimension2,measure, |
|
|
functionOfDimension1,functionOfDimension2,functionOfMeasureDim; |
|
|
for(rownr=0;rownr<selectionRsMetaData.length;rownr++) |
|
|
{ |
|
|
if(selectionRsMetaData[rownr].targetColumn=="dimension1") |
|
|
{ |
|
|
dimension1=selectionRsMetaData[rownr].colname; |
|
|
functionOfDimension1=selectionRsMetaData[rownr].colfunction; |
|
|
} |
|
|
|
|
|
if(selectionRsMetaData[rownr].targetColumn=="dimension2") |
|
|
{ |
|
|
dimension2=selectionRsMetaData[rownr].colname; |
|
|
functionOfDimension2=selectionRsMetaData[rownr].colfunction; |
|
|
} |
|
|
if(selectionRsMetaData[rownr].targetColumn=="measure") |
|
|
{ |
|
|
measure=selectionRsMetaData[rownr].colname; |
|
|
functionOfMeasureDim=selectionRsMetaData[rownr].colfunction; |
|
|
} |
|
|
|
|
|
} |
|
|
//alert(dimension1+"-"+dimension2+"-"+measure+"-"+ functionOfCategoryDim+"-"+functionOfDimension2+"-"+functionOfMeasureDim); |
|
|
//get and transform Data: |
|
|
var maxLenDimension1=0; |
|
|
var maxMeasure=0; |
|
|
var rowcount=rs.length; |
|
|
//alert("Zeilenanzahl " +rowcount); |
|
|
for(rownr=0;rownr<rowcount;rownr++) |
|
|
{ |
|
|
var dimension1Value=rs[rownr][dimension1]; |
|
|
if(functionOfDimension1) |
|
|
{ |
|
|
dimension1Value=applyFunction(dimension1Value,functionOfDimension1); |
|
|
} |
|
|
var dimension2Value; |
|
|
if(dimension2) |
|
|
{ |
|
|
var dimension2Value=rs[rownr][dimension2]; |
|
|
if(functionOfDimension2!="") |
|
|
{ |
|
|
dimension2Value=applyFunction(dimension2,functionOfDimension2); |
|
|
} |
|
|
} |
|
|
|
|
|
var measureDimValue=rs[rownr][measure]; |
|
|
if(functionOfMeasureDim) |
|
|
{ |
|
|
measureDimValue=applyFunction(measureDimValue,functionOfMeasureDim); |
|
|
} |
|
|
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 selectionRs; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
function renderDimensionField(vizTypeProperty,datasource) |
|
|
{ |
|
|
const fieldElem = document.createElement("div"); |
|
|
fieldElem.classList.add("field"); |
|
|
fieldElem.classList.add("is-grouped"); |
|
|
//label: |
|
|
const labelElem = document.createElement("div"); |
|
|
labelElem.classList.add("label-container"); |
|
|
const label = document.createElement("label"); |
|
|
label.classList.add("label"); |
|
|
label.classList.add("is-required"); |
|
|
label.classList.add("is-small"); |
|
|
label.classList.add("has-tooltip-right"); |
|
|
//label.setAttribute("data-tooltip",dimensionProperty.explanation); |
|
|
|
|
|
const textnode = document.createTextNode(vizTypeProperty.caption); |
|
|
label.appendChild(textnode); |
|
|
labelElem.appendChild(label); |
|
|
fieldElem.appendChild(labelElem); |
|
|
//input: |
|
|
const inputFieldElem = document.createElement("div"); |
|
|
inputFieldElem.classList.add("field"); |
|
|
inputFieldElem.classList.add("is-active"); |
|
|
const inputSelectElem = document.createElement("div"); |
|
|
inputSelectElem.classList.add("select"); |
|
|
inputSelectElem.classList.add("is-small"); |
|
|
//inputSelectElem.classList.add("is-fullwidth"); |
|
|
|
|
|
const selElem = document.createElement("select"); |
|
|
selElem.name=vizTypeProperty.propUniquename; |
|
|
selElem.id=vizTypeProperty.propUniquename; |
|
|
/* vermutlich unnötig: selElem.onchange= function () { |
|
|
renderChart('chartDiv'); |
|
|
};*/ |
|
|
var dimensionProperty=fillDimensionProperty(vizTypeProperty,datasource); |
|
|
fillSelectOptions(selElem,dimensionProperty.getValueResultset(),dimensionProperty.isMandatory); |
|
|
inputSelectElem.appendChild(selElem); |
|
|
inputFieldElem.appendChild(inputSelectElem); |
|
|
fieldElem.appendChild(inputFieldElem); |
|
|
return fieldElem; |
|
|
|
|
|
} |
|
|
|
|
|
function renderGeneralChartPropertiesForm(formDiv,myCommonChartProperties,renderer) |
|
|
{ |
|
|
//first empty form: |
|
|
var myForm=document.getElementById(formDiv); |
|
|
while (myForm.firstChild) { |
|
|
myForm.removeChild(myForm.firstChild); |
|
|
} |
|
|
//first Collect all groups: |
|
|
var commonChartPropertyGroups=[]; |
|
|
var previousGroup=""; |
|
|
for(var k=0;k < myCommonChartProperties.length;k++) |
|
|
{ |
|
|
var groupUniquename=myCommonChartProperties[k].groupUniquename; |
|
|
if(groupUniquename!="" |
|
|
&& groupUniquename != previousGroup |
|
|
&& myCommonChartProperties[k].groupVariableName !="" |
|
|
&& isChartPropertyValidForChartelements(myCommonChartProperties[k]) |
|
|
) |
|
|
{ |
|
|
var newcommonChartPropertyGroup = new commonChartPropertyGroup(myCommonChartProperties[k].groupCaption,groupUniquename,""); |
|
|
commonChartPropertyGroups.push(newcommonChartPropertyGroup); |
|
|
previousGroup=groupUniquename; |
|
|
} |
|
|
|
|
|
} |
|
|
const columnDiv = document.createElement("div"); |
|
|
for(var i=0;i < commonChartPropertyGroups.length;i++) |
|
|
{ |
|
|
|
|
|
const columnGroupDiv = document.createElement("div"); |
|
|
columnGroupDiv.id=commonChartPropertyGroups[i].groupUniquename; |
|
|
columnGroupDiv.classList.add("box"); |
|
|
|
|
|
const columnGroupHeaderDiv = document.createElement("div"); |
|
|
const colHeader = document.createTextNode(commonChartPropertyGroups[i].caption); |
|
|
const colHeaderBold = document.createElement("strong"); |
|
|
colHeaderBold.appendChild(colHeader); |
|
|
const colHeaderParagraph = document.createElement("label"); |
|
|
colHeaderParagraph.classList.add("label"); |
|
|
colHeaderParagraph.classList.add("is-small"); |
|
|
colHeaderParagraph.appendChild(colHeaderBold); |
|
|
//Toggle visibility: |
|
|
const colHeaderToggleBtn = document.createElement("a"); |
|
|
colHeaderToggleBtn.id="openBody"+commonChartPropertyGroups[i].groupUniquename; |
|
|
//colHeaderToggleBtn.classList.add("is-small"); |
|
|
colHeaderToggleBtn.onclick =function() { |
|
|
toggleGroupBodyDiv(this.id) |
|
|
} |
|
|
const colHeaderToggleBtnText = document.createTextNode(" ..."); |
|
|
colHeaderToggleBtn.appendChild(colHeaderToggleBtnText); |
|
|
colHeaderParagraph.appendChild(colHeaderToggleBtn); |
|
|
columnGroupHeaderDiv.appendChild(colHeaderParagraph); |
|
|
//columnGroupHeaderDiv.appendChild(colHeaderToggleBtn); |
|
|
|
|
|
columnGroupDiv.appendChild(columnGroupHeaderDiv); |
|
|
const columnGroupBodyDiv = document.createElement("div"); |
|
|
columnGroupBodyDiv.id="Body"+commonChartPropertyGroups[i].groupUniquename; |
|
|
columnGroupBodyDiv.style.display="none"; |
|
|
for(var k=0;k < myCommonChartProperties.length;k++) |
|
|
{ |
|
|
if(myCommonChartProperties[k].groupUniquename==commonChartPropertyGroups[i].groupUniquename |
|
|
&& myCommonChartProperties[k].variableName!="" |
|
|
&& isChartPropertyValidForChartelements(myCommonChartProperties[k])) |
|
|
columnGroupBodyDiv.appendChild(renderChartPropertyField(myCommonChartProperties[k])); |
|
|
} |
|
|
columnGroupDiv.appendChild(columnGroupBodyDiv); |
|
|
columnDiv.appendChild(columnGroupDiv); |
|
|
|
|
|
} |
|
|
myForm.appendChild(columnDiv); |
|
|
/*alte Liste flach: |
|
|
const divBox = document.createElement("div"); |
|
|
for(var k=0;k < myCommonChartProperties.length;k++) |
|
|
{ |
|
|
if((myCommonChartProperties[k].groupVariableName=="layout" |
|
|
|| myCommonChartProperties[k].groupVariableName=="style" |
|
|
|| myCommonChartProperties[k].groupVariableName=="x" |
|
|
|| myCommonChartProperties[k].groupVariableName=="y" |
|
|
|| myCommonChartProperties[k].groupVariableName=="color" |
|
|
) |
|
|
&& myCommonChartProperties[k].rendererUniquename==renderer) |
|
|
divBox.appendChild(renderChartPropertyField(myCommonChartProperties[k])); |
|
|
} |
|
|
|
|
|
|
|
|
myForm.appendChild(divBox); |
|
|
*/ |
|
|
} |
|
|
|
|
|
function isChartPropertyValidForChartelements(prop) |
|
|
{ |
|
|
var propValid=false; |
|
|
if(prop.isGeneric==1) |
|
|
return true; |
|
|
var nrOfChartElements=myChartModel.chartElements.length; |
|
|
for(var k=0;k < nrOfChartElements;k++) |
|
|
{ |
|
|
var usedVizTypeUniquename=myChartModel.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 toggleGroupBodyDiv(groupBodyDiv) |
|
|
{ |
|
|
var bodyDiv=groupBodyDiv.substr(4); //remove "open" Prefix |
|
|
var myDiv=document.getElementById(bodyDiv); |
|
|
if(myDiv.style.display=="block") |
|
|
myDiv.style.display="none"; |
|
|
else |
|
|
myDiv.style.display="block"; |
|
|
|
|
|
} |
|
|
|
|
|
function renderChartPropertyField(commonChartProperty) |
|
|
{ |
|
|
//Wenn im chartModel schon ein Wert vorhanden ist, wird er vorbelegt: if(commonChartProperty) |
|
|
var propValue=""; |
|
|
if(myChartModel && myChartModel.chartPropertiesUsed.length>0) |
|
|
{ |
|
|
propValue=getCommonChartPropertyFromModel(myChartModel.chartPropertiesUsed,commonChartProperty.name ); |
|
|
} |
|
|
|
|
|
const fieldElem = document.createElement("div"); |
|
|
fieldElem.classList.add("field"); |
|
|
fieldElem.classList.add("is-grouped"); |
|
|
//label: |
|
|
const labelElem = document.createElement("div"); |
|
|
labelElem.classList.add("label-container"); |
|
|
const label = document.createElement("label"); |
|
|
label.classList.add("label"); |
|
|
label.classList.add("is-required"); |
|
|
label.classList.add("is-small"); |
|
|
label.classList.add("has-tooltip-right"); |
|
|
label.setAttribute("data-tooltip",commonChartProperty.explanation); |
|
|
|
|
|
const textnode = document.createTextNode(commonChartProperty.caption); |
|
|
label.appendChild(textnode); |
|
|
labelElem.appendChild(label); |
|
|
fieldElem.appendChild(labelElem); |
|
|
//input: |
|
|
const inputFieldElem = document.createElement("div"); |
|
|
inputFieldElem.classList.add("field"); |
|
|
const inputParaElem = document.createElement("p"); |
|
|
inputParaElem.classList.add("control-new"); |
|
|
const inputElem = document.createElement("div"); |
|
|
inputElem.classList.add("is-small"); |
|
|
//inputElem.classList.add("is-fullwidth"); |
|
|
|
|
|
switch (commonChartProperty.inputType) { |
|
|
case "SELECT": |
|
|
//select input: |
|
|
inputElem.classList.add("select"); |
|
|
inputElem.classList.add("is-small"); |
|
|
const selElem = document.createElement("select"); |
|
|
selElem.name=commonChartProperty.name; |
|
|
selElem.id=commonChartProperty.name; |
|
|
//selElem.style="width:50px"; |
|
|
if(commonChartProperty.variableName=="") |
|
|
{ |
|
|
selElem.disabled="disabled"; |
|
|
selElem.readonly="readonly"; |
|
|
} |
|
|
|
|
|
selElem.onchange= function () { |
|
|
updateChartModel(); |
|
|
renderChart('chartDiv',myChartModel); |
|
|
}; |
|
|
fillSelectOptions(selElem,commonChartProperty.getValueResultset(),commonChartProperty.isMandatory); |
|
|
selElem.value= (propValue=="")?commonChartProperty.defaultValue:propValue; |
|
|
inputElem.appendChild(selElem); |
|
|
inputParaElem.appendChild(inputElem); |
|
|
|
|
|
break; |
|
|
case "TEXTAREA": |
|
|
//großes Texteingabefeld: |
|
|
const textAreaElem = document.createElement("textarea"); |
|
|
textAreaElem.cols="20"; |
|
|
textAreaElem.rows=3; |
|
|
if(commonChartProperty.variableName=="") |
|
|
{ |
|
|
textAreaElem.disabled="disabled"; |
|
|
textAreaElem.readonly="readonly"; |
|
|
} |
|
|
textAreaElem.name=commonChartProperty.name; |
|
|
textAreaElem.id=commonChartProperty.name; |
|
|
textAreaElem.value= (propValue=="")?commonChartProperty.defaultValue:propValue; |
|
|
textAreaElem.onchange= function () { |
|
|
updateChartModel(); |
|
|
renderChart('chartDiv',myChartModel); |
|
|
}; |
|
|
inputElem.appendChild(textAreaElem); |
|
|
inputParaElem.appendChild(inputElem); |
|
|
|
|
|
break; |
|
|
case "RANGE": |
|
|
|
|
|
//Schieberegler: |
|
|
const rangeElem = document.createElement("input"); |
|
|
rangeElem.type="NUMBER"; |
|
|
rangeElem.size=5; |
|
|
if(commonChartProperty.variableName=="") |
|
|
{ |
|
|
rangeElem.disabled="disabled"; |
|
|
rangeElem.readonly="readonly"; |
|
|
} |
|
|
|
|
|
/* klappt noch nicht: |
|
|
rangeElem.type="RANGE"; |
|
|
rangeElem.min=commonChartProperty.range_from; |
|
|
rangeElem.max=commonChartProperty.range_to; |
|
|
rangeElem.step=50; |
|
|
*/ |
|
|
|
|
|
rangeElem.name=commonChartProperty.name; |
|
|
rangeElem.id=commonChartProperty.name; |
|
|
rangeElem.value= (propValue=="")?commonChartProperty.defaultValue:propValue; |
|
|
rangeElem.onchange= function () { |
|
|
updateChartModel(); |
|
|
renderChart('chartDiv',myChartModel); |
|
|
}; |
|
|
inputElem.appendChild(rangeElem); |
|
|
inputParaElem.appendChild(inputElem); |
|
|
break; |
|
|
default: |
|
|
//Einfaches Texteingabefeld: |
|
|
const inpElem = document.createElement("input"); |
|
|
inpElem.type="TEXT"; |
|
|
if(commonChartProperty.propValueType=="integer") |
|
|
inpElem.type="NUMBER"; |
|
|
if(commonChartProperty.inputType=="COLOR") |
|
|
inpElem.type="color"; |
|
|
inpElem.size=5; |
|
|
if(commonChartProperty.variableName=="") |
|
|
{ |
|
|
inpElem.disabled="disabled"; |
|
|
inpElem.readonly="readonly"; |
|
|
} |
|
|
inpElem.name=commonChartProperty.name; |
|
|
inpElem.id=commonChartProperty.name; |
|
|
inpElem.value= (propValue=="")?commonChartProperty.defaultValue:propValue; |
|
|
inpElem.onchange= function () { |
|
|
updateChartModel(); |
|
|
renderChart('chartDiv',myChartModel); |
|
|
}; |
|
|
inputElem.appendChild(inpElem); |
|
|
inputParaElem.appendChild(inputElem); |
|
|
|
|
|
break; |
|
|
} |
|
|
|
|
|
|
|
|
inputFieldElem.appendChild(inputParaElem); |
|
|
fieldElem.appendChild(inputFieldElem); |
|
|
return fieldElem; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function fillSelectOptions(myCombo,myValues,isMandatory) |
|
|
{ |
|
|
var optionCounter=0; |
|
|
var selectedOption=null; |
|
|
while (myCombo.firstChild) { |
|
|
myCombo.removeChild(myCombo.firstChild); |
|
|
} |
|
|
var optionCounter=0; |
|
|
if(!isMandatory) |
|
|
{ |
|
|
//add an empty option: |
|
|
var o=new Option("",""); |
|
|
myCombo.options[optionCounter]=o; |
|
|
selectedOption=optionCounter; |
|
|
optionCounter++; |
|
|
} |
|
|
for(var j=0;j < myValues.length;j++) |
|
|
{ |
|
|
if(myValues[j].isDefault) |
|
|
selectedOption=optionCounter; |
|
|
|
|
|
var o=new Option(myValues[j].name,myValues[j].value,null,null); |
|
|
myCombo.options[optionCounter]=o; |
|
|
optionCounter++; |
|
|
} |
|
|
if(selectedOption!=null) |
|
|
myCombo.selectedIndex=selectedOption; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function prepareData_alt() |
|
|
{ |
|
|
var data=[]; |
|
|
|
|
|
var rowcount=rs.length; |
|
|
var colnrOfCategorydimName=document.getElementById("dimension1").value; |
|
|
var colnrOfMeasure=document.getElementById("measure1").value; |
|
|
var functionOfCategoryDim=document.getElementById("dimension1_fn").value; |
|
|
var functionOfMeasureDim=document.getElementById("measure1_fn").value; |
|
|
var maxLenName=0; |
|
|
var maxValue=0; |
|
|
for(j=1;j<rowcount;j++) |
|
|
{ |
|
|
console.log(rs.length+"-"+j+"-"+colnrOfCategorydimName); |
|
|
if(rs[j][colnrOfCategorydimName]) //only if Name is not empty: |
|
|
{ |
|
|
var dimension1Value=rs[j][colnrOfCategorydimName]; |
|
|
var measureDimValue=rs[j][colnrOfMeasure]; |
|
|
if(functionOfCategoryDim !="") |
|
|
dimension1Value=applyFunction(dimension1Value,functionOfCategoryDim); |
|
|
if(functionOfMeasureDim !="") |
|
|
measureDimValue=applyFunction(measureDimValue,functionOfMeasureDim); |
|
|
data.push(new d3dataRow(j,dimension1Value,measureDimValue)); |
|
|
//identify max String length to compute x axis size |
|
|
if(dimension1Value.length >maxLenName) |
|
|
maxLenName=dimension1Value.length; |
|
|
//the same for values: |
|
|
if(measureDimValue >maxValue) |
|
|
maxValue=measureDimValue; |
|
|
} |
|
|
|
|
|
} |
|
|
return data; |
|
|
} |
|
|
|
|
|
|
|
|
function showDataTable(myTableDiv,tableId,mydata,metadata,maxRows) |
|
|
{ |
|
|
|
|
|
tableDiv=document.getElementById(myTableDiv); |
|
|
if(tableDiv.innerHTML=="") |
|
|
{ |
|
|
var rowcount=mydata.length; |
|
|
if(rowcount > maxRows) |
|
|
rowcount=maxRows; |
|
|
const tabElem = document.createElement("table"); |
|
|
tabElem.border="1"; |
|
|
tabElem.width="100%"; |
|
|
const rowElem = document.createElement("tr"); |
|
|
const thCap = document.createElement("th"); |
|
|
const textnode = document.createTextNode("Zeilennr."); |
|
|
thCap.appendChild(textnode); |
|
|
rowElem.appendChild(thCap); |
|
|
|
|
|
for(var col=0;col < metadata.length;col++) |
|
|
{ |
|
|
if(metadata[col].nr) |
|
|
{ |
|
|
const thCap = document.createElement("th"); |
|
|
const textnode = document.createTextNode(metadata[col].colcaption); |
|
|
thCap.appendChild(textnode); |
|
|
rowElem.appendChild(thCap); |
|
|
} |
|
|
} |
|
|
tabElem.appendChild(rowElem); |
|
|
|
|
|
//Variablennamen in Subheader |
|
|
const rowElemSubHeader = document.createElement("tr"); |
|
|
const tdCap = document.createElement("td"); |
|
|
tdCap.style="font-family:monospace;font-size:smaller"; |
|
|
const textnodeSubHeader = document.createTextNode("(rownr)"); |
|
|
tdCap.appendChild(textnodeSubHeader); |
|
|
rowElemSubHeader.appendChild(tdCap); |
|
|
|
|
|
for(var col=0;col < metadata.length;col++) |
|
|
{ |
|
|
if(metadata[col].nr) |
|
|
{ |
|
|
const thCap = document.createElement("td"); |
|
|
thCap.style="font-family:monospace;font-size:smaller"; |
|
|
const textnode = document.createTextNode("("+metadata[col].colname+")"); |
|
|
thCap.appendChild(textnode); |
|
|
rowElemSubHeader.appendChild(thCap); |
|
|
} |
|
|
} |
|
|
tabElem.appendChild(rowElemSubHeader); |
|
|
|
|
|
for(row=0;row<rowcount;row++) |
|
|
{ |
|
|
if(mydata[row]) |
|
|
{ |
|
|
const rowElem = document.createElement("tr"); |
|
|
const tdCap = document.createElement("td"); |
|
|
const textnode = document.createTextNode(row); |
|
|
tdCap.appendChild(textnode); |
|
|
rowElem.appendChild(tdCap); |
|
|
for(var col=0;col < metadata.length;col++) |
|
|
{ |
|
|
if(metadata[col].nr) |
|
|
{ |
|
|
const tdCap = document.createElement("td"); |
|
|
const textnode = document.createTextNode(mydata[row][metadata[col].colname]); |
|
|
tdCap.appendChild(textnode); |
|
|
rowElem.appendChild(tdCap); |
|
|
} |
|
|
} |
|
|
tabElem.appendChild(rowElem); |
|
|
} |
|
|
} |
|
|
|
|
|
//Start Funktionen: |
|
|
var dimFunctions=[]; |
|
|
var myFunction= new dimFunction(0,"Wort 1 ans Ende","switchWord1and2ff",false); |
|
|
dimFunctions[0]=myFunction; |
|
|
var myFunction= new dimFunction(1,"Nur Wort 1","justWord1",false); |
|
|
dimFunctions[1]=myFunction; |
|
|
var myFunction= new dimFunction(2,"Abkürzen (20)","abbreviate",false); |
|
|
dimFunctions[2]=myFunction; |
|
|
|
|
|
const rowElemFunc = document.createElement("tr"); |
|
|
const tdCapFunc = document.createElement("td"); |
|
|
const textnodeFunc = document.createTextNode("Funktion:"); |
|
|
tdCapFunc.appendChild(textnodeFunc); |
|
|
rowElemFunc.appendChild(tdCapFunc); |
|
|
for(var col=0;col < metadata.length;col++) |
|
|
{ |
|
|
if(metadata[col].nr) |
|
|
{ |
|
|
const tdCapFunc = document.createElement("td"); |
|
|
if(metadata[col].colcaption.trim() != "" && metadata[col].coltype==1) //String |
|
|
{ |
|
|
//const textnode = document.createTextNode(data[row][metadata[col].colname]); |
|
|
const selElem = document.createElement("select"); |
|
|
selElem.name=metadata[col].colname; |
|
|
selElem.id=metadata[col].colname; |
|
|
|
|
|
fillSelectOptions(selElem,dimFunctions,false); |
|
|
selElem.onchange= function () { |
|
|
applyColFunction(myTableDiv,tableId,mydata,metadata,maxRows,this.name,this.value); |
|
|
}; |
|
|
tdCapFunc.appendChild(selElem); |
|
|
} |
|
|
|
|
|
rowElemFunc.appendChild(tdCapFunc); |
|
|
} |
|
|
} |
|
|
tabElem.appendChild(rowElemFunc); |
|
|
|
|
|
tableDiv.appendChild(tabElem); |
|
|
} |
|
|
else |
|
|
tableDiv.innerHTML=""; //reset table |
|
|
} |
|
|
|
|
|
function applyColFunction(myTableDiv,tableId,data,metadata,maxRows,colname,functionName) |
|
|
{ |
|
|
//first update chartModel: |
|
|
var myFunc=new dataTransformationCol(tableId,colname,functionName); |
|
|
myChartModel.dataTransformation.push(myFunc); |
|
|
|
|
|
for(var row=0;row < data.length;row++) |
|
|
{ |
|
|
data[row][colname]=applyFunction(data[row][colname],functionName); |
|
|
} |
|
|
document.getElementById(myTableDiv).innerHTML=""; |
|
|
showDataTable(myTableDiv,tableId,data,metadata,maxRows) |
|
|
|
|
|
} |
|
|
|
|
|
function showSelectionTable(myTableDiv,data,metadata,maxRows) |
|
|
{ |
|
|
/*OBSOLETE*/ |
|
|
tableDiv=document.getElementById(myTableDiv); |
|
|
tableDiv.innerHTML=""; //reset table |
|
|
var rowcount=data.length; |
|
|
if(rowcount > maxRows) |
|
|
rowcount=maxRows; |
|
|
const tabElem = document.createElement("table"); |
|
|
tabElem.border="1"; |
|
|
tabElem.width="100%"; |
|
|
const rowElem = document.createElement("tr"); |
|
|
for(var col=0;col < metadata.length;col++) |
|
|
{ |
|
|
if(metadata[col].nr) |
|
|
{ |
|
|
const thCap = document.createElement("th"); |
|
|
const textnode = document.createTextNode(metadata[col].colcaption); |
|
|
thCap.appendChild(textnode); |
|
|
rowElem.appendChild(thCap); |
|
|
} |
|
|
} |
|
|
tabElem.appendChild(rowElem); |
|
|
|
|
|
for(row=1;row<rowcount;row++) |
|
|
{ |
|
|
if(data[row]) |
|
|
{ |
|
|
const rowElem = document.createElement("tr"); |
|
|
for(var col=0;col < metadata.length;col++) |
|
|
{ |
|
|
if(metadata[col].nr) |
|
|
{ |
|
|
const tdCap = document.createElement("td"); |
|
|
const textnode = document.createTextNode(data[row][metadata[col].targetColumn]); |
|
|
tdCap.appendChild(textnode); |
|
|
rowElem.appendChild(tdCap); |
|
|
} |
|
|
} |
|
|
tabElem.appendChild(rowElem); |
|
|
} |
|
|
} |
|
|
tableDiv.appendChild(tabElem); |
|
|
} |
|
|
function showChartDiv(chartDivElem) |
|
|
{ |
|
|
var myDiv=document.getElementById(chartDivElem); |
|
|
if(myDiv.style.display=="block") |
|
|
myDiv.style.display="none"; |
|
|
else |
|
|
myDiv.style.display="block"; |
|
|
} |
|
|
|
|
|
function renderChartElementWithPlot(chartElem,targetDiv) |
|
|
{ |
|
|
var plotMark=new Object; |
|
|
if(chartElem) |
|
|
{ |
|
|
var chartType=chartElem.vizTypeUniquename; |
|
|
var myDatasourceRs=rs[chartElem.datasource]; |
|
|
|
|
|
var optionString=prepareChartPropertiesForPlotMark(chartType,chartElem); |
|
|
|
|
|
console.log("Mark-option for "+chartType+":"+ optionString); |
|
|
var markOptions=JSON.parse(optionString); |
|
|
switch (chartType) |
|
|
{ |
|
|
case "bar_x": |
|
|
plotMark=Plot.barX(myDatasourceRs,markOptions); |
|
|
break; |
|
|
/* case "bar_x_stacked": |
|
|
plotMark=Plot.barX(myDatasourceRs,markOptions); |
|
|
break;*/ |
|
|
case "bar_x_alt": |
|
|
makeBarX(svg,data); |
|
|
break; |
|
|
case "bar_y": |
|
|
plotMark=Plot.barY(myDatasourceRs,markOptions); |
|
|
break; |
|
|
case "area_x": |
|
|
plotMark=Plot.areaX(myDatasourceRs,markOptions); |
|
|
break; |
|
|
case "area_y": |
|
|
plotMark=Plot.areaY(myDatasourceRs,markOptions); |
|
|
break; |
|
|
case "dot": |
|
|
plotMark=Plot.dot(myDatasourceRs,markOptions); |
|
|
break; |
|
|
case "line": |
|
|
plotMark=Plot.line(myDatasourceRs,markOptions); |
|
|
break; |
|
|
case "box_x": |
|
|
plotMark=Plot.boxX(myDatasourceRs,markOptions); |
|
|
break; |
|
|
case "box_y": |
|
|
plotMark=Plot.boxY(myDatasourceRs,markOptions); |
|
|
break; |
|
|
case "text": |
|
|
plotMark=Plot.text(myDatasourceRs,markOptions); |
|
|
break; |
|
|
default: |
|
|
alert("Unknown chart type"); |
|
|
break; |
|
|
} |
|
|
} |
|
|
return plotMark; |
|
|
} |
|
|
function prepareChartPropertiesForPlotMark(chartType,chartElem) |
|
|
{ |
|
|
var orientation=getVizTypeOrientation(chartElem.vizTypeUniquename); |
|
|
var optionString="{\"dummy\": \"1\""; |
|
|
for(var k=0;k<chartElem.elementTypeProperties.length;k++) |
|
|
{ |
|
|
var propUniquename=chartElem.elementTypeProperties[k].vizTypePropertyUniquename; |
|
|
var propValue=chartElem.elementTypeProperties[k].propertyValue; |
|
|
if(propValue!="") |
|
|
{ |
|
|
optionString+=",\""+propUniquename+"\":\""+propValue+"\""; |
|
|
if(propUniquename=="stroke" && chartType!="line") |
|
|
{ |
|
|
//Seriendimension hat immer fill |
|
|
optionString+=",\"fill\":\""+propValue+"\""; |
|
|
//optionString+=",\"sort\":\""+propValue+"\""; |
|
|
} |
|
|
if(propUniquename=="text") |
|
|
{ |
|
|
//Wertelabel |
|
|
optionString+=",\"textAnchor\":\"start\""; |
|
|
} |
|
|
|
|
|
if(propUniquename=="x" && orientation=="V") |
|
|
{ |
|
|
//Vertikale Diagramme sortieren immer nach X-Achse |
|
|
optionString+=",\"sort\":\""+propValue+"\""; |
|
|
} |
|
|
if(propUniquename=="y" && orientation=="H") |
|
|
{ |
|
|
//Horizontale Diagramme sortieren immer nach Y-Achse |
|
|
optionString+=",\"sort\":\""+propValue+"\""; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
optionString+=" }"; |
|
|
return optionString; |
|
|
} |
|
|
function getVizTypeOrientation(vizTypeUniquename) |
|
|
{ |
|
|
var orientation=""; |
|
|
for(var k=0;k<vizTypes.length;k++) |
|
|
{ |
|
|
if(vizTypes[k].uniquename==vizTypeUniquename) |
|
|
orientation=vizTypes[k].orientation; |
|
|
} |
|
|
return orientation; |
|
|
} |
|
|
function renderChartElementWithD3(currentChartModel,chartElemNr,targetDiv) |
|
|
{ |
|
|
|
|
|
// append the svg canvas to the page |
|
|
var margin = { top: 10, right: 10, bottom: 10, left: 10 }, |
|
|
//var margin = { top: 0, right: 50, bottom: 0, left: 0 }, |
|
|
width = getCommonChartPropertyFromModel(currentChartModel.chartPropertiesUsed,"width") - margin.left - margin.right, |
|
|
height = getCommonChartPropertyFromModel(currentChartModel.chartPropertiesUsed,"height") - margin.top - margin.bottom; |
|
|
|
|
|
var clearCanvas=document.getElementById(targetDiv); |
|
|
while (clearCanvas.firstChild) { |
|
|
clearCanvas.removeChild(clearCanvas.firstChild); |
|
|
} |
|
|
//targetDiv |
|
|
var mySvg = d3.select("#"+targetDiv).append("svg") |
|
|
.attr("width", width + margin.left + margin.right) |
|
|
.attr("height", height + margin.top + margin.bottom) |
|
|
.append("g") |
|
|
.attr("transform", |
|
|
"translate(" + margin.left + "," + margin.top + ")"); |
|
|
|
|
|
chartElem=currentChartModel.chartElements[chartElemNr]; |
|
|
if(chartElem) |
|
|
{ |
|
|
var chartType=chartElem.vizTypeUniquename; |
|
|
var myDatasourceRs=rs[chartElem.datasource]; |
|
|
var data=filld3data(rs[chartElem.datasource],rsColumnMetaData[chartElem.datasource],chartElem); |
|
|
console.log("Mark-option for "+chartType); |
|
|
switch (chartType) |
|
|
{ |
|
|
case "bar_x_d3": |
|
|
mySvg=makeBarX_d3(currentChartModel.chartPropertiesUsed,mySvg,data,chartElem); |
|
|
break; |
|
|
case "sankey": |
|
|
mySvg=makeSankeyD3(currentChartModel.chartPropertiesUsed,mySvg,data,rsColumnMetaData[chartElem.datasource],chartElem); |
|
|
break; |
|
|
case "worldmap": |
|
|
mySvg=makeWorldmapD3(currentChartModel.chartPropertiesUsed,mySvg,data,rsColumnMetaData[chartElem.datasource],chartElem); |
|
|
break; |
|
|
default: |
|
|
alert("Unknown chart type"); |
|
|
break; |
|
|
} |
|
|
} |
|
|
return mySvg; |
|
|
} |
|
|
|
|
|
function createChart(chartDivElem) |
|
|
{ |
|
|
//OBSOLETE! |
|
|
chartType=document.getElementById("viz_chart_type").value; |
|
|
|
|
|
var selectionRsMetaData=[]; |
|
|
var selectionRs=[]; |
|
|
|
|
|
//data=prepareData(); |
|
|
selectionRsMetaData=fillSelectionResultMetaData(); |
|
|
//alert(selectionRsMetaData[0].colname); |
|
|
selectionRs=fillSelectionResult(selectionRsMetaData); |
|
|
|
|
|
|
|
|
var valueLabelWidth = getCommonChartProperty("valueLabelWidth"); |
|
|
var fontFamily=getCommonChartProperty("fontFamily"); |
|
|
var gridLabelHeight = getCommonChartProperty("gridLabelHeight"); |
|
|
var gridChartOffset = getCommonChartProperty("gridChartOffset"); |
|
|
var chartWidth=getCommonChartProperty("chartWidth"); |
|
|
var fontSize=getCommonChartProperty("fontSize"); |
|
|
//svg,data |
|
|
document.getElementById(chartDivElem).innerHTML=""; //reset canvas |
|
|
/* |
|
|
var svg = d3.select("#"+chartDivElem).append("svg") |
|
|
.attr("width", chartWidth) //maxBarWidth + barLabelWidth + valueLabelWidth) |
|
|
//.attr("height", y.range()[1]) |
|
|
.attr("font-family", fontFamily) |
|
|
.attr("font-size", fontSize) |
|
|
.attr("text-anchor", "start") |
|
|
.attr("id", "chartSVG") |
|
|
; |
|
|
svg.width=50; |
|
|
*/ |
|
|
switch (chartType) |
|
|
{ |
|
|
case "sample": |
|
|
makeSample(); |
|
|
break; |
|
|
case "bar_x": |
|
|
makeBarX(chartDivElem,selectionRs); |
|
|
break; |
|
|
case "bar_x_stacked": |
|
|
makeBarXStacked(chartDivElem,selectionRs); |
|
|
break; |
|
|
case "bar_x_alt": |
|
|
makeBarX(svg,data); |
|
|
break; |
|
|
case "bar_y": |
|
|
makeBarY(chartDivElem,selectionRs); |
|
|
break; |
|
|
case "area_y": |
|
|
makeAreaY(chartDivElem,selectionRs); |
|
|
break; |
|
|
case "dot": |
|
|
makeDot(chartDivElem,selectionRs); |
|
|
break; |
|
|
case "line": |
|
|
makeLine(chartDivElem,selectionRs); |
|
|
break; |
|
|
default: |
|
|
alert("Please select a chart type"); |
|
|
break; |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
function makeBarX_d3(myCommonChartProperties,svg,data,chartElem) |
|
|
{ |
|
|
var barHeight = 18; |
|
|
//var barLabelWidth = 500; |
|
|
//var barLabelPadding = 10; |
|
|
//var maxBarWidth = maxValue; |
|
|
var fontSize=12;//getCommonChartProperty("fontSize"); |
|
|
var chartWidth=800;//getCommonChartProperty("chartWidth"); |
|
|
var maxValue=d3.max(data, d => d.measure1); |
|
|
var maxLenName=d3.max(data, d => d.dimension1.length); |
|
|
var maxLenNamePx=maxLenName*fontSize; |
|
|
var x = d3.scaleLinear().domain([0, d3.max(data, d => d.measure1)]).range([0, chartWidth]); |
|
|
var y = d3.scaleBand().domain(data.map(d => d.nr)).range([0, barHeight * data.length]); |
|
|
const bar = svg.selectAll("g") |
|
|
.data(data) |
|
|
.join("g") |
|
|
.attr("transform", d => `translate(${maxLenNamePx},${y(d.nr)})`) |
|
|
; |
|
|
|
|
|
bar.append("rect") |
|
|
.attr("fill", "steelblue") |
|
|
.on("mouseover",function(){ |
|
|
d3.select(this).attr("fill", "red"); |
|
|
}) |
|
|
.on("mouseout",function(){ |
|
|
d3.select(this).attr("fill", "steelblue"); |
|
|
}) |
|
|
.transition() |
|
|
.duration(750) |
|
|
.delay(function(d, i) { return i * 10; }) |
|
|
.attr("width", d => x(d.measure1)) //x) |
|
|
.attr("height", y.bandwidth() - 1) |
|
|
|
|
|
; |
|
|
//value label: |
|
|
bar.append("text") |
|
|
.attr("fill", "white") |
|
|
.attr("x", d => x(d.measure1)/2) |
|
|
.attr("y", (y.bandwidth() - 1) / 2) |
|
|
.attr("dy", "0.35em") |
|
|
.attr("text-anchor","middle") |
|
|
.text(d => d.measure1); |
|
|
//label: |
|
|
bar.append("text") |
|
|
.attr("fill", "black") |
|
|
.attr("x", 0) |
|
|
.attr("y", (y.bandwidth() - 1) / 2) |
|
|
.attr("dy", "0.35em") |
|
|
.attr("text-anchor","end") |
|
|
.text(d => d.dimension1); |
|
|
|
|
|
return bar; |
|
|
} |
|
|
|
|
|
function makeLine_alt(svg,data) { |
|
|
var xLabel=rsMetaData[document.getElementById("dimension1").value-1].colcaption; |
|
|
var yLabel=rsMetaData[document.getElementById("measure1").value-1].colcaption; |
|
|
var fontSize=getCommonChartProperty("fontSize"); |
|
|
var maxLenName=d3.max(data, d => d.name.length); |
|
|
var maxLenNamePx=maxLenName*fontSize/1.5; |
|
|
var marginLeftPx=xLabel.length*fontSize; |
|
|
|
|
|
var options = { |
|
|
marginBottom:maxLenNamePx, |
|
|
marginLeft:marginLeftPx, |
|
|
x: { |
|
|
tickRotate: -45, |
|
|
ticks: 5, |
|
|
tickSize: 5, |
|
|
line: true, |
|
|
tickPadding: 10, |
|
|
labelAnchor: "left", |
|
|
labelOffset: 0, |
|
|
nice: true, |
|
|
label: xLabel, |
|
|
type:"point" |
|
|
}, |
|
|
// set y axis options |
|
|
y: { |
|
|
grid:true, |
|
|
label: yLabel |
|
|
}, |
|
|
sort: "nr", |
|
|
// define the marks we will use, dots and a line |
|
|
marks: [ |
|
|
Plot.line(data, {x: "name", y: "value",curve:"linear"}), |
|
|
Plot.dot(data, {x: "name", y: "value" }) |
|
|
] |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
document.getElementById("chartDiv").appendChild(Plot.plot(options)); |
|
|
} |
|
|
function makeSample() |
|
|
{ |
|
|
var sales = [4]; |
|
|
sales = [ |
|
|
{units: 10, fruit: "fig"}, |
|
|
{units: 20, fruit: "date"}, |
|
|
{units: 40, fruit: "plum"}, |
|
|
{units: 30, fruit: "plum"} |
|
|
]; |
|
|
document.getElementById("chartDiv").appendChild(Plot.dot(sales, |
|
|
{x: "units", y: "fruit"} |
|
|
).plot()); |
|
|
|
|
|
} |
|
|
function getChartOptions(categoryDim1,categoryDim2,measureDim,marksArray,chartOrientationVertical) |
|
|
{ |
|
|
/*OBSOLETE*/ |
|
|
var options; |
|
|
//var categoryDim1=document.getElementById("viz_dimension1").value; |
|
|
//var categoryDim2=document.getElementById("viz_dimension2").value; |
|
|
//var measureDim=document.getElementById("viz_measure1").value; |
|
|
var chartWidth=getCommonChartProperty("width"); |
|
|
var marginLeftValue=chartWidth/5; //Default 20% linker Rand |
|
|
//if(getCommonChartProperty("marginLeft")!="") |
|
|
// marginLeftValue=getCommonChartProperty("marginLeft"); |
|
|
var fontSizeDefault=getCommonChartProperty("fontSize")+"pt"; |
|
|
var myCaption=getCommonChartProperty("caption"); |
|
|
var myFontFamily=getCommonChartProperty("font-family"); |
|
|
var myBgColor=getCommonChartProperty("background-color"); |
|
|
var myColor=getCommonChartProperty("color"); |
|
|
var marginBottomValue=100;//getCommonChartProperty("marginBottom");; |
|
|
var categoryLabel1=getColumnCaption(categoryDim1); |
|
|
var categoryLabel2=getColumnCaption(categoryDim2); |
|
|
var measureLabel=getColumnCaption(measureDim); |
|
|
|
|
|
var optionsString="{\"dummy\":1"; |
|
|
//first Collect all groups: |
|
|
var commonChartPropertyGroups=[]; |
|
|
var previousGroup=""; |
|
|
for(var k=0;k < commonChartProperties.length;k++) |
|
|
{ |
|
|
var groupVariableName=commonChartProperties[k].groupVariableName; |
|
|
if(groupVariableName!="" |
|
|
&& groupVariableName != previousGroup) |
|
|
{ |
|
|
var newcommonChartPropertyGroup = new commonChartPropertyGroup(commonChartProperties[k].groupCaption,commonChartProperties[k].groupUniquename,groupVariableName); |
|
|
commonChartPropertyGroups.push(newcommonChartPropertyGroup); |
|
|
} |
|
|
previousGroup=groupVariableName; |
|
|
} |
|
|
//Now create options Str with all groups: |
|
|
var textDelim=""; |
|
|
for(var i=0;i < commonChartPropertyGroups.length;i++) |
|
|
{ |
|
|
if(commonChartPropertyGroups[i].groupVariableName!="layout") |
|
|
optionsString+=",\""+commonChartPropertyGroups[i].groupVariableName+"\":{\"dummy1\":1"; |
|
|
for(var k=0;k < commonChartProperties.length;k++) |
|
|
{ |
|
|
if(commonChartProperties[k].groupVariableName==commonChartPropertyGroups[i].groupVariableName |
|
|
&& commonChartProperties[k].variableName!="" |
|
|
&& getCommonChartProperty(commonChartProperties[k].name)!="") |
|
|
{ |
|
|
textDelim=(commonChartProperties[k].propValueType=="string")?"\"":""; |
|
|
optionsString+=",\""+commonChartProperties[k].variableName+"\":"+textDelim+getCommonChartProperty(commonChartProperties[k].name)+textDelim; |
|
|
} |
|
|
} |
|
|
if(commonChartPropertyGroups[i].groupVariableName!="layout") |
|
|
optionsString+=" }"; //close tag |
|
|
} |
|
|
//optionsString+= ",\"y\":{\"label\":\"Semester\"}"; |
|
|
optionsString+= ", \"marks\":[]"; |
|
|
//optionsString+= ", \"marks\":"+JSON.stringify(marksArray)+""; |
|
|
optionsString+= ", \"caption\":\""+myCaption+"\""; |
|
|
optionsString+=" }"; //close options tag |
|
|
console.log("options:"+ optionsString); |
|
|
|
|
|
var stylesString="{\"overflow\": \"visible\""; |
|
|
|
|
|
for(var k=0;k < commonChartProperties.length;k++) |
|
|
{ |
|
|
if(commonChartProperties[k].groupUniquename=="STYLE" ) |
|
|
{ |
|
|
stylesString+=",\""+commonChartProperties[k].variableName+"\":\""+getCommonChartProperty(commonChartProperties[k].name)+"\""; |
|
|
} |
|
|
|
|
|
} |
|
|
stylesString+=" }"; |
|
|
|
|
|
console.log("Styles:"+ stylesString); |
|
|
var styles=JSON.parse(stylesString); |
|
|
var chartOptions=JSON.parse(optionsString); |
|
|
chartOptions["marks"].push(marksArray); |
|
|
options=chartOptions; |
|
|
|
|
|
return options; |
|
|
} |
|
|
function makeAreaY(chartDivElem,selectionRs) { |
|
|
var categoryDim=document.getElementById("viz_dimension1").value; |
|
|
var measureDim=document.getElementById("viz_measure1").value; |
|
|
var marksArray=new Array(); |
|
|
marksArray[0]=Plot.areaY(selectionRs, |
|
|
{ |
|
|
y: measureDim, |
|
|
x: categoryDim |
|
|
}); |
|
|
marksArray[1]=Plot.ruleY([0]); |
|
|
|
|
|
var options= getChartOptions(categoryDim,"",measureDim,marksArray,true); |
|
|
|
|
|
document.getElementById(chartDivElem).appendChild(Plot.plot(options)); |
|
|
} |
|
|
function makeDot(chartDivElem,selectionRs) { |
|
|
var categoryDim=document.getElementById("viz_dimension1").value; |
|
|
var measureDim=document.getElementById("viz_measure1").value; |
|
|
var marksArray=new Array(); |
|
|
marksArray[0]=Plot.dot(selectionRs, |
|
|
{ |
|
|
y: measureDim, |
|
|
x: categoryDim |
|
|
}); |
|
|
marksArray[1]=Plot.ruleY([0]); |
|
|
//marksArray[2]=Plot.ruleX([0]); |
|
|
|
|
|
var options= getChartOptions(categoryDim,"",measureDim,marksArray,true); |
|
|
|
|
|
document.getElementById(chartDivElem).appendChild(Plot.plot(options)); |
|
|
} |
|
|
function makeLine(chartDivElem,selectionRs) { |
|
|
var categoryDim=document.getElementById("viz_dimension1").value; |
|
|
var measureDim=document.getElementById("viz_measure1").value; |
|
|
var marksArray=new Array(); |
|
|
marksArray[0]=Plot.line(selectionRs, |
|
|
{ |
|
|
y: measureDim, |
|
|
x: categoryDim, |
|
|
curve: "linear" |
|
|
}); |
|
|
marksArray[1]=Plot.dot(selectionRs, |
|
|
{ |
|
|
y: measureDim, |
|
|
x: categoryDim |
|
|
}); |
|
|
marksArray[2]=Plot.ruleY([0]); |
|
|
|
|
|
var options= getChartOptions(categoryDim,"",measureDim,marksArray,true); |
|
|
|
|
|
document.getElementById(chartDivElem).appendChild(Plot.plot(options)); |
|
|
} |
|
|
function makeBarY_alt(svg,data) { |
|
|
var xLabel=rsMetaData[document.getElementById("dimension1").value-1].colcaption; |
|
|
var yLabel=rsMetaData[document.getElementById("measure1").value-1].colcaption; |
|
|
var fontSize=getCommonChartProperty("fontSize"); |
|
|
var maxLenName=d3.max(data, d => d.name.length); |
|
|
var maxLenNamePx=maxLenName*fontSize/1.5; |
|
|
var marginLeftPx=xLabel.length*fontSize; |
|
|
|
|
|
var options = { |
|
|
marginBottom:maxLenNamePx, |
|
|
marginLeft:marginLeftPx, |
|
|
x: { |
|
|
tickRotate: -45 |
|
|
}, |
|
|
// set y axis options |
|
|
y: { |
|
|
grid:true, |
|
|
label: yLabel |
|
|
}, |
|
|
|
|
|
marks: [ |
|
|
Plot.barY(data, |
|
|
Plot.groupX( |
|
|
{y: "sum"}, |
|
|
{ |
|
|
x: "name", |
|
|
y: "value" |
|
|
} |
|
|
) |
|
|
) |
|
|
] |
|
|
} |
|
|
|
|
|
document.getElementById("chartDiv").appendChild(Plot.plot(options)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function getChartPropertyValue(propArray,propName) |
|
|
{ |
|
|
var propertyValue=""; |
|
|
for (var i=0;i<propArray.length;i++) |
|
|
{ |
|
|
if(propArray[i].name==propName ) |
|
|
{ |
|
|
propertyValue=propArray[i].propertyValue; |
|
|
if(propArray[i].propUnit && propArray[i].propUnit !="") |
|
|
propertyValue+=propArray[i].propUnit; |
|
|
} |
|
|
|
|
|
} |
|
|
return propertyValue; |
|
|
} |
|
|
function getCommonChartPropertyFromModel(myCommonChartProperties,name) |
|
|
{ |
|
|
var propertyValue=""; |
|
|
if(myCommonChartProperties && myCommonChartProperties.length>0) |
|
|
{ |
|
|
let prop = myCommonChartProperties.find(o => o.name === name); |
|
|
if(prop) |
|
|
propertyValue=prop.propertyValue; |
|
|
} |
|
|
//if no value is set from model, retrieve the default value: |
|
|
if(propertyValue=="") |
|
|
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<commonChartProperties.length;i++) |
|
|
{ |
|
|
if(commonChartProperties[i].name==name && document.forms["chartPropertiesForm"].elements[name]) |
|
|
{ |
|
|
propertyValue=document.forms["chartPropertiesForm"].elements[name].value; |
|
|
if(propertyValue=="" && commonChartProperties[i].defaultValue!="") |
|
|
{ |
|
|
propertyValue=commonChartProperties[i].defaultValue; |
|
|
} |
|
|
} |
|
|
}*/ |
|
|
return propertyValue; |
|
|
} |
|
|
function showSrcCode(renderer) |
|
|
{ |
|
|
var myChartDiv= document.getElementById("chartDiv2"); |
|
|
var mySrcDiv=document.getElementById("chartSVGsrc"); |
|
|
if(mySrcDiv.style.display=="block") |
|
|
mySrcDiv.style.display="none"; |
|
|
else |
|
|
mySrcDiv.style.display="block"; |
|
|
|
|
|
var numberOfChildNodes=myChartDiv.childNodes.length; |
|
|
var svg_xml =""; |
|
|
|
|
|
if(numberOfChildNodes>0) |
|
|
{ |
|
|
switch (renderer) { |
|
|
case "plot": |
|
|
for (var i=0;i<numberOfChildNodes;i++) |
|
|
{ |
|
|
var myNode=myChartDiv.childNodes[i]; |
|
|
var mySvg=myNode; |
|
|
// Extract the data as SVG text string |
|
|
svg_xml += (new XMLSerializer).serializeToString(mySvg); |
|
|
} |
|
|
break; |
|
|
case "d3js": |
|
|
for (var i=0;i<numberOfChildNodes;i++) |
|
|
{ |
|
|
var myNode=myChartDiv.childNodes[i]; |
|
|
if(myNode.nodeName=="svg") |
|
|
{ |
|
|
var mySvg=myNode; |
|
|
// Extract the data as SVG text string |
|
|
svg_xml = (new XMLSerializer).serializeToString(mySvg); |
|
|
} |
|
|
} |
|
|
break; |
|
|
default: |
|
|
document.getElementById("chartSrc").innerHTML="Unbekannter Renderer"; |
|
|
break; |
|
|
} |
|
|
document.getElementById("chartSrc").innerHTML=svg_xml; |
|
|
} |
|
|
else |
|
|
{ |
|
|
document.getElementById("chartSrc").innerHTML="Kein Quellcode gefunden"; |
|
|
} |
|
|
|
|
|
|
|
|
//document.getElementById("chartSVGsrc").style.visibility="visible"; |
|
|
/* |
|
|
const selection = window.getSelection(); |
|
|
const range = document.createRange(); |
|
|
range.selectNodeContents(ergtabelle); |
|
|
selection.removeAllRanges(); |
|
|
selection.addRange(range); |
|
|
|
|
|
document.execCommand('copy'); |
|
|
selection.removeAllRanges(); |
|
|
|
|
|
alert("Angezeigte Tabelle wurde in die Zwischenablage kopiert."); |
|
|
*/ |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function showChartModelCode() |
|
|
{ |
|
|
var mySrcDiv=document.getElementById("chartModelsrc"); |
|
|
if(mySrcDiv.style.display=="block") |
|
|
mySrcDiv.style.display="none"; |
|
|
else |
|
|
mySrcDiv.style.display="block"; |
|
|
|
|
|
updateChartModelCode(myChartModel); |
|
|
|
|
|
|
|
|
} |
|
|
function showPlotCode() |
|
|
{ |
|
|
var mySrcDiv=document.getElementById("plotCodeTextAreaDiv"); |
|
|
if(mySrcDiv.style.display=="block") |
|
|
mySrcDiv.style.display="none"; |
|
|
else |
|
|
mySrcDiv.style.display="block"; |
|
|
|
|
|
} |
|
|
|
|
|
function updateChartModelCode(myChartModel) |
|
|
{ |
|
|
var myCodeDiv= document.getElementById("chartModelSrcCode"); |
|
|
var myJson =""; |
|
|
if(myChartModel) |
|
|
{ |
|
|
myJson=JSON.stringify(myChartModel); |
|
|
myCodeDiv.innerHTML=myJson; |
|
|
myCodeDiv.value=myJson; |
|
|
} |
|
|
else |
|
|
{ |
|
|
myCodeDiv.innerHTML="Kein Quellcode gefunden"; |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
function loadChartModelCode(chartModelSrcCodeTextarea,chartDiv) |
|
|
{ |
|
|
|
|
|
var mySrc=document.getElementById(chartModelSrcCodeTextarea); |
|
|
var myJsonString =mySrc.value; |
|
|
|
|
|
if(myJsonString!="") |
|
|
{ |
|
|
myChartModel=JSON.parse(myJsonString); |
|
|
if(myChartModel) |
|
|
{ |
|
|
document.getElementById("vizElementCounter").value=myChartModel.chartElements.length; |
|
|
renderChart(chartDiv,myChartModel) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
function copySrcCode(mydiv) |
|
|
{ |
|
|
var ergtabelle=document.getElementById(mydiv); |
|
|
const selection = window.getSelection(); |
|
|
const range = document.createRange(); |
|
|
range.selectNodeContents(ergtabelle); |
|
|
selection.removeAllRanges(); |
|
|
selection.addRange(range); |
|
|
|
|
|
document.execCommand('copy'); |
|
|
selection.removeAllRanges(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function makeHisto() { |
|
|
d3.csv( "/superx/xml/js/d3/dense.csv" ).then( function( data ) { |
|
|
var histo = d3.histogram().value( d=>+d.A )( data ); |
|
|
var height=400; |
|
|
var scX = d3.scaleBand().padding( 0.2 ).round( true ) |
|
|
.range( [15, 515] ).domain( histo ); |
|
|
|
|
|
var scY = d3.scaleLinear().range( [height, 0] ) |
|
|
.domain( [0, d3.max( histo, d=>d.length ) ] ).nice(); |
|
|
|
|
|
var g = d3.select("#chartDiv").append("svg") |
|
|
.append( "g" ).attr( "transform", "translate( 40,50 )" ) |
|
|
|
|
|
g.selectAll( "rect" ).data( histo ).enter() |
|
|
.append( "rect" ).attr( "width", scX.bandwidth() ) |
|
|
.attr( "x", scX ).attr( "y", d=>scY(d.length) ) |
|
|
.attr( "height", d => height-scY(d.length) ) |
|
|
.attr( "fill", "red" ).attr( "fill-opacity", 0.2 ) |
|
|
.attr( "stroke", "red" ).attr( "stroke-width", 2 ) |
|
|
|
|
|
g.selectAll( "text" ).data( histo ).enter().append( "text" ) |
|
|
.attr( "text-anchor", "middle" ) |
|
|
.attr( "font-family", "sans-serif" ) |
|
|
.attr( "font-size", 14 ) |
|
|
.attr( "x", d => scX(d)+0.5*scX.bandwidth() ) |
|
|
.attr( "y", 225 ) |
|
|
.text( d=>(d.x0+d.x1)/2 ); |
|
|
|
|
|
g.append( "g" ).call( d3.axisLeft(scY) ); |
|
|
} ); |
|
|
} |
|
|
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 showVizNavTab(nr) |
|
|
{ |
|
|
|
|
|
for (let i = 1; i < 4; i++) { |
|
|
var divName="tab-"+i; |
|
|
//alert(divName); |
|
|
tabDivElem=document.getElementById(divName); |
|
|
if(i==nr) |
|
|
tabDivElem.style.display="block"; |
|
|
else |
|
|
tabDivElem.style.display="none"; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
function makeWorldmapD3(myCommonChartProperties,mySvg,data,metaData,chartElem) |
|
|
{ |
|
|
// load the data |
|
|
var captionEmptyTarget=getCommonChartPropertyFromModel(myCommonChartProperties,"null_value_mask"); |
|
|
renderWorldMap(myCommonChartProperties,mySvg,data); |
|
|
|
|
|
} |
|
|
function renderWorldMap(myCommonChartProperties,mySvg,data) |
|
|
{ |
|
|
const worldWidth = 960; |
|
|
const worldHeight = 600; |
|
|
|
|
|
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 |
|
|
}))*/ |
|
|
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 + "<br>" + (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); |
|
|
}); |
|
|
|
|
|
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=getCommonChartPropertyFromModel(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<chartElem.elementTypeProperties.length;k++) |
|
|
{ |
|
|
if(chartElem.elementTypeProperties[k].propertyValue!="") |
|
|
{ |
|
|
switch (chartElem.elementTypeProperties[k].vizTypePropertyUniquename) |
|
|
{ |
|
|
case "viz_measure1": |
|
|
measure1=chartElem.elementTypeProperties[k].propertyValue; |
|
|
measureCaption=getMetadataOfVizTypeProperty(metaData,measure1); |
|
|
if(measureCaption=="") |
|
|
measureCaption=measure1; |
|
|
break; |
|
|
default: |
|
|
break; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
return measureCaption; |
|
|
} |
|
|
function getMetadataOfVizTypeProperty(metaData,vizTypePropertyUniquename) |
|
|
{ |
|
|
var caption=""; |
|
|
for(var k=0;k<metaData.length;k++) |
|
|
{ |
|
|
if(metaData[k].colname==vizTypePropertyUniquename) |
|
|
{ |
|
|
caption=metaData[k].colcaption; |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
return caption; |
|
|
} |
|
|
function renderSankey(myCommonChartProperties,svg,sNodes,sLinks) |
|
|
{ |
|
|
// set the dimensions and margins of the graph |
|
|
var margin = { top: 10, right: 10, bottom: 10, left: 10 }, |
|
|
//var margin = { top: 0, right: 50, bottom: 0, left: 0 }, |
|
|
width = getCommonChartPropertyFromModel(myCommonChartProperties,"width") - margin.left - margin.right, |
|
|
height = getCommonChartPropertyFromModel(myCommonChartProperties,"height") - margin.top - margin.bottom; |
|
|
// format variables |
|
|
var formatNumber = d3.format(",.0f"), // zero decimal places |
|
|
format = function (d) { return formatNumber(d); }, |
|
|
color = d3.scaleOrdinal().range(["#002060ff", "#164490ff", "#4d75bcff", "#98b3e6ff", "#d5e2feff", "#008cb0ff"]); |
|
|
var textColor=getCommonChartPropertyFromModel(myCommonChartProperties,"color"); |
|
|
if(textColor=="") |
|
|
textColor="#3f3f3f"; |
|
|
var fontSize=getCommonChartPropertyFromModel(myCommonChartProperties,"fontSize"); |
|
|
if(fontSize=="") |
|
|
fontSize="12pt"; |
|
|
var fontFamily=getCommonChartPropertyFromModel(myCommonChartProperties,"fontFamily"); |
|
|
if(fontFamily=="") |
|
|
fontFamily="sans-serif"; |
|
|
// append the svg object to the body of the page |
|
|
/*const sankeyDiv = svg.selectAll("g") |
|
|
.attr("transform", |
|
|
"translate(" + margin.left + "," + margin.top + ")"); |
|
|
*/ |
|
|
// Set the sankey diagram properties |
|
|
var sankey = d3.sankey() |
|
|
.nodeWidth(100) |
|
|
.nodePadding(40) |
|
|
.size([width, height]); |
|
|
|
|
|
var path = sankey.links(); |
|
|
var data=new Object; |
|
|
data.nodes=sNodes; |
|
|
data.links=sLinks; |
|
|
var graph=sankey(data); |
|
|
|
|
|
// add in the links |
|
|
var link = svg.append("g").selectAll(".link") |
|
|
.data(graph.links) |
|
|
.enter().append("path") |
|
|
.attr("class", "link") |
|
|
.attr("d", d3.sankeyLinkHorizontal()) |
|
|
.attr("stroke-width", function (d) { return d.width; }); |
|
|
|
|
|
// add the link titles |
|
|
link.append("title") |
|
|
.text(function (d) { |
|
|
return d.source.name + " → " + |
|
|
d.target.name+": "+d.value; |
|
|
}); |
|
|
|
|
|
// add in the nodes |
|
|
var node = svg.append("g").selectAll(".node") |
|
|
.data(graph.nodes) |
|
|
.enter().append("g") |
|
|
.attr("class", "node") |
|
|
|
|
|
|
|
|
// add the rectangles for the nodes |
|
|
node.append("rect") |
|
|
.attr("x", function (d) { return d.x0; }) |
|
|
.attr("y", function (d) { return d.y0; }) |
|
|
.attr("height", function (d) { return d.y1 - d.y0; }) |
|
|
.attr("width", sankey.nodeWidth()) |
|
|
.style("fill", function (d) { |
|
|
var r = Math.floor(Math.random() * 255); |
|
|
var g = Math.floor(Math.random() * 255); |
|
|
var b = Math.floor(Math.random() * 255); |
|
|
var col = "rgb(" + r + "," + g + "," + b + ")"; |
|
|
return d.color = col; |
|
|
}) |
|
|
/*.style("fill", d3.schemaPastel2)*/ |
|
|
|
|
|
|
|
|
|
|
|
// Attempt at getting whole length of link to highlight |
|
|
.on("mouseover", function (d) { |
|
|
link |
|
|
.transition() |
|
|
.duration(300) |
|
|
.style("stroke-opacity", function (l) { |
|
|
return l.source === d || l.target === d ? 0.5 : 0.2; |
|
|
}); |
|
|
}) |
|
|
.on("mouseleave", function (d) { |
|
|
link |
|
|
.transition() |
|
|
.duration(300) |
|
|
.style("stroke-opacity", 0.2); |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
// Node hover titles |
|
|
.append("title") |
|
|
.text(function (d) { |
|
|
return d.name + "\n" + format(d.value); |
|
|
}); |
|
|
|
|
|
// add in the title for the nodes |
|
|
node.append("text") |
|
|
.style("fill", textColor) |
|
|
.attr("x", function (d) { return d.x0 - 6; }) |
|
|
.attr("y", function (d) { return (d.y1 + d.y0) / 2; }) |
|
|
.attr("dy", "0.35em") |
|
|
.attr("font-size",fontSize) |
|
|
.attr("font-family",fontFamily) |
|
|
.attr("text-anchor", "end") |
|
|
.text(function (d) { return d.name; }) |
|
|
.filter(function (d) { return d.x0 < width / 2; }) |
|
|
.attr("x", function (d) { return d.x1 + 6; }) |
|
|
.attr("text-anchor", "start") |
|
|
; |
|
|
// add in the title for the nodes |
|
|
/*node.append("text") |
|
|
.style("fill", textColor) |
|
|
.attr("x", function (d) { return d.x0 - 6; }) |
|
|
.attr("y", function (d) { return (d.y1 + d.y0) / 2; }) |
|
|
.attr("dy", "0.35em") |
|
|
|
|
|
.attr("text-anchor", "end") |
|
|
.text(function (d) { return d.name; }) |
|
|
.filter(function (d) { return d.x0 < width / 2; }) |
|
|
.attr("x", function (d) { return d.x1 + 6; }) |
|
|
.attr("text-anchor", "start") |
|
|
;*/ |
|
|
// add in the value labels for the nodes |
|
|
node.append("text") |
|
|
.style("fill", textColor) |
|
|
.attr("x", function (d) { return d.x0+20; }) //rechte Seite |
|
|
.attr("y", function (d) { return (d.y1 + d.y0) / 2; }) |
|
|
.attr("dy", "0.35em") |
|
|
.attr("font-size",fontSize) |
|
|
.attr("font-family",fontFamily) |
|
|
.attr("text-anchor", "start") |
|
|
.text(function (d) { return d.value; }) |
|
|
.filter(function (d) { return d.x0 < width / 2; }) |
|
|
.attr("x", function (d) { return d.x1 -40; }) //linke Seite |
|
|
.attr("text-anchor", "start") |
|
|
; |
|
|
} |
|
|
|
|
|
function openModalImage(ergebniselementOrdnr) |
|
|
{ |
|
|
var myModalCard=document.getElementById("modalCard"+ergebniselementOrdnr); |
|
|
myModalCard.classList.add('is-active'); |
|
|
} |
|
|
function closeModalImage(ergebniselementOrdnr) |
|
|
{ |
|
|
var myModalCard=document.getElementById("modalCard"+ergebniselementOrdnr); |
|
|
myModalCard.classList.remove('is-active'); |
|
|
} |
|
|
function openModalCardDetail(ergebniselementOrdnr) |
|
|
{ |
|
|
var myModalCard=document.getElementById("modalCardDetail"+ergebniselementOrdnr); |
|
|
myModalCard.classList.add('is-active'); |
|
|
} |
|
|
function closeModalCardDetail(ergebniselementOrdnr) |
|
|
{ |
|
|
var myModalCard=document.getElementById("modalCardDetail"+ergebniselementOrdnr); |
|
|
myModalCard.classList.remove('is-active'); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|