Browse Source

Sankey chart mit Echarts #17

master
Daniel Quathamer 3 days ago
parent
commit
5388a890af
  1. 3
      src-modules/module/viz/conf/viz.xml
  2. 53
      src-modules/module/viz/schluesseltabellen/viz_properties_echarts_fuellen.sql
  3. 13
      src-modules/module/viz/schluesseltabellen/viz_properties_echarts_sankey_fuellen.sql
  4. 3
      src-modules/module/viz/upgrade/viz_upgrade_man.sql
  5. 271
      superx/xml/js/viz/viz_viewer.js

3
src-modules/module/viz/conf/viz.xml

@ -1181,6 +1181,8 @@ detail_chart_uniquename varchar(255)
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_line_bar_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_line_bar_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_pie_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_pie_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_sankey_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_d3js_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_d3js_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_d3js_pie_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_d3js_pie_fuellen.sql" database=""/>
@ -1373,6 +1375,7 @@ detail_chart_uniquename varchar(255)
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_line_bar_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_line_bar_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_pie_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_pie_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_echarts_sankey_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_d3js_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_d3js_fuellen.sql" database=""/>
<nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_d3js_pie_fuellen.sql" database=""/> <nativeaction sql="" scriptfile="$VIZ_PFAD/schluesseltabellen/viz_properties_d3js_pie_fuellen.sql" database=""/>

53
src-modules/module/viz/schluesseltabellen/viz_properties_echarts_fuellen.sql

@ -758,7 +758,7 @@
"parent_property_uniquename":"valueLabelNode", "parent_property_uniquename":"valueLabelNode",
"variableName":"distance_y" "variableName":"distance_y"
}, },
{ "caption":"Ausrichtung Wertelabel (vertikal)", { "caption":"Ausrichtung Wertelabel",
"prop_uniquename":"position_valueLabel", "prop_uniquename":"position_valueLabel",
"explanation":"", "explanation":"",
"prop_default":"inside", "prop_default":"inside",
@ -809,6 +809,57 @@
"parent_property_uniquename":"valueLabelNode", "parent_property_uniquename":"valueLabelNode",
"variableName":"offset_y_valueLabel" "variableName":"offset_y_valueLabel"
}, },
{ "caption":"Wertelabel Schriftart",
"prop_uniquename":"valueLabelFontFamily",
"explanation":"Wertelabel Schriftart",
"prop_default":"sans-serif",
"prop_unit":"",
"is_generic":"1",
"static_values":"",
"is_mandatory":"0",
"input_type_uniquename":"TEXT",
"property_group_uniquename":"",
"sortnr":"460",
"range_from":"",
"range_to":"",
"prop_value_type":"STRING",
"parent_property_uniquename":"valueLabelNode",
"variableName":"valueLabelFontFamily"
},
{ "caption":"Wertelabel Schriftgröße",
"prop_uniquename":"valueLabelFontSize",
"explanation":"Wertelabel Schriftgröße",
"prop_default":"1em",
"prop_unit":"",
"is_generic":"1",
"static_values":"",
"is_mandatory":"0",
"input_type_uniquename":"TEXT",
"property_group_uniquename":"",
"sortnr":"460",
"range_from":"",
"range_to":"",
"prop_value_type":"STRING",
"parent_property_uniquename":"valueLabelNode",
"variableName":"valueLabelFontSize"
},
{ "caption":"Wertelabel Schriftfarbe",
"prop_uniquename":"valueLabelFontColor",
"explanation":"Wertelabel Schriftfarbe",
"prop_default":"1em",
"prop_unit":"",
"is_generic":"1",
"static_values":"",
"is_mandatory":"0",
"input_type_uniquename":"COLOR",
"property_group_uniquename":"",
"sortnr":"480",
"range_from":"",
"range_to":"",
"prop_value_type":"STRING",
"parent_property_uniquename":"valueLabelNode",
"variableName":"valueLabelFontColor"
},
{ "caption":"Diagrammelement", { "caption":"Diagrammelement",
"prop_uniquename":"seriesNode", "prop_uniquename":"seriesNode",
"explanation":"Layout der Diagrammelemente", "explanation":"Layout der Diagrammelemente",

13
src-modules/module/viz/schluesseltabellen/viz_properties_echarts_sankey_fuellen.sql

@ -23,7 +23,18 @@
"is_mandatory":"1"}, "is_mandatory":"1"},
{"viz_property_uniquename":"measure1", {"viz_property_uniquename":"measure1",
"is_mandatory":"1"}, "is_mandatory":"1"},
{"viz_property_uniquename":"nodeGap"} {"viz_property_uniquename":"null_value_mask",
"is_mandatory":"0"},
{"viz_property_uniquename":"margin.left"},
{"viz_property_uniquename":"margin.top"},
{"viz_property_uniquename":"margin.right"},
{"viz_property_uniquename":"margin.bottom"},
{"viz_property_uniquename":"valueLabelShow"},
{"viz_property_uniquename":"valueLabelFontFamily"},
{"viz_property_uniquename":"valueLabelFontColor"},
{"viz_property_uniquename":"valueLabelFontSize"},
{"viz_property_uniquename":"position_valueLabel"}
] ]
/> />

