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);
}
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 array $inputArgs
* @param \Parser $parser
* @param \PPFrame $frame
* @return string
*/
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;
}
}