cell_group_field

master
vitalif 2010-07-28 15:07:42 +00:00
parent e9ab8df823
commit 2b9454371a
4 changed files with 88 additions and 96 deletions

View File

@ -894,9 +894,9 @@ $iset";
}
/* ключи хеша или массива */
function function_keys($a) { return "array_keys($a)"; }
function function_hash_keys($a) { return "array_keys($a)"; }
function function_array_keys($a) { return "array_keys($a)"; }
function function_keys($a) { return "array_keys(is_array($a) ? $a : array())"; }
function function_hash_keys($a) { return "array_keys(is_array($a) ? $a : array())"; }
function function_array_keys($a) { return "array_keys(is_array($a) ? $a : array())"; }
// создание массива
function function_array()
@ -917,9 +917,9 @@ $iset";
// получить элемент хеша/массива по неконстантному ключу (например get(iteration.array, rand(5)))
// по-моему, это лучше, чем Template Toolkit'овский ад - hash.key.${another.hash.key}.зюка.хрюка и т.п.
function function_get($a, $k) { return $a."[$k]"; }
function function_hget($a, $k) { return $a."[$k]"; }
function function_aget($a, $k) { return $a."[$k]"; }
function function_get($a, $k=NULL) { if ($k !== NULL) return $a."[$k]"; return "\$this->tpldata[$a]"; }
function function_hget($a, $k=NULL) { if ($k !== NULL) return $a."[$k]"; return "\$this->tpldata[$a]"; }
function function_aget($a, $k=NULL) { if ($k !== NULL) return $a."[$k]"; return "\$this->tpldata[$a]"; }
// shift, unshift, pop, push
function function_shift($a) { return "array_shift($a)"; }

View File

