Skip to content

Commit

Permalink
chart modules | data points -> added the possibility to add additiona…
Browse files Browse the repository at this point in the history
…lly datapoint arrays besides simple data arrays to the charts. The current advantage of using data point arrays is that you can define actionhandlers for each data point which will be executed when clicking on a data point in the chart (currently supported by module_jqplot only)

changes for jqplot charts: - BUG: chart will now be displayed even it contains no data
NEW: width of bar charts is now larger
  • Loading branch information
spoonguard2k committed Oct 1, 2014
1 parent 7b9ae76 commit c15c77b
Show file tree
Hide file tree
Showing 9 changed files with 665 additions and 139 deletions.
142 changes: 110 additions & 32 deletions module_ezcchart/system/class_graph_ezc.php
Expand Up @@ -92,16 +92,34 @@ public function __construct() {
* $objGraph->setStrXAxisTitle("x-axis");
* $objGraph->setStrYAxisTitle("y-axis");
* $objGraph->setStrGraphTitle("Test Graph");
* $objGraph->addBarChartSet(array(1,2,4,5) "serie 1");
*
* @param array $arrValues see the example above for the internal array-structure
* //simple array
* $objGraph->addBarChartSet(array(1,2,4,5) "serie 1");
*
* //datapoints array
* $objDataPoint1 = new class_graph_datapoint(1);
* $objDataPoint2 = new class_graph_datapoint(2);
* $objDataPoint3 = new class_graph_datapoint(4);
* $objDataPoint4 = new class_graph_datapoint(5);
*
* //set action handler example
* $objDataPoint1->setObjActionHandler("<javascript code here>");
* $objDataPoint1->getObjActionHandlerValue("<value_object> e.g. some json");
*
* $objGraph->addBarChartSet(array($objDataPoint1, $objDataPoint2, $objDataPoint3, $objDataPoint4) "serie 1");
*
*
* @param array $arrValues - an array with simple values or an array of data points (class_graph_datapoint).
* The advantage of a data points are that action handlers can be defined for each data point which will be executed when clicking on the data point in the chart.
* @param string $strLegend
* @param bool $bitWriteValues Enables the rendering of values on top of the graphs
*
* @throws class_exception
* @return void
*/
public function addBarChartSet($arrValues, $strLegend, $bitWriteValues = false) {
$arrDataPoints = class_graph_commons::convertArrValuesToDataPointArray($arrValues);

if($this->intCurrentGraphMode > 0) {
//only allow this method to be called again if in bar-mode
if($this->intCurrentGraphMode != $this->GRAPH_TYPE_BAR && $this->intCurrentGraphMode != $this->GRAPH_TYPE_STACKEDBAR) {
Expand All @@ -113,15 +131,16 @@ public function addBarChartSet($arrValues, $strLegend, $bitWriteValues = false)

$arrEntries = array();
$intCounter = 0;
foreach($arrValues as $strValue) {
$arrEntries[$this->getArrXAxisEntry($intCounter)] = $strValue;
foreach($arrDataPoints as $objDataPoint) {
$floatValue = $objDataPoint->getFloatValue();
$arrEntries[$this->getArrXAxisEntry($intCounter)] = $floatValue;

if($strValue > $this->intMaxValue && $this->intCurrentGraphMode != $this->GRAPH_TYPE_STACKEDBAR) {
$this->intMaxValue = $strValue;
if($floatValue > $this->intMaxValue && $this->intCurrentGraphMode != $this->GRAPH_TYPE_STACKEDBAR) {
$this->intMaxValue = $floatValue;
}

if($strValue < $this->intMinValue && $this->intCurrentGraphMode != $this->GRAPH_TYPE_STACKEDBAR) {
$this->intMinValue = $strValue;
if($floatValue < $this->intMinValue && $this->intCurrentGraphMode != $this->GRAPH_TYPE_STACKEDBAR) {
$this->intMinValue = $floatValue;
}

$intCounter++;
Expand All @@ -143,16 +162,36 @@ public function addBarChartSet($arrValues, $strLegend, $bitWriteValues = false)
* $objGraph->setStrXAxisTitle("x-axis");
* $objGraph->setStrYAxisTitle("y-axis");
* $objGraph->setStrGraphTitle("Test Graph");
* $objGraph->addStackedBarChartSet(array(1,2,4,5) "serie 1");
* $objGraph->addStackedBarChartSet(array(1,2,4,5) "serie 2");
*
* @param array $arrValues see the example above for the internal array-structure
*
* //simple array
* $objGraph->addStackedBarChartSet(array(1,2,4,5) "serie 1");
* $objGraph->addStackedBarChartSet(array(1,2,4,5) "serie 2");
*
* //datapoints array
* $objDataPoint1 = new class_graph_datapoint(1);
* $objDataPoint2 = new class_graph_datapoint(2);
* $objDataPoint3 = new class_graph_datapoint(4);
* $objDataPoint4 = new class_graph_datapoint(5);
*
* //set action handler example
* $objDataPoint1->setObjActionHandler("<javascript code here>");
* $objDataPoint1->getObjActionHandlerValue("<value_object> e.g. some json");
*
* $objGraph->addStackedBarChartSet(array($objDataPoint1, $objDataPoint2, $objDataPoint3, $objDataPoint4) "serie 1");
*
*
* @param array $arrValues - an array with simple values or an array of data points (class_graph_datapoint).
* The advantage of a data points are that action handlers can be defined for each data point which will be executed when clicking on the data point in the chart.
* @param string $strLegend
*
* @throws class_exception
* @return void
*/
public function addStackedBarChartSet($arrValues, $strLegend) {
$arrDataPoints = class_graph_commons::convertArrValuesToDataPointArray($arrValues);


if($this->intCurrentGraphMode > 0) {
//only allow this method to be called again if in stackedbar-mode
if($this->intCurrentGraphMode != $this->GRAPH_TYPE_STACKEDBAR) {
Expand All @@ -163,21 +202,22 @@ public function addStackedBarChartSet($arrValues, $strLegend) {
//add max value from each set to max value
$intMax = 0;
$intMin = 0;
foreach($arrValues as $strValue) {
if($strValue > $intMax) {
$intMax = $strValue;
foreach($arrDataPoints as $objDataPoint) {
$floatValue = $objDataPoint->getFloatValue();
if($floatValue > $intMax) {
$intMax = $floatValue;
}

if($strValue < $intMin) {
$intMin = $strValue;
if($floatValue < $intMin) {
$intMin = $floatValue;
}
}

$this->intMaxValue += $intMax;
$this->intMinValue -= $intMin;

$this->intCurrentGraphMode = $this->GRAPH_TYPE_STACKEDBAR;
$this->addBarChartSet($arrValues, $strLegend);
$this->addBarChartSet(class_graph_commons::getDataPointFloatValues($arrDataPoints), $strLegend);
$this->intCurrentGraphMode = $this->GRAPH_TYPE_STACKEDBAR;

}
Expand All @@ -194,15 +234,33 @@ public function addStackedBarChartSet($arrValues, $strLegend) {
* $objGraph->setStrXAxisTitle("x-axis");
* $objGraph->setStrYAxisTitle("y-axis");
* $objGraph->setStrGraphTitle("Test Graph");
* $objGraph->addLinePlot(array(1,4,6,7,4), "serie 1");
*
* @param array $arrValues e.g. array(1,3,4,5,6)
* //simple array
* $objGraph->addLinePlot(array(1,4,6,7,4), "serie 1");
*
* //datapoints array
* $objDataPoint1 = new class_graph_datapoint(1);
* $objDataPoint2 = new class_graph_datapoint(2);
* $objDataPoint3 = new class_graph_datapoint(4);
* $objDataPoint4 = new class_graph_datapoint(5);
*
* //set action handler example
* $objDataPoint1->setObjActionHandler("<javascript code here>");
* $objDataPoint1->getObjActionHandlerValue("<value_object> e.g. some json");
*
* $objGraph->addLinePlot(array($objDataPoint1, $objDataPoint2, $objDataPoint3, $objDataPoint4) "serie 1");
*
*
* @param array $arrValues - an array with simple values or an array of data points (class_graph_datapoint).
* The advantage of a data points are that action handlers can be defined for each data point which will be executed when clicking on the data point in the chart.
* @param string $strLegend the name of the single plot
*
* @throws class_exception
* @return void
*/
public function addLinePlot($arrValues, $strLegend) {
$arrDataPoints = class_graph_commons::convertArrValuesToDataPointArray($arrValues);

if($this->intCurrentGraphMode > 0) {
//in bar mode, its ok. just place on top
if($this->intCurrentGraphMode != $this->GRAPH_TYPE_LINE && $this->intCurrentGraphMode != $this->GRAPH_TYPE_BAR) {
Expand All @@ -217,25 +275,26 @@ public function addLinePlot($arrValues, $strLegend) {

$arrEntries = array();
$intCounter = 0;
foreach($arrValues as $strValue) {
foreach($arrDataPoints as $objDataPoint) {
$floatValue = $objDataPoint->getFloatValue();
$strAxisLabel = $this->getArrXAxisEntry($intCounter);
if($strAxisLabel != "") {
$arrEntries[$strAxisLabel] = $strValue;
$arrEntries[$strAxisLabel] = $floatValue;
}
else {
$arrEntries[$intCounter + 1] = $strValue;
$arrEntries[$intCounter + 1] = $floatValue;
}

if($strValue < 0) {
$strValue *= -2;
if($floatValue < 0) {
$floatValue *= -2;
}

if($strValue > $this->intMaxValue) {
$this->intMaxValue = $strValue;
if($floatValue > $this->intMaxValue) {
$this->intMaxValue = $floatValue;
}

if($strValue < $this->intMinValue) {
$this->intMinValue = $strValue;
if($floatValue < $this->intMinValue) {
$this->intMinValue = $floatValue;
}

$intCounter++;
Expand All @@ -255,24 +314,43 @@ public function addLinePlot($arrValues, $strLegend) {
* A sample-code could be:
* $objChart = new class_graph();
* $objChart->setStrGraphTitle("Test Pie Chart");
* $objChart->createPieChart(array(2,6,7,3), array("val 1", "val 2", "val 3", "val 4"));
*
* @param array $arrValues
* //simple array
* $objChart->createPieChart(array(2,6,7,3), array("val 1", "val 2", "val 3", "val 4"));
*
* //datapoints array
* $objDataPoint1 = new class_graph_datapoint(1);
* $objDataPoint2 = new class_graph_datapoint(2);
* $objDataPoint3 = new class_graph_datapoint(4);
* $objDataPoint4 = new class_graph_datapoint(5);
*
* //set action handler example
* $objDataPoint1->setObjActionHandler("<javascript code here>");
* $objDataPoint1->getObjActionHandlerValue("<value_object> e.g. some json");
*
* $objGraph->createPieChart(array($objDataPoint1, $objDataPoint2, $objDataPoint3, $objDataPoint4) , array("val 1", "val 2", "val 3", "val 4"), "serie 1");
*
*
* @param array $arrValues - an array with simple values or an array of data points (class_graph_datapoint).
* The advantage of a data points are that action handlers can be defined for each data point which will be executed when clicking on the data point in the chart.
* @param array $arrLegends
*
* @throws class_exception
* @return void
*/
public function createPieChart($arrValues, $arrLegends) {
$arrDataPoints = class_graph_commons::convertArrValuesToDataPointArray($arrValues);

if($this->intCurrentGraphMode > 0) {
throw new class_exception("Chart already initialized", class_exception::$level_ERROR);
}

$this->intCurrentGraphMode = $this->GRAPH_TYPE_PIE;

$arrEntries = array();
foreach($arrValues as $intKey => $strValue) {
$arrEntries[$arrLegends[$intKey]] = $strValue;
foreach($arrDataPoints as $intKey => $objDataPoint) {
$floatValue = $objDataPoint->getFloatValue();
$arrEntries[$arrLegends[$intKey]] = $floatValue;
}

$objData = new ezcGraphArrayDataSet($arrEntries);
Expand Down
Expand Up @@ -10,18 +10,29 @@ if (!KAJONA) {
KAJONA.admin.jqplotHelper = {

previousNeighbor : null,//used in methods mouseLeave and mouseMove
arrChartObjects : [],
arrChartObjects : [],//container for all chart objects

jqPlotChart : function (strChartId, strTooltipId, strResizeableId, arrChartData, objChartOptions, objPostPlotOptions) {
/**
*
* @param strChartId - id of the chart
* @param strTooltipId - id of the tooltip of the chart
* @param strResizeableId - id of the resizable container
* @param arrChartData - data array for the chart
* @param objChartOptions - chart rendering options
* @param objPostPlotOptions - options set for pos plotting
* @param arrSeriesToDataPoints - two dimensional array which may contains urls for each data point of a series. format: array[seriesIndex][dataPointIndex] => strURL
*/
jqPlotChart : function (strChartId, strTooltipId, strResizeableId, arrChartData, objChartOptions, objPostPlotOptions, arrSeriesToDataPoints) {
this.strTooltipId = strTooltipId;
this.strChartId = strChartId;
this.strResizeableId = strResizeableId;
this.arrChartData = arrChartData;
this.objChartOptions = objChartOptions;
this.objPostPlotOptions = objPostPlotOptions;
this.arrSeriesToDataPoints = arrSeriesToDataPoints;

this.objJqplotChart = null;
this.bitIsRendered = false;
this.objJqplotChart = null;//the actual jqPlot object
this.bitIsRendered = false;//flag to tell if the chart was already rendered or not (needed in case the chart should replotted)

this.objChartOptions.axesDefaults.tickOptions.formatter = KAJONA.admin.jqplotHelper.customJqPlotNumberFormatter;

Expand Down Expand Up @@ -49,7 +60,9 @@ KAJONA.admin.jqplotHelper = {
*/
this.plot = function () {
this.objJqplotChart = $.jqplot(this.strChartId, this.arrChartData, this.objChartOptions);
KAJONA.admin.jqplotHelper.bindMouseEvents(this.strChartId, this.strTooltipId, this.strResizeableId);
KAJONA.admin.jqplotHelper.bindMouseEvents(this.strChartId, this.strTooltipId);
KAJONA.admin.jqplotHelper.bindDataClickEvents(this.strChartId);
KAJONA.admin.jqplotHelper.enableChartResizing(this.strChartId, this.strResizeableId);
};

/**
Expand All @@ -69,10 +82,7 @@ KAJONA.admin.jqplotHelper = {
KAJONA.admin.jqplotHelper.arrChartObjects[this.strChartId] = this;
},

bindMouseEvents : function (strChartId, strTooltipId, strResizeableId) {
$('#' + strChartId).bind('jqplotMouseMove', function (ev, gridpos, datapos, neighbor, plot) {KAJONA.admin.jqplotHelper.mouseMove(ev, gridpos, datapos, neighbor, plot, strTooltipId)});
$('#' + strChartId).bind('jqplotMouseLeave', function (ev, gridpos, datapos, neighbor, plot) {KAJONA.admin.jqplotHelper.mouseLeave(ev, gridpos, datapos, neighbor, plot, strTooltipId)});

enableChartResizing: function(strChartId, strResizeableId) {
//make it resizable
$('#'+strResizeableId).resizable({
delay:20,
Expand All @@ -81,7 +91,35 @@ KAJONA.admin.jqplotHelper = {
KAJONA.admin.jqplotHelper.arrChartObjects[strChartId].render();
}
});
},

bindDataClickEvents : function (strChartId) {
$('#' + strChartId).bind('jqplotDataClick',
function (ev, seriesIndex, pointIndex, data) {
var objChart = KAJONA.admin.jqplotHelper.arrChartObjects[this.id];

//check if a url and call it in a dialogue
if(objChart.arrSeriesToDataPoints && objChart.arrSeriesToDataPoints[seriesIndex]) {
if(objChart.arrSeriesToDataPoints[seriesIndex][pointIndex]) {
var objDataPoint = objChart.arrSeriesToDataPoints[seriesIndex][pointIndex];

if(objDataPoint.actionhandler != null) {
var objFunction = eval("("+objDataPoint.actionhandler+")");
if ($.isFunction(objFunction)) {
objFunction.call(this, ev, seriesIndex, pointIndex, data, objDataPoint);
}
}
else {
KAJONA.admin.jqplotHelper.dataPointOnClickURLHandler(ev, seriesIndex, pointIndex, data, objDataPoint);
}
}
}
});
},

bindMouseEvents : function (strChartId, strTooltipId) {
$('#' + strChartId).bind('jqplotMouseMove', function (ev, gridpos, datapos, neighbor, plot) {KAJONA.admin.jqplotHelper.mouseMove(ev, gridpos, datapos, neighbor, plot, strTooltipId)});
$('#' + strChartId).bind('jqplotMouseLeave', function (ev, gridpos, datapos, neighbor, plot) {KAJONA.admin.jqplotHelper.mouseLeave(ev, gridpos, datapos, neighbor, plot, strTooltipId)});
},


Expand Down Expand Up @@ -125,13 +163,13 @@ KAJONA.admin.jqplotHelper = {
}
},
/**
* Sets the created canvasLabels invisible depending on the intNoOfWrittenLabels
* Sets all canvasLabels invisible for the given axis (xaxis, yaxis)
*
* @param strChartId
* @param strChartId - xaxis or yaxis
* @param strAxis
*/
setAxisInvisible : function (strChartId, strAxis) {
var tickArray = $('#'+strChartId+' div.jqplot-'+strAxis).hide();
$('#'+strChartId+' div.jqplot-'+strAxis).hide();
},
mouseLeave : function (ev, gridpos, datapos, neighbor, plot, tooltipId) {
$('#jqplot_tooltip').remove();
Expand Down Expand Up @@ -264,5 +302,13 @@ KAJONA.admin.jqplotHelper = {
}
var formattedValue = $.jqplot.sprintf(format, value);
return formattedValue;
},

dataPointOnClickURLHandler: function(ev, seriesIndex, pointIndex, data, objDataPoint) {
if(objDataPoint.actionhandlervalue != null && objDataPoint.actionhandlervalue != "") {
KAJONA.admin.folderview.dialog.setContentIFrame(objDataPoint.actionhandlervalue);
KAJONA.admin.folderview.dialog.setTitle('');
KAJONA.admin.folderview.dialog.init();
}
}
};

0 comments on commit c15c77b

Please sign in to comment.