/**
*
*  Generate a chart for a question
*  @param int $iQuestionID      ID of the question
*  @param int $iSurveyID        ID of the survey
*  @param mixed $type           Type of the chart to be created - null produces bar chart, any other value produces pie chart
*  @param array $lbl            An array containing the labels for the chart items
*  @param mixed $gdata          An array containing the percentages for the chart items
*  @param mixed $grawdata       An array containing the raw count for the chart items
*  @param mixed $cache          An object containing [Hashkey] and [CacheFolder]
*  @param string $sQuestionType The question type
*  @return                Name
*/
function createChart($iQuestionID, $iSurveyID, $type = null, $lbl, $gdata, $grawdata, $cache, $oLanguage, $sQuestionType)
{
    /* This is a lazy solution to bug #6389. A better solution would be to find out how
       the "T" gets passed to this function from the statistics.js file in the first place! */
    if (substr($iSurveyID, 0, 1) == "T") {
        $iSurveyID = substr($iSurveyID, 1);
    }
    static $bErrorGenerate = false;
    if ($bErrorGenerate) {
        return false;
    }
    $rootdir = Yii::app()->getConfig("rootdir");
    $homedir = Yii::app()->getConfig("homedir");
    $homeurl = Yii::app()->getConfig("homeurl");
    $admintheme = Yii::app()->getConfig("admintheme");
    $scriptname = Yii::app()->getConfig("scriptname");
    $chartfontfile = Yii::app()->getConfig("chartfontfile");
    $chartfontsize = Yii::app()->getConfig("chartfontsize");
    $alternatechartfontfile = Yii::app()->getConfig("alternatechartfontfile");
    $language = $oLanguage->langcode;
    $cachefilename = "";
    /* Set the fonts for the chart */
    if ($chartfontfile == 'auto') {
        // Tested with ar,be,el,fa,hu,he,is,lt,mt,sr, and en (english)
        // Not working for hi, si, zh, th, ko, ja : see $config['alternatechartfontfile'] to add some specific language font
        $chartfontfile = 'DejaVuSans.ttf';
        if (array_key_exists($language, $alternatechartfontfile)) {
            $neededfontfile = $alternatechartfontfile[$language];
            if (is_file($rootdir . "/fonts/" . $neededfontfile)) {
                $chartfontfile = $neededfontfile;
            } else {
                Yii::app()->setFlashMessage(sprintf(gT('The fonts file %s was not found in <limesurvey root folder>/fonts directory. Please, see the txt file for your language in fonts directory to generate the charts.'), $neededfontfile), 'error');
                $bErrorGenerate = true;
                // Don't do a graph again.
                return false;
            }
        }
    }
    if (count($lbl) > 72) {
        $DataSet = array(1 => array(1 => 1));
        if ($cache->IsInCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet) && Yii::app()->getConfig('debug') < 2) {
            $cachefilename = basename($cache->GetFileFromCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet));
        } else {
            $graph = new pChart(690, 200);
            $graph->loadColorPalette($homedir . DIRECTORY_SEPARATOR . 'styles' . DIRECTORY_SEPARATOR . $admintheme . DIRECTORY_SEPARATOR . 'limesurvey.pal');
            $graph->setFontProperties($rootdir . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . $chartfontfile, $chartfontsize);
            $graph->setFontProperties($rootdir . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . $chartfontfile, $chartfontsize);
            $graph->drawTitle(0, 0, gT('Sorry, but this question has too many answer options to be shown properly in a graph.', 'unescaped'), 30, 30, 30, 690, 200);
            $cache->WriteToCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet, $graph);
            $cachefilename = basename($cache->GetFileFromCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet));
            unset($graph);
        }
        return $cachefilename;
    }
    if (array_sum($gdata) == 0) {
        $DataSet = array(1 => array(1 => 1));
        if ($cache->IsInCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet) && Yii::app()->getConfig('debug') < 2) {
            $cachefilename = basename($cache->GetFileFromCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet));
        } else {
            $graph = new pChart(690, 200);
            $graph->loadColorPalette($homedir . DIRECTORY_SEPARATOR . 'styles' . DIRECTORY_SEPARATOR . $admintheme . DIRECTORY_SEPARATOR . 'limesurvey.pal');
            $graph->setFontProperties($rootdir . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . $chartfontfile, $chartfontsize);
            $graph->setFontProperties($rootdir . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . $chartfontfile, $chartfontsize);
            $graph->drawTitle(0, 0, gT('Sorry, but this question has no responses yet so a graph cannot be shown.', 'unescaped'), 30, 30, 30, 690, 200);
            $cache->WriteToCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet, $graph);
            $cachefilename = basename($cache->GetFileFromCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet));
            unset($graph);
        }
        return $cachefilename;
    }
    if (array_sum($gdata) > 0) {
        $graph = "";
        $p1 = "";
        $i = 0;
        foreach ($gdata as $data) {
            if ($data != 0) {
                $i++;
            }
        }
        /* Totatllines is the number of entries to show in the key and we need to reduce the font
           and increase the size of the chart if there are lots of them (ie more than 15) */
        $totallines = $i;
        if ($totallines > 15) {
            $gheight = 320 + 6.7 * ($totallines - 15);
            $fontsize = 7;
            $legendtop = 0.01;
            $setcentrey = 0.5 / ($gheight / 320);
        } else {
            $gheight = 320;
            $fontsize = 8;
            $legendtop = 0.07000000000000001;
            $setcentrey = 0.5;
        }
        if (!$type) {
            $DataSet = new pData();
            $counter = 0;
            $maxyvalue = 0;
            foreach ($grawdata as $datapoint) {
                $DataSet->AddPoint(array($datapoint), "Serie{$counter}");
                $DataSet->AddSerie("Serie{$counter}");
                $counter++;
                if ($datapoint > $maxyvalue) {
                    $maxyvalue = $datapoint;
                }
            }
            if ($maxyvalue < 10) {
                ++$maxyvalue;
            }
            if ($language == 'ar') {
                if (!class_exists('I18N_Arabic_Glyphs', false)) {
                    $Arabic = new I18N_Arabic('Glyphs');
                } else {
                    $Arabic = new I18N_Arabic_Glyphs();
                }
                foreach ($lbl as $kkey => $kval) {
                    if (preg_match("^[A-Za-z]^", $kkey)) {
                        //auto detect if english
                        $lblout[] = $kkey . ' (' . $kval . ')';
                    } else {
                        $lblout[] = $Arabic->utf8Glyphs($kkey . ' )' . $kval . '(');
                    }
                }
            } elseif (getLanguageRTL($language)) {
                foreach ($lbl as $kkey => $kval) {
                    $lblout[] = UTF8Strrev($kkey . ' )' . $kval . '(');
                }
            } else {
                foreach ($lbl as $kkey => $kval) {
                    $lblout[] = $kkey . ' (' . $kval . ')';
                }
            }
            $counter = 0;
            foreach ($lblout as $sLabelName) {
                $DataSet->SetSerieName(html_entity_decode($sLabelName, null, 'UTF-8'), "Serie{$counter}");
                $counter++;
            }
            if ($cache->IsInCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet->GetData()) && Yii::app()->getConfig('debug') < 2) {
                $cachefilename = basename($cache->GetFileFromCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet->GetData()));
            } else {
                $graph = new pChart(1, 1);
                $graph->setFontProperties($rootdir . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . $chartfontfile, $chartfontsize);
                $legendsize = $graph->getLegendBoxSize($DataSet->GetDataDescription());
                if ($legendsize[1] < 320) {
                    $gheight = 420;
                } else {
                    $gheight = $legendsize[1] + 100;
                }
                $graph = new pChart(690 + $legendsize[0], $gheight);
                $graph->drawFilledRectangle(0, 0, 690 + $legendsize[0], $gheight, 254, 254, 254, false);
                $graph->loadColorPalette($homedir . DIRECTORY_SEPARATOR . 'styles' . DIRECTORY_SEPARATOR . $admintheme . DIRECTORY_SEPARATOR . 'limesurvey.pal');
                $graph->setFontProperties($rootdir . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . $chartfontfile, $chartfontsize);
                $graph->setGraphArea(50, 30, 500, $gheight - 60);
                $graph->drawFilledRoundedRectangle(7, 7, 523 + $legendsize[0], $gheight - 7, 5, 254, 255, 254);
                $graph->drawRoundedRectangle(5, 5, 525 + $legendsize[0], $gheight - 5, 5, 230, 230, 230);
                $graph->drawGraphArea(254, 254, 254, TRUE);
                $graph->drawScale($DataSet->GetData(), $DataSet->GetDataDescription(), SCALE_START0, 150, 150, 150, TRUE, 90, 0, TRUE, 5, false);
                $graph->drawGrid(4, TRUE, 230, 230, 230, 50);
                // Draw the 0 line
                $graph->setFontProperties($rootdir . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . $chartfontfile, $chartfontsize);
                $graph->drawTreshold(0, 143, 55, 72, TRUE, TRUE);
                // Draw the bar graph
                $graph->drawBarGraph($DataSet->GetData(), $DataSet->GetDataDescription(), FALSE);
                //$Test->setLabel($DataSet->GetData(),$DataSet->GetDataDescription(),"Serie4","1","Important point!");
                // Finish the graph
                $graph->setFontProperties($rootdir . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . $chartfontfile, $chartfontsize);
                $graph->drawLegend(510, 30, $DataSet->GetDataDescription(), 250, 250, 250);
                $cache->WriteToCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet->GetData(), $graph);
                $cachefilename = basename($cache->GetFileFromCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet->GetData()));
                unset($graph);
            }
        } else {
            // this block is to remove the items with value == 0
            // and an inelegant way to remove comments from List with Comments questions
            $i = 0;
            $j = 0;
            $labelTmp = array();
            while (isset($gdata[$i])) {
                $aHelperArray = array_keys($lbl);
                if ($gdata[$i] == 0 || $sQuestionType == "O" && substr($aHelperArray[$i], 0, strlen($oLanguage->gT("Comments"))) == $oLanguage->gT("Comments")) {
                    array_splice($gdata, $i, 1);
                } else {
                    $i++;
                    $labelTmp = $labelTmp + array_slice($lbl, $j, 1, true);
                    // Preserve numeric keys for the labels!
                }
                $j++;
            }
            $lbl = $labelTmp;
            if ($language == 'ar') {
                if (!class_exists('I18N_Arabic_Glyphs', false)) {
                    $Arabic = new I18N_Arabic('Glyphs');
                } else {
                    $Arabic = new I18N_Arabic_Glyphs();
                }
                foreach ($lbl as $kkey => $kval) {
                    if (preg_match("^[A-Za-z]^", $kkey)) {
                        //auto detect if english
                        $lblout[] = $kkey . ' (' . $kval . ')';
                    } else {
                        $lblout[] = $Arabic->utf8Glyphs($kkey . ' )' . $kval . '(');
                    }
                }
            } elseif (getLanguageRTL($language)) {
                foreach ($lbl as $kkey => $kval) {
                    $lblout[] = UTF8Strrev(html_entity_decode($kkey, null, 'UTF-8') . ' )' . $kval . '(');
                }
            } else {
                foreach ($lbl as $kkey => $kval) {
                    $lblout[] = html_entity_decode($kkey, null, 'UTF-8') . ' (' . $kval . ')';
                }
            }
            //create new 3D pie chart
            $DataSet = new pData();
            $DataSet->AddPoint($gdata, "Serie1");
            $DataSet->AddPoint($lblout, "Serie2");
            $DataSet->AddAllSeries();
            $DataSet->SetAbsciseLabelSerie("Serie2");
            if ($cache->IsInCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet->GetData()) && Yii::app()->getConfig('debug') < 2) {
                $cachefilename = basename($cache->GetFileFromCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet->GetData()));
            } else {
                $gheight = ceil($gheight);
                $graph = new pChart(690, $gheight);
                $graph->drawFilledRectangle(0, 0, 690, $gheight, 254, 254, 254, false);
                $graph->loadColorPalette($homedir . '/styles/' . $admintheme . '/limesurvey.pal');
                $graph->drawFilledRoundedRectangle(7, 7, 687, $gheight - 3, 5, 254, 255, 254);
                $graph->drawRoundedRectangle(5, 5, 689, $gheight - 1, 5, 230, 230, 230);
                // Draw the pie chart
                $graph->setFontProperties($rootdir . "/fonts/" . $chartfontfile, $chartfontsize);
                $graph->drawPieGraph($DataSet->GetData(), $DataSet->GetDataDescription(), 225, round($gheight / 2), 170, PIE_PERCENTAGE, TRUE, 50, 20, 5);
                $graph->setFontProperties($rootdir . "/fonts/" . $chartfontfile, $chartfontsize);
                $graph->drawPieLegend(430, 12, $DataSet->GetData(), $DataSet->GetDataDescription(), 250, 250, 250);
                $cache->WriteToCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet->GetData(), $graph);
                $cachefilename = basename($cache->GetFileFromCache("graph" . $iSurveyID . $language . $iQuestionID, $DataSet->GetData()));
                unset($graph);
            }
        }
        //end else -> pie charts
    }
    return $cachefilename;
}
Beispiel #2
0
 /**
  * @param Text_Frame_Decorator $frame
  */
 function render(Frame $frame)
 {
     $text = $frame->get_text();
     if (trim($text) === "") {
         return;
     }
     $style = $frame->get_style();
     list($x, $y) = $frame->get_position();
     $cb = $frame->get_containing_block();
     if (($ml = $style->margin_left) === "auto" || $ml === "none") {
         $ml = 0;
     }
     if (($pl = $style->padding_left) === "auto" || $pl === "none") {
         $pl = 0;
     }
     if (($bl = $style->border_left_width) === "auto" || $bl === "none") {
         $bl = 0;
     }
     $x += $style->length_in_pt(array($ml, $pl, $bl), $cb["w"]);
     $font = $style->font_family;
     $size = $frame_font_size = $style->font_size;
     $height = $style->height;
     $word_spacing = $frame->get_text_spacing() + $style->length_in_pt($style->word_spacing);
     $char_spacing = $style->length_in_pt($style->letter_spacing);
     $width = $style->width;
     /*$text = str_replace(
         array("{PAGE_NUM}"),
         array($this->_canvas->get_page_number()), 
         $text
       );*/
     if (!class_exists('I18N_Arabic')) {
         require_once DOMPDF_DIR . "/I18N/Arabic/Glyphs.php";
         $Arabic = new I18N_Arabic_Glyphs('Glyphs');
         $text = $Arabic->utf8Glyphs($text);
     }
     $this->_canvas->text($x, $y, $text, $font, $size, $style->color, $word_spacing, $char_spacing);
     $line = $frame->get_containing_line();
     // FIXME Instead of using the tallest frame to position,
     // the decoration, the text should be well placed
     if (false && $line->tallest_frame) {
         $base_frame = $line->tallest_frame;
         $style = $base_frame->get_style();
         $size = $style->font_size;
         $height = $line->h * ($size / $style->line_height);
     }
     $line_thickness = $size * self::DECO_THICKNESS;
     $underline_offset = $size * self::UNDERLINE_OFFSET;
     $overline_offset = $size * self::OVERLINE_OFFSET;
     $linethrough_offset = $size * self::LINETHROUGH_OFFSET;
     $underline_position = -0.08;
     if ($this->_canvas instanceof CPDF_Adapter) {
         $cpdf_font = $this->_canvas->get_cpdf()->fonts[$style->font_family];
         if (isset($cpdf_font["UnderlinePosition"])) {
             $underline_position = $cpdf_font["UnderlinePosition"] / 1000;
         }
         if (isset($cpdf_font["UnderlineThickness"])) {
             $line_thickness = $size * ($cpdf_font["UnderlineThickness"] / 1000);
         }
     }
     $descent = $size * $underline_position;
     $base = $size;
     // Handle text decoration:
     // http://www.w3.org/TR/CSS21/text.html#propdef-text-decoration
     // Draw all applicable text-decorations.  Start with the root and work our way down.
     $p = $frame;
     $stack = array();
     while ($p = $p->get_parent()) {
         $stack[] = $p;
     }
     while (isset($stack[0])) {
         $f = array_pop($stack);
         if (($text_deco = $f->get_style()->text_decoration) === "none") {
             continue;
         }
         $deco_y = $y;
         //$line->y;
         $color = $f->get_style()->color;
         switch ($text_deco) {
             default:
                 continue;
             case "underline":
                 $deco_y += $base - $descent + $underline_offset + $line_thickness / 2;
                 break;
             case "overline":
                 $deco_y += $overline_offset + $line_thickness / 2;
                 break;
             case "line-through":
                 $deco_y += $base * 0.7 + $linethrough_offset;
                 break;
         }
         $dx = 0;
         $x1 = $x - self::DECO_EXTENSION;
         $x2 = $x + $width + $dx + self::DECO_EXTENSION;
         $this->_canvas->line($x1, $deco_y, $x2, $deco_y, $color, $line_thickness);
     }
     if (DEBUG_LAYOUT && DEBUG_LAYOUT_LINES) {
         $text_width = Font_Metrics::get_text_width($text, $font, $frame_font_size);
         $this->_debug_layout(array($x, $y, $text_width + ($line->wc - 1) * $word_spacing, $frame_font_size), "orange", array(0.5, 0.5));
     }
 }