@ -33,10 +33,15 @@ class OLAP
'min' => array('name' => 'Минимум', 'sql' => 'MIN($)'),
'max' => array('name' => 'Максимум', 'sql' => 'MAX($)'),
'stddev' => array('name' => 'Дисперсия', 'sql' => 'STDDEV($)'),
'distinct' => array('name' => 'Значения', 'cell_only' => true),
'n_uniq' => array('name' => 'Количество уникальных', 'sql' => 'COUNT(DISTINCT $)'),
# 'equally' => array('name' => '', ),
);
static $specf = array(
'v_field', 'v_func', 'h_field', 'h_func',
'cell_field', 'cell_aggr', 'cell_func', 'cell_group_field', 'cell_group_func',
'v_sort_dir', 'v_sort_field', 'v_sort_aggr', 'v_sort_func',
'h_sort_dir', 'h_sort_field', 'h_sort_aggr', 'h_sort_func',
);
static $specf = array('v_field', 'v_func', 'h_field', 'h_func', 'cell_field', 'cell_aggr', 'cell_func', 'v_sort_dir', 'v_sort_field', 'v_sort_aggr', 'v_sort_func', 'h_sort_dir', 'h_sort_field', 'h_sort_aggr', 'h_sort_func');
static function execute($request)
{
@ -83,15 +88,16 @@ class OLAP
$wh["value-$i"] = $v;
if ($fd['is_time'])
$v = Template::timestamp($v, self::$current_src['fielddefs'][$f]['format']);
$dn = $fd['dbname'];
$dn = $fd['sql'];
if (!$dn)
$dn = $f;
$v = mysql_ecranize($v);
if ($t == 'eq')
$where[$dn] = $v;
$where[] = "$dn = $v";
elseif ($t == 'ge')
$where[] = "$dn >= ".mysql_ecranize($v);
$where[] = "$dn >= $v";
elseif ($t == 'le')
$where[] = "$dn <= ".mysql_ecranize($v);
$where[] = "$dn <= $v";
}
}
@ -131,6 +137,12 @@ class OLAP
$fields[] = $h_sql.' h_field';
$options['GROUP BY'][] = $h_sql;
}
if ($cell_group_field !== '')
{
$cg_sql = self::sql_trans_field($cell_group_field, $cell_group_func);
$fields[] = $cg_sql.' cell_group_field';
$options['GROUP BY'][] = $cg_sql;
}
$cell_sql = self::sql_trans_field($cell_field, $cell_func);
if (self::$aggregates[$cell_aggr]['sql'])
$fields[] = str_replace('$', $cell_sql, self::$aggregates[$cell_aggr]['sql']).' cell_field';
@ -147,16 +159,28 @@ class OLAP
$hkeys = array();
while ($r = mysql_fetch_assoc($result))
{
$v = &$group[$r['v_field']][$r['h_field']];
if ($cell_group_field !== '')
$v = &$v[$r['cell_group_field']];
if ($do_aggr)
call_user_func_array('self::aggr_update_'.$cell_aggr, array(&$group[$r['v_field']][$r['h_field']], &$r['cell_field']));
call_user_func_array('self::aggr_update_'.$cell_aggr, array(&$v, &$r['cell_field']));
else
$group[$r['v_field']][$r['h_field']] = $r['cell_field'];
$v = $r['cell_field'];
$hkeys[$r['h_field']] = 1;
}
unset($v);
if ($do_aggr && is_callable('self::aggr_finish_'.$cell_aggr))
foreach ($group as $i => &$r)
foreach ($r as $j => &$c)
call_user_func_array('self::aggr_finish_'.$cell_aggr, array(&$c));
{
if ($cell_group_field !== '')
foreach ($group as $i => &$r)
foreach ($r as $j => &$c)
call_user_func_array('self::aggr_finish_'.$cell_aggr, array(&$c));
else
foreach ($group as $i => &$r)
foreach ($r as $j => &$c)
foreach ($c as $k => &$g)
call_user_func_array('self::aggr_finish_'.$cell_aggr, array(&$g));
}
if ($v_field !== '' && $v_sort_aggr !== '' && $v_sort_field !== '')
{
@ -215,9 +239,11 @@ class OLAP
static function sql_trans_field($field, $func)
{
$fd = &self::$current_src['fielddescs'][$field];
$sql = $field;
if (self::$current_src['fielddescs'][$field]['is_time'] &&
self::$current_src['fielddescs'][$field]['format'] == TS_UNIX &&
if ($fd['sql'])
$sql = $fd['sql'];
if ($fd['is_time'] && $fd['format'] == TS_UNIX &&
(!self::$functions[$func] || self::$functions[$func]['time_format']))
$sql = "FROM_UNIXTIME($sql)";
if (self::$functions[$func])
@ -256,15 +282,7 @@ class OLAP
static function field_format($field, $func, $aggr, $value)
{
$o = &self::$current_src['fielddescs'][$field]['options_hash'];
if ($aggr == 'distinct')
{
$r = '';
if ($value)
foreach($value as $k => $n)
$r .= self::field_format($field, $func, false, $k).': '.$n.(self::$is_html_format ? "<br />" : "")."\n";
return $r;
}
elseif ($o && $o[$value])
if ($o && $o[$value])
return $o[$value];
elseif (preg_match('/^-?\d+\.\d+$/s', $value))
return sprintf(self::$decimal, $value);

View File

@ -19,18 +19,7 @@
<table>
<tr><td style="text-align: center; vertical-align: middle"><input type="submit" value=" Построить отчёт " /></td><td style="background-color: #e0e0e0; padding: 8px">
По горизонтали:<br />
<select style="width:100px" name="h_field">
<option value="">---</option>
<!-- FOR f = fielddescs -->
<option value="{s f.id}"<!-- IF eq(h_field, f.id) --> selected<!-- END -->>{s f.name}</option>
<!-- END -->
</select>
<select style="width:100px" name="h_func">
<option value="">без преобразования</option>
<!-- FOR f = functions -->
<option value="{s f.id}"<!-- IF eq(h_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
<!-- END -->
</select><br />
<!-- SET fld = 'h' --><!-- INCLUDE admin_olap_field.tpl --><br />
Сортировка:<br />
<select style="width:100px" name="h_sort_dir">
<option value="asc">по возрастанию</option>
@ -39,38 +28,14 @@
<select style="width:100px" name="h_sort_aggr">
<option value="">по значениям поля</option>
<!-- FOR f = aggregates -->
<!-- IF NOT f.cell_only -->
<option value="{s f.id}"<!-- IF eq(h_sort_aggr, f.id) --> selected<!-- END -->>{s f.name} другого поля:</option>
<!-- END -->
<!-- END -->
</select>
<select style="width:100px" name="h_sort_field">
<option value="">---</option>
<!-- FOR f = fielddescs -->
<option value="{s f.id}"<!-- IF eq(h_sort_field, f.id) --> selected<!-- END -->>{s f.name}</option>
<!-- END -->
</select>
<select style="width:100px" name="h_sort_func">
<option value="">без преобразования</option>
<!-- FOR f = functions -->
<option value="{s f.id}"<!-- IF eq(h_sort_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
<!-- END -->
</select>
</select>
<!-- SET fld = 'h_sort' --><!-- INCLUDE admin_olap_field.tpl -->
</td></tr>
<tr><td style="background-color: #e0e0e0; padding: 8px">
По вертикали:<br />
<select style="width:100px" name="v_field">
<option value="">---</option>
<!-- FOR f = fielddescs -->
<option value="{s f.id}"<!-- IF eq(v_field, f.id) --> selected<!-- END -->>{s f.name}</option>
<!-- END -->
</select>
<select style="width:100px" name="v_func">
<option value="">без преобразования</option>
<!-- FOR f = functions -->
<option value="{s f.id}"<!-- IF eq(v_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
<!-- END -->
</select><br />
<!-- SET fld = 'v' --><!-- INCLUDE admin_olap_field.tpl --><br />
Сортировка:<br />
<select style="width:100px" name="v_sort_dir">
<option value="asc">по возрастанию</option>
@ -79,41 +44,20 @@
<select style="width:100px" name="v_sort_aggr">
<option value="">по значениям поля</option>
<!-- FOR f = aggregates -->
<!-- IF NOT f.cell_only -->
<option value="{s f.id}"<!-- IF eq(v_sort_aggr, f.id) --> selected<!-- END -->>{s f.name} другого поля:</option>
<!-- END -->
<!-- END -->
</select>
<select style="width:100px" name="v_sort_field">
<option value="">---</option>
<!-- FOR f = fielddescs -->
<option value="{s f.id}"<!-- IF eq(v_sort_field, f.id) --> selected<!-- END -->>{s f.name}</option>
<!-- END -->
</select>
<select style="width:100px" name="v_sort_func">
<option value="">без преобразования</option>
<!-- FOR f = functions -->
<option value="{s f.id}"<!-- IF eq(v_sort_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
<!-- END -->
</select>
</select>
<!-- SET fld = 'v_sort' --><!-- INCLUDE admin_olap_field.tpl -->
</td><td style="background-color: #ffe0e0; padding: 8px">
В таблице:<br />
<select style="width:100px" name="cell_aggr">
<!-- FOR f = aggregates -->
<option value="{s f.id}"<!-- IF eq(cell_aggr, f.id) --> selected<!-- END -->>{s f.name}</option>
<!-- END -->
</select>
<select style="width:100px" name="cell_field">
<!-- FOR f = fielddescs -->
<option value="{s f.id}"<!-- IF eq(cell_field, f.id) --> selected<!-- END -->>{s f.name}</option>
<!-- END -->
</select>
<select style="width:100px" name="cell_func">
<option value="">без преобразования</option>
<!-- FOR f = functions -->
<option value="{s f.id}"<!-- IF eq(cell_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
<!-- END -->
</select>
</select>
<!-- SET fld = 'cell' --><!-- INCLUDE admin_olap_field.tpl --><br />
Дополнительно разбить по:<br />
<!-- SET fld = 'cell_group' --><!-- INCLUDE admin_olap_field.tpl --><br />
</td></tr>
</table>
Условия выборки данных:
@ -150,10 +94,28 @@
<!-- IF NOT data -->
<p>Нет данных для показа.</p>
<!-- ELSE -->
<!-- SET hascg = strlen(cell_group_field) -->
<table class="simpletable">
<tr><th></th><!-- FOR k = hkeys --><th>{fformat(h_field,h_func,'',k)}</th><!-- END --><!-- IF vsort --><th></th><!-- END --></tr>
<tr><th></th><!-- FOR k = hkeys --><th>{fformat(h_field,h_func,'',k)}</th><!-- END --><!-- IF vsort --><th></th><!-- END --></tr>
<!-- FOR v = vkeys -->
<tr><th>{fformat(v_field,v_func,'',v)}</th><!-- FOR k = hkeys --><td>{fformat(cell_field,cell_func,cell_aggr,get(get(data,v),k))}</td><!-- END --><!-- IF vsort --><th>{get(vsort,v)}</th><!-- END --></tr>
<tr>
<th>{fformat(v_field,v_func,'',v)}</th>
<!-- FOR k = hkeys -->
<td>
<!-- SET cv = get(get(data,v),k) -->
<!-- IF hascg -->
<!-- FOR ck = keys(cv) -->
{fformat(cell_group_field,cell_group_func,'',ck)}: {fformat(cell_field,cell_func,cell_aggr,get(cv,ck))}<br />
<!-- END -->
<!-- ELSE -->
{fformat(cell_field,cell_func,cell_aggr,cv)}
<!-- END -->
</td>
<!-- END -->
<!-- IF vsort -->
<th>{get(vsort,v)}</th>
<!-- END -->
</tr>
<!-- END -->
<!-- IF hsort -->
<tr><th></th><!-- FOR k = hkeys --><th>{get(hsort,k)}</th><!-- END --><!-- IF vsort --><th></th><!-- END --></tr>

View File

@ -0,0 +1,12 @@
<select style="width:100px" name="{fld}_field">
<option value="">---</option>
<!-- FOR f = fielddescs -->
<option value="{s f.id}"<!-- IF eq(get(concat(fld,'_field')), f.id) --> selected<!-- END -->>{s f.name}</option>
<!-- END -->
</select>
<select style="width:100px" name="{fld}_func">
<option value="">без преобразования</option>
<!-- FOR f = functions -->
<option value="{s f.id}"<!-- IF eq(get(concat(fld,'_func')), f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
<!-- END -->
</select>