setHook('isekaichart', self::class . '::create'); return true; } /** * @param string $input * @param string[] $args * @param \Parser $parser * @param \PPFrame $frame */ public static function create($input, $args, $parser, $frame) { if (isset($args['type'])) { switch ($args['type']) { case 'radar': return self::createRadar($input, $args, $parser, $frame); break; } return '' . wfMessage("isekai-chart-unknow-type", $args['type'])->parse() . ''; } return '' . wfMessage("isekai-chart-undefined-type")->parse() . ''; } public static function parseArgs(&$args, $defaultArgs = []) { $newArgs = array_merge([ 'legend' => true, 'width' => 350, 'height' => 300, ], $defaultArgs); $argsType = [ 'width' => 'int', 'height' => 'int', ]; foreach ($args as $key => $arg) { if (isset($argsType[$key])) { switch ($argsType[$key]) { case 'int': $arg = intval($arg); break; case 'float': $arg = floatval($arg); break; } } $newArgs[$key] = $arg; } return $newArgs; } /** * @param string $input * @param string[] $args * @param \Parser $parser * @param \PPFrame $frame */ public static function createRadar(&$input, &$inputArgs, &$parser, &$frame) { $parser->getOutput()->addModules("ext.isekai.chart"); // 添加样式和脚本 $allowedArgs = ['width', 'height', 'shape']; $args = self::parseArgs($inputArgs, [ 'shape' => 'polygon' ]); $legend = $args['legend']; $lines = explode("\n", $input); $csvData = []; foreach ($lines as $line) { if (!empty(trim($line))) { $csvData[] = str_getcsv($line); } } $names = []; $values = []; if (count($csvData) > 1) { if (count($csvData[0]) > 1 && $csvData[0][0] === "") { // 标题行 $names = array_slice($csvData[0], 1); array_splice($csvData, 0, 1); } else { // 不存在标题行 $legend = false; $valueLen = count($csvData[0]); for ($i = 0; $i < $valueLen; $i ++) { // 创建默认标题 $names[] = wfMessage('isekai-chart-default-row-name', $i + 1)->text(); } } } foreach ($csvData as $csvLine) { $valueLine = []; foreach ($csvLine as $pos => $csvCol) { if ($pos === 0) { $valueLine[$pos] = $csvCol; } else { $valueLine[$pos] = floatval($csvCol); } } $values[] = $valueLine; } $nameJson = json_encode($names, JSON_UNESCAPED_UNICODE); $valueJson = json_encode($values, JSON_UNESCAPED_UNICODE); if (!$valueJson) { return '' . wfMessage("isekai-chart-transform-error", "Cannot encode json")->parse() . ''; } $attr = []; foreach ($args as $key => $val) { if (in_array($key, $allowedArgs)) { $attr['data-' . $key] = $val; } } $attr = array_merge($attr, [ 'class' => 'isekai-chart', 'style' => "width: {$args['width']}px; height: {$args['height']}px; display: inline-block", 'data-name' => $nameJson, 'data-value' => $valueJson, 'data-legend' => $legend ? 'on' : 'off', ]); ksort($attr); $chartId = md5(serialize($attr)); $attr['data-chart-id'] = $chartId; $html = Html::openElement('div', $attr); $html .= Html::closeElement('div'); return $html; } }