Skip to content

Commit

Permalink
[feature] Allow to send xml in surveys
Browse files Browse the repository at this point in the history
[feature] Allow diffrent XML by questions (using Question code)
  • Loading branch information
Shnoulle committed Apr 23, 2019
1 parent edb24c2 commit 7d73267
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 59 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ A plugin for LimeSurvey to generate graph from question in question answer of th


## Documentation

- Activate the plugin
- Create a long text question type
- Use the new attribute to set label and value by other question code
Expand All @@ -40,8 +41,10 @@ There is 2 solution to show the graph :
### Adapt the graph

The generated graph have only one option in question setting : the total size of the grap in pixel.
You can update all the default setting with a xml file in template upload file directory.
The plugin read the default settings and, if exist, `graphQuestion.xml` file, you can replace default value here.
You can update all the default setting with a xml file in template upload file directory or survey uploaded files directory.

The plugin read the default settings and, if exist, `graphQuestion.xml` and `graphQuestionRadar.xml` file in template directory, you can replace default value here.
The plugin look at survey uploaded files to get `graphQuestion.xml`, `graphQuestionRadar.xml` and `graphQuestionQuestionCode.xml` (replaceQuestionCode by the question code of the graph question) and add it in graph configuration.

You can update color, font size and some margin for the graph wrapper and for the header. Font used use included LimeSurvey system to choose the best font for your language, you can set it globally in your config file.

Expand Down
61 changes: 43 additions & 18 deletions generateGraphQuestion.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @copyright 2017-2018 Denis Chenu <https://www.sondages.pro>
* @copyright 2017 Réseau en scène Languedoc-Roussillon <https://www.reseauenscene.fr>
* @license AGPL v3
* @version 2.0.1
* @version 2.1.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -104,7 +104,6 @@ public function beforeSurveyPage()
default:
$step=0;
}

$aDatasGraphSources['questions'][$aDataGraphSource['qid']]['step']=$step;
}
$aDatasGraphSources['state']='step';
Expand Down Expand Up @@ -141,9 +140,9 @@ public function beforeQuestionRender()
$title=LimeExpressionManager::ProcessString($title);
/* Get the size */
$oGenerateGraphSize=QuestionAttribute::model()->find('qid=:qid and attribute=:attribute',array(':qid'=>$this->getEvent()->get('qid'),':attribute'=>'generateGraphSize'));
$generateGraphSize=($oGenerateGraphSize)? $oGenerateGraphSize->value : 400;
$generateGraphSize=!empty($oGenerateGraphSize) ? $oGenerateGraphSize->value : 400;
/* Generate graph */
$base64image=$this->generateGraphRadar($aGraphData,flattenText($title,false,true),$generateGraphSize);
$base64image=$this->generateGraphRadar($oQuestion->title,$aGraphData,flattenText($title,false,true),$generateGraphSize);
$_SESSION["survey_{$surveyId}"][$answerSGQ]=$base64image;
$_SESSION["survey_{$surveyId}"]['startingValues'][$answerSGQ]=$base64image;
/* Maybe must save the value in DB */
Expand Down Expand Up @@ -175,7 +174,7 @@ public function generateGraphRender()
$oGenerateGraphSize=QuestionAttribute::model()->find('qid=:qid and attribute=:attribute',array(':qid'=>$this->getEvent()->get('qid'),':attribute'=>'generateGraphSize'));
$generateGraphSize=($oGenerateGraphSize)? $oGenerateGraphSize->value : null;

