Browse Source

Obervable plot integrated, refactoring JS #3

makro_datasrc
Daniel Quathamer 2 years ago
parent
commit
56a467d882
  1. 13
      superx/xml/js/d3/plot-0.4.3-license.txt
  2. 2
      superx/xml/js/d3/plot.js
  3. 430
      superx/xml/js/d3/viz_functions.js
  4. 59
      superx/xml/viz_html_chart.xsl

13
superx/xml/js/d3/plot-0.4.3-license.txt

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
Copyright 2020-2022 Observable, Inc.
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.

2
superx/xml/js/d3/plot.js vendored

File diff suppressed because one or more lines are too long

430
superx/xml/js/d3/viz_functions.js vendored

@ -8,51 +8,189 @@ this.value=value; @@ -8,51 +8,189 @@ this.value=value;
}
function fillSelectFields()
{
fillSelectOptions("viz_category_dim",false);
fillSelectOptions("viz_measure_dim",true);
function chartPropertyValue(nr,name,value,isDefault )
{
this.nr=nr;
this.name=name;
this.value=value;
this.isDefault=isDefault;
}
function chartProperty(name,caption,isDynamic,isMeasure,isOptional,staticValues,defaultValue)
{
this.name=name;
this.caption=caption;
this.isDynamic=isDynamic;
this.isMeasure=isMeasure;
this.staticValues=staticValues;
this.isOptional=isOptional;
this.defaultValue=defaultValue;
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 chartPropertyValue(rsMetaData[j].nr,rsMetaData[j].colcaption,rsMetaData[j].colcaption,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 chartPropertyValue(k,staticValuesArray[k],staticValuesArray[k],isDefault);
valueOptions[k]=o;
}
}
return valueOptions;
}
}
function prepareChartProperties(chartType)
{
var chartProperties=[];
switch (chartType) {
case "bar_x":
chartProperties=prepareBarXForm();
break;
case "line":
chartProperties=prepareLineForm();
break;
default:
return false;
break;
}
renderForm("chartProperties",chartProperties,commonChartProperties);
return true;
}
function fillSelectOptions(fldSelectId,typeMeasureWanted)
function prepareBarXForm()
{
var chartProperties=[];
var propertyCounter=0;
var myProp= new chartProperty("viz_category_dim","Kategorie-Dimension",true,false,false,null,null);
chartProperties[0]=myProp;
var myProp= new chartProperty("viz_measure_dim","Maß",true,true,false,null,null);
chartProperties[1]=myProp;
return chartProperties;
}
function prepareLineForm()
{
var chartProperties=[];
var propertyCounter=0;
var myProp= new chartProperty("viz_category_dim","X-Achse",true,false,false,null,null);
chartProperties[0]=myProp;
var myProp= new chartProperty("viz_measure_dim","Y-Achse",true,true,false,null,null);
chartProperties[1]=myProp;
return chartProperties;
}
function renderForm(formDiv,chartProperties,myCommonChartProperties)
{
//first empty form:
var myForm=document.getElementById(formDiv);
while (myForm.firstChild) {
myForm.removeChild(myForm.firstChild);
}
//now fill it:
const tabElem = document.createElement("table");
myForm.appendChild(tabElem);
for(var k=0;k < chartProperties.length;k++)
{
const rowElem = document.createElement("tr");
const tdCap = document.createElement("td");
const textnode = document.createTextNode(chartProperties[k].caption);
tdCap.appendChild(textnode);
const tdSelElem = document.createElement("td");
const selElem = document.createElement("select");
selElem.name=chartProperties[k].name;
selElem.id=chartProperties[k].name;
fillSelectOptions(selElem,chartProperties[k].getValueResultset());
tdSelElem.appendChild(selElem);
rowElem.appendChild(tdCap);
rowElem.appendChild(tdSelElem);
//here values, and then:
tabElem.appendChild( rowElem);
}
/*
const rowElem = document.createElement("tr");
const tdCap = document.createElement("td");
const textnode = document.createTextNode("Breite");
tdCap.appendChild(textnode);
const tdInpElem = document.createElement("td");
const inpElem = document.createElement("input");
inpElem.id="viz_width";
inpElem.name="viz_width";
inpElem.type="text";
inpElem.value="800";
tdInpElem.appendChild(inpElem);
rowElem.appendChild(tdCap);
rowElem.appendChild(tdInpElem);
tabElem.appendChild(rowElem);
*/
myForm.appendChild(tabElem);
//TODO: myCommonChartProperties auf separatem TAB
}
function fillSelectOptions(myCombo,chartPropertyValues)
{
var optionCounter=0;
var myCombo=document.getElementById(fldSelectId);
var selectedOption=null;
while (myCombo.firstChild) {
myCombo.removeChild(myCombo.firstChild);
}
for(var j=0;j < rsMetaData.length;j++)
for(var j=0;j < chartPropertyValues.length;j++)
{
if(rsMetaData[j].colcaption.trim() !="" &&
(typeMeasureWanted==false || rsMetaData[j].coltype == 4 || rsMetaData[j].coltype == 3)
if(chartPropertyValues[j].isDefault)
selectedOption=j;
)
{
var o=new Option(rsMetaData[j].colcaption,rsMetaData[j].nr,null,null);
var o=new Option(chartPropertyValues[j].name,chartPropertyValues[j].nr,null,null);
myCombo.options[optionCounter]=o;
optionCounter++;
}
if(selectedOption!=null)
myCombo.selectedIndex=selectedOption;
}
}
function createChart()
/* alt:*/
function fillSelectFields()
{
fillSelectOptions("viz_category_dim",false);
fillSelectOptions("viz_measure_dim",true);
chartType=document.getElementById("viz_chart_type").value;
if(document.getElementById("viz_category_dim").value=="" ||
document.getElementById("viz_measure_dim").value=="" )
{
alert("Bitte wählen Sie eine Kategorie und ein Maß");
return false;
return true;
}
function prepareData()
{
var data=[];
//TODO: filld3ArrayofObjects
var colcount=rsMetaData.length;
var rowcount=rs.length;
var colnrOfCategorydimName=document.getElementById("viz_category_dim").value;
var colnrOfMeasure=document.getElementById("viz_measure_dim").value;
@ -73,46 +211,70 @@ for(j=1;j<rowcount;j++) @@ -73,46 +211,70 @@ for(j=1;j<rowcount;j++)
}
}
return data;
}
//alert(maxValue);
//var barLabel = function(d) { return d.name; };
//var barValue = function(d) { return parseInt(d.value); };
var valueLabelWidth = 20;
var barHeight = 18;
var barLabelWidth = 500;
var barLabelPadding = 10;
var gridLabelHeight = 18;
var gridChartOffset = 3;
var maxBarWidth = maxValue;
var fontSize=10;
var maxLenNamePx=maxLenName*fontSize;
//alert(maxLenNamePx);
//var width=420;
//var height=1420;
document.getElementById("chartDiv").innerHTML=""; //reset canvas
var chartWidth=document.getElementById("viz_width").value;
if(chartType=="bar")
function createChart()
{
var x = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).range([0, chartWidth]);
var y = d3.scaleBand().domain(data.map(d => d.nr)).range([0, barHeight * data.length]);
chartType=document.getElementById("viz_chart_type").value;
/*
if(document.getElementById("viz_category_dim").value=="" ||
document.getElementById("viz_measure_dim").value=="" )
{
alert("Bitte wählen Sie eine Kategorie und ein Maß");
return false;
}
*/
var data=[];
data=prepareData();
var svg = d3.select("#chartDiv").append("svg")
var valueLabelWidth = getCommonChartProperty("valueLabelWidth");
var fontFamily=getCommonChartProperty("fontFamily");
var gridLabelHeight = getCommonChartProperty("gridLabelHeight");
var gridChartOffset = getCommonChartProperty("gridChartOffset");
var chartWidth=getCommonChartProperty("chartWidth");
var fontSize=getCommonChartProperty("fontSize");
document.getElementById("chartDiv").innerHTML=""; //reset canvas
var svg = d3.select("#chartDiv").append("svg")
.attr("width", chartWidth) //maxBarWidth + barLabelWidth + valueLabelWidth)
.attr("height", y.range()[1])
.attr("font-family", "sans-serif")
//.attr("height", y.range()[1])
.attr("font-family", fontFamily)
.attr("font-size", fontSize)
.attr("text-anchor", "start")
.attr("id", "chartSVG")
;
switch (chartType)
{
case "bar_x":
makeBarX(svg,data);
//makeBarY(svg,data);
break;
case "line":
makeLine(svg,data);
break;
default:
alert("Please select a chart type");
break;
}
;
}
const bar = svg.selectAll("g")
function makeBarX(svg,data)
{
var barHeight = 18;
var barLabelWidth = 500;
var barLabelPadding = 10;
var maxBarWidth = maxValue;
var fontSize=getCommonChartProperty("fontSize");
var chartWidth=getCommonChartProperty("chartWidth");
var maxValue=d3.max(data, d => d.value);
var maxLenName=d3.max(data, d => d.name.length);
var maxLenNamePx=maxLenName*fontSize;
var x = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).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)})`)
@ -132,8 +294,8 @@ const bar = svg.selectAll("g") @@ -132,8 +294,8 @@ const bar = svg.selectAll("g")
.attr("width", d => x(d.value)) //x)
.attr("height", y.bandwidth() - 1)
;
//value label:
;
//value label:
bar.append("text")
.attr("fill", "white")
.attr("x", d => x(d.value)/2)
@ -141,7 +303,7 @@ const bar = svg.selectAll("g") @@ -141,7 +303,7 @@ const bar = svg.selectAll("g")
.attr("dy", "0.35em")
.attr("text-anchor","middle")
.text(d => d.value);
//label:
//label:
bar.append("text")
.attr("fill", "black")
.attr("x", 0)
@ -149,57 +311,97 @@ const bar = svg.selectAll("g") @@ -149,57 +311,97 @@ const bar = svg.selectAll("g")
.attr("dy", "0.35em")
.attr("text-anchor","end")
.text(d => d.name);
}
function makeLine(svg,data) {
var options = {
marginBottom:100,
x: {
tickRotate: -45,
ticks: 5,
tickSize: 5,
line: true,
tickPadding: 10,
labelAnchor: "left",
labelOffset: 0,
nice: true,
label: "My label",
type:"point"
},
// set y axis options
y: {
grid:true
},
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));
}
else {
//line chart:
// set the dimensions and margins of the graph
var margin = {top: 10, right: 30, bottom: 30, left: 60},
width = 1224 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
var y = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).range([height, 0 ]);
var x = d3.scaleBand().domain(data.map(d => d.name)).range([0, width]);
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom) //y.range()[1])
.attr("font-family", "sans-serif")
.attr("font-size", "10")
.attr("text-anchor", "end")
;
svg.append("g")
//.attr("transform","translate(" + margin.left + "," + margin.top + ")")
.attr("transform", "translate(0," + height + ")")
.attr("class", "x axis")
.call(d3.axisBottom(x));
// Add Y axis
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return +d.value; })])
.range([ height, 0 ]);
svg.append("g")
.call(d3.axisLeft(y));
// Add the line
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", d3.line()
.x(function(d) { return x(d.name) })
.y(function(d) { return y(d.value) })
function makeBarY(svg,data) {
var options = {
marginBottom:100,
x: {
tickRotate: -45,
ticks: 5,
tickSize: 5,
line: true,
tickPadding: 10,
labelAnchor: "left",
labelOffset: 0,
nice: true,
label: "My label"
},
// set y axis options
y: {
grid:true
},
sort: "nr",
// define the marks we will use, dots and a line
marks: [
//Plot.barY(data, Plot.groupX({x: "name", y: "value" }))
Plot.barY(
data,
Plot.groupX(
{ y: "sum" },
{
x: "name",
y: "value",
sort: {x:"nr"},
filter: null
}
)
)
]
//Plot.dot(data, {x: "nr", y: "value",sort: { x: "nr" } })
};
document.getElementById("chartDiv").appendChild(Plot.plot(options));
}
function getCommonChartProperty(name)
{
var propertyValue="";
for (var i=0;i<commonChartProperties.length;i++)
{
if(commonChartProperties[i].name==name)
propertyValue=commonChartProperties[i].defaultValue; //TODO aus formular übersteuern
}
return propertyValue;
}
function showSrcCode()
{
//alert(mydiv);
@ -235,3 +437,37 @@ var ergtabelle=document.getElementById(mydiv); @@ -235,3 +437,37 @@ var ergtabelle=document.getElementById(mydiv);
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) );
} );
}

59
superx/xml/viz_html_chart.xsl

@ -84,7 +84,8 @@ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:HtmlUtils="de.superx.util @@ -84,7 +84,8 @@ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:HtmlUtils="de.superx.util
<!-- end main -->
<!-- start css -->
<xsl:template name="tableCSS">
<style type="text/css">
<style type="text/css">
.dojoDialog {background : #eee; border : 1px solid #999;-moz-border-radius : 5px;padding : 4px;width:650;height:420px;overflow:scroll}
.treebutton {
border:none;
@ -115,7 +116,47 @@ padding:3px; @@ -115,7 +116,47 @@ padding:3px;
<!-- start Javascript-->
<xsl:template name="tableJavascript_viz">
<script language="Javascript" type="text/javascript" src="/superx/xml/js/d3/d3.min.js" />
<script language="Javascript" type="text/javascript" src="/superx/xml/js/d3/plot.js" />
<script><xsl:text>
//document.body.append(Plot.plot(options));
function commonChartProperty(name,caption,isOptional,staticValues,defaultValue)
{
this.name=name;
this.caption=caption;
this.staticValues=staticValues;
this.isOptional=isOptional;
this.defaultValue=defaultValue;
}
var commonChartProperties=[];
var newCommonChartProperty = new commonChartProperty("valueLabelWidth","Werte-Label Breite", null,true,20);
commonChartProperties.push(newCommonChartProperty);
var newCommonChartProperty = new commonChartProperty("gridLabelHeight","Grid-Label Höhe", null,true,18);
commonChartProperties.push(newCommonChartProperty);
var newCommonChartProperty = new commonChartProperty("gridChartOffset","Grid Offset", null,true,3);
commonChartProperties.push(newCommonChartProperty);
var newCommonChartProperty = new commonChartProperty("fontSize","Schriftgröße", null,false,10);
commonChartProperties.push(newCommonChartProperty);
var newCommonChartProperty = new commonChartProperty("font-family","Schriftart", null,false,"sans-serif");
commonChartProperties.push(newCommonChartProperty);
var newCommonChartProperty = new commonChartProperty("chartWidth","Breite des Diagramms", null,false,"800");
commonChartProperties.push(newCommonChartProperty);
var newCommonChartProperty = new commonChartProperty("chartCaption","Titel des Diagramms", null,false,"</xsl:text>
<xsl:value-of select="/ergebnisse/ergebnis/maskenname" /><xsl:text>");
commonChartProperties.push(newCommonChartProperty);
</xsl:text>
</script>
<script language="Javascript" type="text/javascript" src="/superx/xml/js/d3/viz_functions.js" />
</xsl:template>
<xsl:template name="tableJavascript">
@ -1127,14 +1168,18 @@ rs[</xsl:text><xsl:value-of select="$rownr"/><xsl:text>][</xsl:text><xsl:value-o @@ -1127,14 +1168,18 @@ rs[</xsl:text><xsl:value-of select="$rownr"/><xsl:text>][</xsl:text><xsl:value-o
</script>
<table border="0">
<tr><td>Diagrammtyp:</td>
<td><select class="maskinputPflicht" id="viz_chart_type" NAME="viz_chart_type" tabindex="200" onChange="fillSelectFields()" >
<td><select class="maskinputPflicht" id="viz_chart_type" NAME="viz_chart_type" tabindex="200" onChange="prepareChartProperties(this.value)" >
<option class="maskinput" value="">Bitte wählen</option>
<option class="maskinput" value="bar">Balkendiagramm horizontal (einfach)</option>
<option class="maskinput" value="bar_x">Balkendiagramm horizontal (einfach)</option>
<option class="maskinput" value="line">Liniendiagramm vertikal (einfach)</option>
</select>
</td>
</tr>
<tr><td>Kategorie-Dimension:</td>
</table>
<div id="chartProperties" style="background-color:ECEDEF;border:thin solid gray">
</div>
<!--<tr><td>Kategorie-Dimension:</td>
<td><select class="maskinputPflicht" id="viz_category_dim" NAME="viz_category_dim" tabindex="210">
<option class="maskinput" value="">Bitte wählen</option>
</select>
@ -1155,11 +1200,11 @@ Aggregatfunktion: <select class="maskinputPflicht" id="viz_measure_dim_func" NAM @@ -1155,11 +1200,11 @@ Aggregatfunktion: <select class="maskinputPflicht" id="viz_measure_dim_func" NAM
</td>
</tr>
<tr><td></td>
<td><input type="button" tabindex="10000" class="sx_buttondiv_submit" value="Diagramm erzeugen" onClick="createChart();" />
<td>
</td>
</tr>
</table>
<p>
</table>-->
<p><input type="button" tabindex="10000" class="sx_buttondiv_submit" value="Diagramm erzeugen" onClick="createChart();" />
</p>
<div id="chartDiv" style="border:thin solid black">
</div>

Loading…
Cancel
Save