3
src-modules/module/viz/upgrade/viz_upgrade_man.sql

@ -59,3 +59,6 @@ where T.uniquename in ('echarts_bar_x_series','echarts_bar_y_series','echarts_li
delete from viz_type delete from viz_type
where uniquename in ('echarts_bar_x_series','echarts_bar_y_series','echarts_line_x_series','echarts_line_y_series'); where uniquename in ('echarts_bar_x_series','echarts_bar_y_series','echarts_line_x_series','echarts_line_y_series');
--Sankey nicht mehr über d3js, sondern Echarts:
delete from viz_chart where is_custom=0
and uniquename='ERFOLG_BA_MA_SANKEY';

271
superx/xml/js/viz/viz_viewer.js

@ -191,6 +191,9 @@ function fillEchartsDataSet(myRs,myRsMetaData,currentChartModel,seriesDistinctCo
case "echarts_generic": case "echarts_generic":
dataset=fillEchartsDataSetSimpleCopy(myRs,myRsMetaData); dataset=fillEchartsDataSetSimpleCopy(myRs,myRsMetaData);
break; break;
case "echarts_sankey":
dataset=myRs;
break;
default: default:
//dataset=fillEchartsDataSetSimpleCopy(myRs,myRsMetaData); //dataset=fillEchartsDataSetSimpleCopy(myRs,myRsMetaData);
var seriesFldname=getChartElementPropertyValueFromModel(currentChartModel,"1","stroke"); var seriesFldname=getChartElementPropertyValueFromModel(currentChartModel,"1","stroke");
@ -1082,6 +1085,7 @@ renderSankey(myCommonChartProperties,mySvg,sNodes,sLinks);
function getSankeyNodes(data,captionEmptyTarget) function getSankeyNodes(data,captionEmptyTarget)
{ {
//obsolet
var myNodes=[]; var myNodes=[];
var distinctSource = []; var distinctSource = [];
@ -1114,6 +1118,7 @@ return myNodes;
function getSankeyLinks(myNodes,data) function getSankeyLinks(myNodes,data)
{ {
//obsolet
var myLinks=[]; var myLinks=[];
var linkIndex=0; var linkIndex=0;
@ -1136,6 +1141,7 @@ return myLinks;
} }
function getSankeyNodeIndex(myNodes,name) function getSankeyNodeIndex(myNodes,name)
{ {
//obsolet
var myIndex=0; var myIndex=0;
for (var i = 0; i < myNodes.length; i++) for (var i = 0; i < myNodes.length; i++)
{ {
@ -1185,6 +1191,7 @@ function getMetadataOfVizTypeProperty(metaData,vizTypePropertyUniquename)
} }
function renderSankey(myCommonChartProperties,svg,sNodes,sLinks) function renderSankey(myCommonChartProperties,svg,sNodes,sLinks)
{ {
//obsolet
// set the dimensions and margins of the graph // set the dimensions and margins of the graph
var margin = { top: 10, right: 10, bottom: 10, left: 10 }, var margin = { top: 10, right: 10, bottom: 10, left: 10 },
//var margin = { top: 0, right: 50, bottom: 0, left: 0 }, //var margin = { top: 0, right: 50, bottom: 0, left: 0 },
@ -2500,226 +2507,154 @@ function getEchartOptionsSankey(currentChartModel,myDataset)
var measure1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","measure1"); var measure1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","measure1");
var dimension1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","dimension1"); var dimension1Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","dimension1");
var dimension2Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","dimension2"); var dimension2Fldname=getChartElementPropertyValueFromModel(currentChartModel,"1","dimension2");
var titleText=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"caption"); var titleText=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"caption");
var subtitleText=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"subtitle"); var subtitleText=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"subtitle");
var scheme = getChartPropertyValue(currentChartModel.chartPropertiesUsed,"schemeArray"); var scheme = getChartPropertyValue(currentChartModel.chartPropertiesUsed,"schemeArray");
var myPalette=getPaletteArray(scheme,""); var myPalette=getPaletteArray(scheme,"");
var captionEmptyNode=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"null_value_mask");
if(captionEmptyNode=="")
captionEmptyNode="Leer";
/*const sourceData = [ var marginLeft=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.left");
{"rownr":1,"pj_ba_str":"2023","pj_ba_sem_von_str":"WiSe 2022/2023","pj_ba_sem_bis_str":"SoSe 2023","ba_abschluss_grp_str":"Bachelor","ba_abschluesse_summe":1964,"ma_sem_von_str":"WiSe 2022/2023","ma_sem_bis_str":"WiSe 2024/2025","ma_abschluss_grp_str":"LA Master","ma_anfaenger_summe":2,"ba_ma_ueberg_quote":0}, var marginRight=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.right");
{"rownr":2,"pj_ba_str":"2023","pj_ba_sem_von_str":"WiSe 2022/2023","pj_ba_sem_bis_str":"SoSe 2023","ba_abschluss_grp_str":"Bachelor","ba_abschluesse_summe":1964,"ma_sem_von_str":"WiSe 2022/2023","ma_sem_bis_str":"WiSe 2024/2025","ma_abschluss_grp_str":"Master","ma_anfaenger_summe":706,"ba_ma_ueberg_quote":0.36}, var marginTop=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.top");
{"rownr":3,"pj_ba_str":"2023","pj_ba_sem_von_str":"WiSe 2022/2023","pj_ba_sem_bis_str":"SoSe 2023","ba_abschluss_grp_str":"Bachelor","ba_abschluesse_summe":1964,"ma_sem_von_str":"WiSe 2022/2023","ma_sem_bis_str":"WiSe 2024/2025","ma_abschluss_grp_str":"kein Master","ma_anfaenger_summe":1256,"ba_ma_ueberg_quote":0.64}, var marginBottom=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"margin.bottom");
{"rownr":4,"pj_ba_str":"2023","pj_ba_sem_von_str":"WiSe 2022/2023","pj_ba_sem_bis_str":"SoSe 2023","ba_abschluss_grp_str":"LA Bachelor","ba_abschluesse_summe":1392,"ma_sem_von_str":"WiSe 2022/2023","ma_sem_bis_str":"WiSe 2024/2025","ma_abschluss_grp_str":"LA Master","ma_anfaenger_summe":1258,"ba_ma_ueberg_quote":0.9},
{"rownr":5,"pj_ba_str":"2023","pj_ba_sem_von_str":"WiSe 2022/2023","pj_ba_sem_bis_str":"SoSe 2023","ba_abschluss_grp_str":"LA Bachelor","ba_abschluesse_summe":1392,"ma_sem_von_str":"WiSe 2022/2023","ma_sem_bis_str":"WiSe 2024/2025","ma_abschluss_grp_str":"Master","ma_anfaenger_summe":21,"ba_ma_ueberg_quote":0.02},
{"rownr":6,"pj_ba_str":"2023","pj_ba_sem_von_str":"WiSe 2022/2023","pj_ba_sem_bis_str":"SoSe 2023","ba_abschluss_grp_str":"LA Bachelor","ba_abschluesse_summe":1392,"ma_sem_von_str":"WiSe 2022/2023","ma_sem_bis_str":"WiSe 2024/2025","ma_abschluss_grp_str":"kein Master","ma_anfaenger_summe":113,"ba_ma_ueberg_quote":0.08}
];*/
const sourceData =myDataset.source;
// DEBUG: Zeige die Rohdaten an
console.log('DATEN:', sourceData);
// Farbzuordnung (intensivere Töne für besseren Kontrast)
const colorMap = {
'Bachelor': '#3a5a2c',
'LA Bachelor': '#8a9e7a',
'Master': '#001e30',
'LA Master': '#5a7a90',
'kein Master': '#c0c8d0'
};
// ✅ Erstelle ein Map für die Gesamtwerte der Quellknoten (ba_abschluesse_summe)
const sourceTotalMap = new Map();
sourceData.forEach(row => { var valueLabelShow=(getChartPropertyValue(currentChartModel.chartPropertiesUsed,"valueLabelShow")=="true")?true:false;
const sourceName = row.ba_abschluss_grp_str; var valueLabelFontColor=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"valueLabelFontColor");
const total = row.ba_abschluesse_summe; var valueLabelFontSize=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"valueLabelFontSize");
var valueLabelFontFamily=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"valueLabelFontFamily");
var position_valueLabel=getChartPropertyValue(currentChartModel.chartPropertiesUsed,"position_valueLabel");
if (!sourceTotalMap.has(sourceName)) {
sourceTotalMap.set(sourceName, total);
} else if (sourceTotalMap.get(sourceName) !== total) {
console.warn(` Inkonsequenter Gesamtwert für Quellknoten "${sourceName}": ${total} vs ${sourceTotalMap.get(sourceName)}`);
}
});
// DEBUG: Zeige die Quellgesamtwerte an var dataNodeArray=new Array();
console.log('Gesamtwerte der Quellknoten (ba_abschluesse_summe):', Object.fromEntries(sourceTotalMap));
dataNodeArray=getDistinctColumnValuesAsSankeyNodes(myDataset,dimension1Fldname,dataNodeArray,captionEmptyNode);
dataNodeArray=getDistinctColumnValuesAsSankeyNodes(myDataset,dimension2Fldname,dataNodeArray,captionEmptyNode);
// ✅ Generiere die Links mit Farbverlauf (Gradienten) var linkArray=new Array();
const links = sourceData.map(row => {
const source = row.ba_abschluss_grp_str;
const target = row.ma_abschluss_grp_str;
const value = row.ma_anfaenger_summe;
const sourceColor = colorMap[source];
const targetColor = colorMap[target];
return { myDataset.forEach(row => {
source, var sourceName = row[dimension1Fldname].toString();
target, if(sourceName==""){
value, sourceName=captionEmptyNode;
lineStyle: {
width: 2,
color: echartsSankeyCreateGradientColor(sourceColor, targetColor),
opacity: 0.3
} }
var targetName = row[dimension2Fldname].toString();
if(targetName==""){
targetName=captionEmptyNode;
}
var linkValue=row[measure1Fldname];
var linkObj={source: sourceName,
target:targetName,
value: linkValue
}; };
}); linkArray.push(linkObj);
// DEBUG: Zeige die generierten Links an });
console.log('GENERIERTE LINKS mit Gradienten:', links);
// ECharts Option // ECharts Option
var option = { var option = {
title: { title: {
text: 'Übergang von Bachelor zu Master', text: titleText,
left: 'center', left: 'center',
textStyle: { fontSize: 16 } textStyle: { fontSize: "2em" }
}, },
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
triggerOn: 'mousemove', triggerOn: 'mousemove',
formatter: function (params) { formatter: function (params) {
if (params.dataType === 'node') { if (params.dataType === 'node') {
const nodeName = params.name; var nodeName = params.name;
return nodeName + ': ' + params.value.toLocaleString();
// Knotenfarbe als Tooltip-Farbe
const color = colorMap[nodeName] || '#ccc';
// Prüfe, ob der Knoten als Quelle oder Ziel vorkommt
const isSource = links.some(link => link.source === nodeName);
const isTarget = links.some(link => link.target === nodeName);
if (isSource && !isTarget) {
// Nur Quelle (links): Name + ba_abschluesse_summe
const total = sourceTotalMap.get(nodeName);
return `<span style="color:${color}; font-weight:bold">${nodeName}-Abschlüsse: ${total}`;
} else if (isTarget) {
// Ziel (rechts): Name + summierte ankommende Werte
const incomingValue = links
.filter(link => link.target === nodeName)
.reduce((sum, link) => sum + link.value, 0);
return `<span style="color:${color}; font-weight:bold">${nodeName}-Studiengänge: ${incomingValue}`;
} else {
return nodeName;
} }
} else { else
// Link-Tooltip { //link:
return params.data.source + ' --> ' + params.data.target + ': ' + params.data.value; return params.data.source + ' --> ' + params.data.target + ': ' + params.data.value.toLocaleString();
} }
} }
}, },
series: { series: {
name: 'Bachelor-Master Übergänge', name: titleText,
type: 'sankey', type: 'sankey',
layout: 'none', layout: 'center',
nodeGap: 25, // ← Erhöhter vertikaler Abstand //layoutIterations: 0, // Um automatische Sortierung zu deaktivieren
nodeWidth: 60, // ← Breite der Knoten //nodeOrder: ['Bachelor', 'Kein Master BUW','Master'] ,//'LA Bachelor', 'kein Bachelor an UzK', 'Master', 'LA Master', 'kein Master an UzK'],
emphasis: { nodeAlign: 'left',
focus: 'adjacency' nodeGap: 25, // Erhöhter vertikaler Abstand
}, nodeWidth: 60, // Breite der Knoten
data: [ edgeLabel:{ show: valueLabelShow,
{ fontFamily:valueLabelFontFamily,
name: 'Bachelor', color:valueLabelFontColor,
itemStyle: { color: colorMap['Bachelor'] }, fontSize:valueLabelFontSize,
label: { position: 'left', show: true, fontSize: 12, color: '#333' } formatter: function (params) {
}, return params.value.toLocaleString()
{ }
name: 'LA Bachelor',
itemStyle: { color: colorMap['LA Bachelor'] },
label: { position: 'left', show: true, fontSize: 12, color: '#333' }
},
{
name: 'Master',
itemStyle: { color: colorMap['Master'] },
label: { position: 'right', show: true, fontSize: 12, color: '#333' }
}, },
{ emphasis: {
name: 'LA Master', disabled:true
itemStyle: { color: colorMap['LA Master'] }, //focus: 'self' //'adjacency'
label: { position: 'right', show: true, fontSize: 12, color: '#333' }
}, },
{ data: dataNodeArray,
name: 'kein Master', links: linkArray,
itemStyle: { color: colorMap['kein Master'] },
label: { position: 'right', show: true, fontSize: 12, color: '#333' }
}
],
links: links,
label: { label: {
show: true, show: true,
fontSize: 12, fontFamily:valueLabelFontFamily,
color: '#333' color:valueLabelFontColor,
fontSize:"1em",
position:position_valueLabel,
distance:1
}, },
lineStyle: { lineStyle: {
width: 2, width: 2,
color: 'source' color: "gradient"
// , opacity: 0.9, // , opacity: 0.9,
// curveness: 0.3 // curveness: 0.3
}
}
};
var option2 = {
dataset: {
source: myDataset
},
title: {
text: titleText,
subtext: subtitleText,
left: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"title.left"), //"center",
top: getChartPropertyValue(currentChartModel.chartPropertiesUsed,"title.top"), //"top",
textStyle: {
fontSize: 20
},
subtextStyle: {
fontSize: 15
}
}, },
left:marginLeft,
top:marginTop,
right:marginRight,
bottom:marginBottom,
width:"100%"
series: [ }
{ };
type: 'pie',// sunburst
/*encode: {
value: measure1Fldname,
name: dimension1Fldname
},*/
tooltip: {
trigger: "item"
},
stillShowZeroSum: false,
label: { return option;
show: (getChartPropertyValue(currentChartModel.chartPropertiesUsed,"valueLabelShow")=="true")?true:false, //true
fontWeight:'bolder',
formatter: '{c}' }
function getDistinctColumnValuesAsSankeyNodes(myRs,fieldname,nodes,captionEmptyNode)
{
var distinctValues=new Array();
} , myRs.forEach(row => {
var newName = row[fieldname].toString();
if(newName=="")
newName=captionEmptyNode;
fontSize: 12, if( distinctValues.length==0)
radius: [getChartPropertyValue(currentChartModel.chartPropertiesUsed,"innerRadius"),getChartPropertyValue(currentChartModel.chartPropertiesUsed,"outerRadius")],// ['30%', '80%'], //1. Parameter inside radius, macht ihn zum Donut. 2.Parameter definiert den Anteil des Kreises am ganzen Viewport" {
color: myPalette, distinctValues.push(newName);
itemStyle: {
borderRadius: (getChartPropertyValue(currentChartModel.chartPropertiesUsed,"cornerRadiusRounded")=="true" ? [20, 5, 5, 10] :[]),
borderColor: '#fff',
borderWidth: 2
} }
else if( distinctValues.length>0 && !distinctValues.includes(newName))
{
distinctValues.push(newName);
} }
]
};
return option;
}
// ✅ Funktion: Erzeugt einen Farbverlauf von sourceColor zu targetColor });
function echartsSankeyCreateGradientColor(sourceColor, targetColor) { distinctValues.forEach(row => {
return { var nameObj={name:row};
type: 'linear', nodes.push(nameObj);
x: 0, y: 0, x2: 1, y2: 0, });
colorStops: [ return nodes;
{ offset: 0, color: sourceColor },
{ offset: 1, color: targetColor }
]
};
} }

Loading…
Cancel
Save