$base64image=$this->generateGraphRadar($aGraphData,flattenText($title,false,true),$generateGraphSize);
$base64image=$this->generateGraphRadar($oEvent->get('code'),$aGraphData,flattenText($title,false,true),$generateGraphSize);
/* Fill the session value */
$oQuestion=Question::model()->find("qid=:qid",array(':qid'=>$this->getEvent()->get('qid')));
$answerSGQ=$oQuestion->sid."X".$oQuestion->gid."X".$oQuestion->qid;
Expand Down Expand Up @@ -209,7 +208,7 @@ public function generateGraphRender()
* @var string $sTitle of the graph
* @return string
*/
public function generateGraphRadar($aData,$sTitle='',$size=null){
public function generateGraphRadar($qCode,$aData,$sTitle='',$size=null){
$aLabels=array_column($aData, 'label');
$aValues=array_column($aData, 'value');/* Only one serie currently */

Expand All @@ -219,7 +218,6 @@ public function generateGraphRadar($aData,$sTitle='',$size=null){
$fileName="generateGraph".hash("md5",json_encode($aData));
require_once(__DIR__ . '/vendor/pChart2/class/pData.class.php');
require_once(__DIR__ . '/vendor/pChart2/class/pDraw.class.php');
require_once(__DIR__ . '/vendor/pChart2/class/pRadar.class.php');
require_once(__DIR__ . '/vendor/pChart2/class/pImage.class.php');
$DataSet = new pData();
$DataSet->addPoints($aValues,"Serie1");
Expand All @@ -229,7 +227,7 @@ public function generateGraphRadar($aData,$sTitle='',$size=null){
$DataSet->setAbscissa("Labels");

/* TODO : get color and size via a css file in template */
$graphConfig=$this->_getGraphConfig();
$graphConfig=$this->_getGraphConfig($qCode);
$size=intval($size) ? intval($size) : $graphConfig['size'];
$headerSize=$graphConfig['header']['size'];
$borderSize=$graphConfig['border'];
Expand All @@ -243,12 +241,15 @@ public function generateGraphRadar($aData,$sTitle='',$size=null){
$Image->setFontProperties(array("FontName"=>$font,"FontSize"=>$graphConfig['header']['fontsize']));
$Image->drawText(10,$headerSize-4,$sTitle,$graphConfig['header']['color']);
$Image->setFontProperties(array("FontName"=>$font,"FontSize"=>$graphConfig['fontsize'],"R"=>$graphConfig['color']['R'],"G"=>$graphConfig['color']['G'],"B"=>$graphConfig['color']['B']));
/* Here start the radar */
require_once(__DIR__ . '/vendor/pChart2/class/pRadar.class.php');
$Chart = new pRadar();
$Image->setGraphArea($margin['left'],$headerSize+$margin['top'],$size-$margin['right'],$size-$margin['bottom']);
$chartOptions=$graphConfig['chart'];
$chartOptions['Layout']=$this->_getFixedValue($chartOptions['Layout']);
$chartOptions['LabelPos']=$this->_getFixedValue($chartOptions['LabelPos']);
$Chart->drawRadar($Image,$DataSet,$chartOptions);
/* Here end the radar */
$path=App()->getRuntimePath().DIRECTORY_SEPARATOR.$fileName.".png";
$Image->Render($path);

Expand Down Expand Up @@ -416,8 +417,8 @@ private function _getChartFontFile()
}
}
if(version_compare(App()->getConfig('versionnumber'),'3.0.0','>=')) {
return $rootdir.DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.'fonts'.DIRECTORY_SEPARATOR.$chartfontfile;
}
return $rootdir.DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.'fonts'.DIRECTORY_SEPARATOR.$chartfontfile;
}
return $rootdir.DIRECTORY_SEPARATOR.'fonts'.DIRECTORY_SEPARATOR.$chartfontfile;

}
Expand All @@ -426,24 +427,48 @@ private function _getChartFontFile()
* Get the config for this chart for this survey/template
* @return array
*/
private function _getGraphConfig()
private function _getGraphConfig($qCode, $graphType = "Radar")
{
$oldValue = libxml_disable_entity_loader(true);
$xmlDefaultConfigFile = file_get_contents( realpath (__DIR__ . DIRECTORY_SEPARATOR.'graphQuestion.xml'));
$xmlDefaultConfig=simplexml_load_string($xmlDefaultConfigFile);
$aConfig=$aDefaultConfig=json_decode(json_encode($xmlDefaultConfig), true);
$aConfig = $this->_addXmlConfig(realpath(__DIR__ .DIRECTORY_SEPARATOR.'graphQuestion.xml'));
$aConfig = $this->_addXmlConfig(realpath(__DIR__ .DIRECTORY_SEPARATOR.'graphQuestion'.$graphType.'.xml'),$aConfig);
/* By template files */
$oTemplate = \Template::model()->getInstance(null, $this->_iSurveyId);
if(is_file($oTemplate->filesPath.'graphQuestion.xml')){
$xmlTemplateConfigFile=file_get_contents($oTemplate->filesPath.'/graphQuestion.xml');
$xmlTemplateConfig=simplexml_load_string($xmlTemplateConfigFile);
$aTemplateConfig=json_decode(json_encode($xmlTemplateConfig), true);
$aConfig=\CMap::mergeArray($aConfig,$aTemplateConfig);
$aConfig = $this->_addXmlConfig($oTemplate->filesPath.'graphQuestion.xml',$aConfig);
}
if(is_file($oTemplate->filesPath.'graphQuestion'.$graphType.'.xml')){
$aConfig = $this->_addXmlConfig($oTemplate->filesPath.'graphQuestion'.$graphType.'.xml',$aConfig);
}
/* By survey files */
$surveyDir = Yii::app()->getConfig('uploaddir')."/surveys/{$this->_iSurveyId}/files/";
if(is_file($surveyDir.'graphQuestion.xml')){
$aConfig = $this->_addXmlConfig($surveyDir.'graphQuestion.xml',$aConfig);
}
if(is_file($surveyDir.'graphQuestion'.$graphType.'.xml')){
$aConfig = $this->_addXmlConfig($surveyDir.'graphQuestion'.$graphType.'.xml',$aConfig);
}

if(is_file($surveyDir.'graphQuestion'.$qCode.'.xml')){
$aConfig = $this->_addXmlConfig($surveyDir.'graphQuestion'.$qCode.'.xml',$aConfig);
}
libxml_disable_entity_loader($oldValue);
/* @todo : reset bad value to default config ( color between 0 and 255, intval for size ...) */
return $aConfig;
}

/**
* Add a config file to the config
* @param strinf $file that must exist
* @param array $config to update
* @return array updated config
*/
private function _addXmlConfig($file, $config = array())
{
$xmlConfigFile = file_get_contents($file);
$xmlConfig = simplexml_load_string($xmlConfigFile);
return \CMap::mergeArray($config,json_decode(json_encode($xmlConfig), true));
}
/**
* Fix some var (by constant)
* @param string $param name to test
Expand Down
11 changes: 3 additions & 8 deletions graphQuestion.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
</color>
<!-- background color of graph -->
<bgcolor>
<R>250</R>
<G>250</G>
<B>250</B>
<R>255</R>
<G>255</G>
<B>255</B>
</bgcolor>
<!-- palette file used , see vendor/pChart2/palettes-->
<palette></palette>
Expand All @@ -43,9 +43,4 @@
<B>40</B>
</bgcolor>
</header>
<!--Chart format see http://wiki.pchart.net/doc.draw.radar.html -->
<chart>
<Layout>RADAR_LAYOUT_CIRCLE</Layout>
<LabelPos>RADAR_LABELS_ROTATED</LabelPos>
</chart>
</graph>
9 changes: 9 additions & 0 deletions graphQuestionRadar.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Configuration for graphQuestion , default part, same xml file in templates/files/graphQuestionRadar.xml to update. -->
<graph>
<!--Chart format see http://wiki.pchart.net/doc.draw.radar.html -->
<chart>
<Layout>RADAR_LAYOUT_CIRCLE</Layout>
<LabelPos>RADAR_LABELS_ROTATED</LabelPos>
</chart>
</graph>
15 changes: 15 additions & 0 deletions vendor/pChart2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

cloc-1.80.exe
php.exe
php.ini
php7.2/php.exe
php7.2/php7ts.dll
php7.2/php_gd2.dll
php7.2/php_pdo_sqlite.dll
php7.3/php.exe
php7.3/php7ts.dll
php7.3/php_gd2.dll
php7.3/php_pdo_sqlite.dll
php7ts.dll
php_gd2.dll
php_pdo_sqlite.dll
63 changes: 34 additions & 29 deletions vendor/pChart2/class/pDraw.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -3957,12 +3957,14 @@ function drawSplineChart($Format = [])
list($XMargin, $XDivs) = $this->scaleGetXSettings();
foreach($Data["Series"] as $SerieName => $Serie) {
if ($Serie["isDrawable"] == TRUE && $SerieName != $Data["Abscissa"]) {

$R = $Serie["Color"]["R"];
$G = $Serie["Color"]["G"];
$B = $Serie["Color"]["B"];
$Alpha = $Serie["Color"]["Alpha"];
$Ticks = $Serie["Ticks"];
$Weight = $Serie["Weight"];

if ($BreakR == NULL) {
$BreakSettings = ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"Ticks" => $VoidTicks];
} else {
Expand All @@ -3976,13 +3978,16 @@ function drawSplineChart($Format = [])
}

$AxisID = $Serie["Axis"];
$Mode = $Data["Axis"][$AxisID]["Display"];
$Mode = $Data["Axis"][$AxisID]["Display"];
$Format = $Data["Axis"][$AxisID]["Format"];
$Unit = $Data["Axis"][$AxisID]["Unit"];
$Unit = $Data["Axis"][$AxisID]["Unit"];

$SerieDescription = (isset($Serie["Description"])) ? $Serie["Description"] : $SerieName;
$PosArray = $this->scaleComputeY($Serie["Data"], ["AxisID" => $Serie["Axis"]]);
$this->DataSet->Data["Series"][$SerieName]["XOffset"] = 0;

if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {

if ($XDivs == 0) {
$XStep = ($this->GraphAreaX2 - $this->GraphAreaX1) / 4;
} else {
Expand All @@ -3992,51 +3997,52 @@ function drawSplineChart($Format = [])
$X = $this->GraphAreaX1 + $XMargin;
$WayPoints = [];
$Force = $XStep / 5;

$PosArray = $this->convertToArray($PosArray);

$LastGoodY = NULL;
$LastGoodX = NULL;
$LastX = 1;
$LastY = 1;

foreach($PosArray as $Key => $Y) {
if ($DisplayValues) $this->drawText($X, $Y - $DisplayOffset, $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit), array(
"R" => $DisplayR,
"G" => $DisplayG,
"B" => $DisplayB,
"Align" => TEXT_ALIGN_BOTTOMMIDDLE
));
if ($DisplayValues){
$this->drawText($X, $Y - $DisplayOffset, $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit), [
"R" => $DisplayR,
"G" => $DisplayG,
"B" => $DisplayB,
"Align" => TEXT_ALIGN_BOTTOMMIDDLE
]);
}
if ($RecordImageMap && $Y != VOID) {
$this->addToImageMap("CIRCLE", floor($X) . "," . floor($Y) . "," . $ImageMapPlotSize, $this->toHTMLColor($R, $G, $B), $SerieDescription, $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit));
}

if ($Y == VOID && $LastY != NULL) {
$this->drawSpline($WayPoints, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"Ticks" => $Ticks,"Weight" => $Weight]);
$WayPoints = [];
if ($Y == VOID && $LastY != NULL){
$this->drawSpline($WayPoints,["Force"=>$Force,"R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks,"Weight"=>$Weight]);
$WayPoints = [];
}

if ($Y != VOID && $LastY == NULL && $LastGoodY != NULL && !$BreakVoid) {
$this->drawLine($LastGoodX, $LastGoodY, $X, $Y, $BreakSettings);
}

if ($Y != VOID) $WayPoints[] = [$X,$Y];
if ($Y != VOID){
$WayPoints[] = [$X,$Y];
}

if ($Y != VOID) {
$LastGoodY = $Y;
$LastGoodX = $X;
}

if ($Y == VOID) {
} else {
$Y = NULL;
}

$LastX = $X;
$LastY = $Y;
$X = $X + $XStep;
$X += $XStep;
}

$this->drawSpline($WayPoints, ["Force" => $Force,"R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"Ticks" => $Ticks,"Weight" => $Weight]);

} else {

if ($XDivs == 0) {
$YStep = ($this->GraphAreaY2 - $this->GraphAreaY1) / 4;
} else {
Expand All @@ -4048,12 +4054,12 @@ function drawSplineChart($Format = [])
$Force = $YStep / 5;

$PosArray = $this->convertToArray($PosArray);

$LastGoodY = NULL;
$LastGoodX = NULL;
$LastX = 1;
$LastY = 1;

foreach($PosArray as $Key => $X) {

if ($DisplayValues) {
$this->drawText($X + $DisplayOffset, $Y, $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit), ["Angle" => 270,"R" => $DisplayR,"G" => $DisplayG,"B" => $DisplayB,"Align" => TEXT_ALIGN_BOTTOMMIDDLE]);
}
Expand All @@ -4071,20 +4077,19 @@ function drawSplineChart($Format = [])
$this->drawLine($LastGoodX, $LastGoodY, $X, $Y, $BreakSettings);
}

if ($X != VOID){
$WayPoints[] = [$X,$Y];
}

if ($X != VOID) {
$WayPoints[] = [$X, $Y];
#} # Momchil
#if ($X != VOID) {
$LastGoodX = $X;
$LastGoodY = $Y;
} else {
#if ($X == VOID) {
$X = NULL;
}

$LastX = $X;
$LastY = $Y;
$Y = $Y + $YStep;
$Y += $YStep;
}

$this->drawSpline($WayPoints, ["Force" => $Force,"R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"Ticks" => $Ticks,"Weight" => $Weight]);
Expand Down
4 changes: 2 additions & 2 deletions vendor/pChart2/generateGraphQuestion-readme.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Include pChart 2.1.4a
https://github.com/bozhinov/pChart2.0-for-PHP7/releases/tag/2.1.4a
Include pChart 2.1.4b
https://github.com/bozhinov/pChart2.0-for-PHP7/releases/tag/2.1.4b
Remove example directory

0 comments on commit 7d73267

Please sign in to comment.