Browse Source

Obervable plot integrated, refactoring JS #3

makro_datasrc
Daniel Quathamer 3 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. 504
      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 @@
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

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

@ -8,51 +8,189 @@ this.value=value;
} }
function fillSelectFields() function chartPropertyValue(nr,name,value,isDefault )
{ {
fillSelectOptions("viz_category_dim",false); this.nr=nr;
fillSelectOptions("viz_measure_dim",true); 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; 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 optionCounter=0;
var myCombo=document.getElementById(fldSelectId); var selectedOption=null;
while (myCombo.firstChild) { while (myCombo.firstChild) {
myCombo.removeChild(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() !="" && if(chartPropertyValues[j].isDefault)
(typeMeasureWanted==false || rsMetaData[j].coltype == 4 || rsMetaData[j].coltype == 3) selectedOption=j;
) var o=new Option(chartPropertyValues[j].name,chartPropertyValues[j].nr,null,null);
{
var o=new Option(rsMetaData[j].colcaption,rsMetaData[j].nr,null,null);
myCombo.options[optionCounter]=o; myCombo.options[optionCounter]=o;
optionCounter++; 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=="" || return true;
document.getElementById("viz_measure_dim").value=="" )
{
alert("Bitte wählen Sie eine Kategorie und ein Maß");
return false;
} }
function prepareData()
{
var data=[]; var data=[];
//TODO: filld3ArrayofObjects //TODO: filld3ArrayofObjects
var colcount=rsMetaData.length;
var rowcount=rs.length; var rowcount=rs.length;
var colnrOfCategorydimName=document.getElementById("viz_category_dim").value; var colnrOfCategorydimName=document.getElementById("viz_category_dim").value;
var colnrOfMeasure=document.getElementById("viz_measure_dim").value; var colnrOfMeasure=document.getElementById("viz_measure_dim").value;
@ -73,133 +211,197 @@ for(j=1;j<rowcount;j++)
} }
} }
return data;
}
//alert(maxValue); function createChart()
//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")
{ {
var x = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).range([0, chartWidth]); chartType=document.getElementById("viz_chart_type").value;
var y = d3.scaleBand().domain(data.map(d => d.nr)).range([0, barHeight * data.length]); /*
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("width", chartWidth) //maxBarWidth + barLabelWidth + valueLabelWidth)
.attr("height", y.range()[1]) //.attr("height", y.range()[1])
.attr("font-family", "sans-serif") .attr("font-family", fontFamily)
.attr("font-size", fontSize) .attr("font-size", fontSize)
.attr("text-anchor", "start") .attr("text-anchor", "start")
.attr("id", "chartSVG") .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)
.data(data) {
.join("g") var barHeight = 18;
.attr("transform", d => `translate(${maxLenNamePx},${y(d.nr)})`) var barLabelWidth = 500;
; var barLabelPadding = 10;
var maxBarWidth = maxValue;
bar.append("rect") var fontSize=getCommonChartProperty("fontSize");
.attr("fill", "steelblue") var chartWidth=getCommonChartProperty("chartWidth");
.on("mouseover",function(){ var maxValue=d3.max(data, d => d.value);
d3.select(this).attr("fill", "red"); var maxLenName=d3.max(data, d => d.name.length);
}) var maxLenNamePx=maxLenName*fontSize;
.on("mouseout",function(){ var x = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).range([0, chartWidth]);
d3.select(this).attr("fill", "steelblue"); var y = d3.scaleBand().domain(data.map(d => d.nr)).range([0, barHeight * data.length]);
}) const bar = svg.selectAll("g")
.transition() .data(data)
.duration(750) .join("g")
.delay(function(d, i) { return i * 10; }) .attr("transform", d => `translate(${maxLenNamePx},${y(d.nr)})`)
.attr("width", d => x(d.value)) //x) ;
.attr("height", y.bandwidth() - 1)
bar.append("rect")
; .attr("fill", "steelblue")
//value label: .on("mouseover",function(){
bar.append("text") d3.select(this).attr("fill", "red");
.attr("fill", "white") })
.attr("x", d => x(d.value)/2) .on("mouseout",function(){
.attr("y", (y.bandwidth() - 1) / 2) d3.select(this).attr("fill", "steelblue");
.attr("dy", "0.35em") })
.attr("text-anchor","middle") .transition()
.text(d => d.value); .duration(750)
//label: .delay(function(d, i) { return i * 10; })
bar.append("text") .attr("width", d => x(d.value)) //x)
.attr("fill", "black") .attr("height", y.bandwidth() - 1)
.attr("x", 0)
.attr("y", (y.bandwidth() - 1) / 2) ;
.attr("dy", "0.35em") //value label:
.attr("text-anchor","end") bar.append("text")
.text(d => d.name); .attr("fill", "white")
.attr("x", d => x(d.value)/2)
.attr("y", (y.bandwidth() - 1) / 2)
} .attr("dy", "0.35em")
else { .attr("text-anchor","middle")
//line chart: .text(d => d.value);
//label:
bar.append("text")
// set the dimensions and margins of the graph .attr("fill", "black")
var margin = {top: 10, right: 30, bottom: 30, left: 60}, .attr("x", 0)
width = 1224 - margin.left - margin.right, .attr("y", (y.bandwidth() - 1) / 2)
height = 600 - margin.top - margin.bottom; .attr("dy", "0.35em")
.attr("text-anchor","end")
var y = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).range([height, 0 ]); .text(d => d.name);
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 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));
} }
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() function showSrcCode()
{ {
//alert(mydiv); //alert(mydiv);
@ -235,3 +437,37 @@ var ergtabelle=document.getElementById(mydiv);
document.execCommand('copy'); document.execCommand('copy');
selection.removeAllRanges(); 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
<!-- end main --> <!-- end main -->
<!-- start css --> <!-- start css -->
<xsl:template name="tableCSS"> <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} .dojoDialog {background : #eee; border : 1px solid #999;-moz-border-radius : 5px;padding : 4px;width:650;height:420px;overflow:scroll}
.treebutton { .treebutton {
border:none; border:none;
@ -115,7 +116,47 @@ padding:3px;
<!-- start Javascript--> <!-- start Javascript-->
<xsl:template name="tableJavascript_viz"> <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/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" /> <script language="Javascript" type="text/javascript" src="/superx/xml/js/d3/viz_functions.js" />
</xsl:template> </xsl:template>
<xsl:template name="tableJavascript"> <xsl:template name="tableJavascript">
@ -1127,14 +1168,18 @@ rs[</xsl:text><xsl:value-of select="$rownr"/><xsl:text>][</xsl:text><xsl:value-o
</script> </script>
<table border="0"> <table border="0">
<tr><td>Diagrammtyp:</td> <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="">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> <option class="maskinput" value="line">Liniendiagramm vertikal (einfach)</option>
</select> </select>
</td> </td>
</tr> </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"> <td><select class="maskinputPflicht" id="viz_category_dim" NAME="viz_category_dim" tabindex="210">
<option class="maskinput" value="">Bitte wählen</option> <option class="maskinput" value="">Bitte wählen</option>
</select> </select>
@ -1155,11 +1200,11 @@ Aggregatfunktion: <select class="maskinputPflicht" id="viz_measure_dim_func" NAM
</td> </td>
</tr> </tr>
<tr><td></td> <tr><td></td>
<td><input type="button" tabindex="10000" class="sx_buttondiv_submit" value="Diagramm erzeugen" onClick="createChart();" /> <td>
</td> </td>
</tr> </tr>
</table> </table>-->
<p> <p><input type="button" tabindex="10000" class="sx_buttondiv_submit" value="Diagramm erzeugen" onClick="createChart();" />
</p> </p>
<div id="chartDiv" style="border:thin solid black"> <div id="chartDiv" style="border:thin solid black">
</div> </div>

Loading…
Cancel
Save