*/ class syntax_plugin_gchart extends SyntaxPlugin { private $supported_charts = [ 'qr' => 'qr', 'pie' => 'p3', 'pie3d' => 'p3', 'pie2d' => 'p', 'line' => 'lc', 'spark' => 'ls', 'sparkline' => 'ls', 'bar' => 'bvs', 'hbar' => 'bhs', 'vbar' => 'bvs' ]; /** * What kind of syntax are we? */ public function getType() { return 'substition'; } public function getPType() { return 'block'; } /** * Where to sort in? */ public function getSort() { return 160; } /** * Connect pattern to lexer */ public function connectTo($mode) { $this->Lexer->addSpecialPattern('\n.*?\n', $mode, 'plugin_gchart'); } /** * Handle the match */ public function handle($match, $state, $pos, Doku_Handler $handler) { // prepare default data $return = [ 'type' => 'p3', 'data' => [], 'width' => 320, 'height' => 140, 'align' => 'right', 'legend' => false, 'value' => false, 'title' => '', 'fg' => ltrim($this->getConf('fg'), '#'), 'bg' => ltrim($this->getConf('bg'), '#') ]; // prepare input $lines = explode("\n", $match); $conf = array_shift($lines); array_pop($lines); // parse adhoc configs if (preg_match('/"([^"]+)"/', $conf, $match)) { $return['title'] = $match[1]; $conf = preg_replace('/"([^"]+)"/', '', $conf); } if (preg_match('/\b(left|center|right)\b/i', $conf, $match)) { $return['align'] = strtolower($match[1]); } if (preg_match('/\b(legend)\b/i', $conf, $match)) { $return['legend'] = true; } if (preg_match('/\b(values?)\b/i', $conf, $match)) { $return['value'] = true; } if (preg_match('/\b(\d+)x(\d+)\b/', $conf, $match)) { $return['width'] = $match[1]; $return['height'] = $match[2]; } $type_regex = '/\b(' . implode('|', array_keys($this->supported_charts)) . ')\b/i'; if (preg_match($type_regex, $conf, $match)) { $return['type'] = $this->supported_charts[strtolower($match[1])]; } if (preg_match_all('/#([0-9a-f]{6}([0-9a-f][0-9a-f])?)\b/i', $conf, $match)) { if (isset($match[1][0])) { $return['fg'] = $match[1][0]; } if (isset($match[1][1])) { $return['bg'] = $match[1][1]; } } // parse chart data $data = []; foreach ($lines as $line) { //ignore comments (except escaped ones) $line = preg_replace('/(?createColorPalette($data['fg'], count($val))); } $parameters['chs'] = $data['width'] . 'x' . $data['height']; # size $parameters['chd'] = 't:' . implode(',', $val); $parameters['chds'] = $min . ',' . $max; $parameters['choe'] = 'UTF-8'; if ($data['title']) { $parameters['chtt'] = $data['title']; } switch ($data['type']) { case 'bhs': # horizontal bar $parameters['chxt'] = 'y'; $parameters['chxl'] = '0:|' . implode('|', array_reverse($key)); $parameters['chbh'] = 'a'; if ($data['value']) { $parameters['chm'] = 'N*f*,333333,0,-1,11'; } break; case 'bvs': # vertical bar $parameters['chxt'] = 'y,x'; $parameters['chxr'] = '0,' . $min . ',' . $max; $parameters['chxl'] = '1:|' . implode('|', $key); $parameters['chbh'] = 'a'; if ($data['value']) { $parameters['chm'] = 'N*f*,333333,0,-1,11'; } break; case 'lc': # line graph $parameters['chxt'] = 'y,x'; $parameters['chxr'] = '0,' . floor(min($min, 0)) . ',' . ceil($max); $parameters['chxl'] = '1:|' . implode('|', $key); if ($data['value']) { $parameters['chm'] = 'N*f*,333333,0,-1,11'; } break; case 'ls': # spark line if ($data['value']) { $parameters['chm'] = 'N*f*,333333,0,-1,11'; } break; case 'p3': # pie graphs case 'p': if ($data['value']) { $cnt = count($key); for ($i = 0; $i < $cnt; $i++) { $key[$i] .= ' (' . $val[$i] . ')'; } } $parameters['chl'] = implode('|', $key); break; case 'qr': $rawval = array_keys($data['data']); if (in_array($rawval[0], ['L', 'M', 'Q', 'H'])) { $parameters['chld'] = array_shift($rawval); } unset($parameters['chd']); unset($parameters['chds']); $parameters['chl'] = implode(';', $rawval); break; } $url = $this->getConf('charturl') . '?' . http_build_query($parameters, '', '&') . '&.png'; $attr = [ 'class' => 'media' . $data['align'], 'alt' => '', 'width' => $data['width'], 'height' => $data['height'] ]; if ($data['align'] == 'left') { $attr['align'] = 'left'; } elseif ($data['align'] == 'right') { $attr['align'] = 'right'; } $R->doc .= sprintf('', ml($url), buildAttributes($attr)); return true; } /** * Google used to creae a palette of colors based on a single given color, * quickcharts won't so we do it ourselves. Crudely. Using transparancy. * It does not look great but at least each element has a different shade. * * @param string $rgb original hex color * @param int $count number of colors to generate * @return array */ protected function createColorPalette($rgb, $count) { $palette = []; $inc = floor(255 / $count); for ($i = 0; $i < $count; $i++) { $palette[] = $rgb . dechex(255 - $i * $inc); } return $palette; } }