merge sanjiangyuan-sub r5057

This commit is contained in:
wlx 2014-12-22 06:37:02 +00:00
parent c9727e73fd
commit 8a2c226431
9 changed files with 3350 additions and 3007 deletions

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
<?= $this->error ?> <?= $this->error ?>
</div> </div>
<?php }?> <?php }?>
<form class="form-horizontal" method="post" action=""> <form class="form-horizontal" method="post" action="">
<div class="control-group"> <div class="control-group">
<label class="control-label" for="inputUUID">UUID</label> <label class="control-label" for="inputUUID">UUID</label>
@ -53,32 +54,106 @@
</label> </label>
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label" for="inputData">数据读取SQL或表名</label> <label class="control-label">默认绘制类型</label>
<div class="controls"> <div class="controls">
<textarea name="data" rows="4" class="input-block-level" id="inputData"><?= !isset($this->info['data']) ? "":$this->info['data']?></textarea> <label class="radio inline">
<input type="radio" name="visual_type" id="optionsRadios1" value="line" <?= (isset($this->info['visual_type']) && $this->info['visual_type']=='line') || empty($this->info['visual_type']) ? "checked":"" ?>>
折线图
</label>
<label class="radio inline">
<input type="radio" name="visual_type" id="optionsRadios2" value="column"
<?= isset($this->info['visual_type']) && $this->info['visual_type'] == 'column' ? 'checked="checked"':"" ?>>
柱状图
</label>
</div> </div>
</div> </div>
<?php if(empty($this->info['vars'])) { ?>
<div class="control-group"> <div class="control-group">
<label class="control-label" for="inputVariable">可视化要素</label> <label class="control-label">数据表</label>
<div class="controls"> <div class="controls">
<input type="text" id="inputVariable" placeholder="Variable" class="input-block-level" name="var[]"> <select name="visual_datatable" id="data-table">
<option value="0">请选择</option>
<?php foreach($this->visualTable as $k=>$v){ ?>
<?php if(isset($this->info['visual_datatable']) && $this->info['visual_datatable']==$v){ ?>
<option value="<?= $v ?>" selected="selected"><?= $v ?></option>
<?php }else{ ?>
<option value="<?= $v ?>"><?= $v ?></option>
<?php } ?>
<?php } ?>
</select>
</div> </div>
</div> </div>
<?php }else{ ?>
<div class="control-group">
<label class="control-label">时间字段模式</label>
<div class="controls" id="field-time-model">
<label class="radio inline">
<input type="radio" name="visual_timefield_model" id="model-single" value="single" <?= (isset($this->info['visual_timefield_model']) && $this->info['visual_timefield_model']=='single') || !isset($this->info['visual_timefield_model']) || empty($this->info['visual_timefield_model']) ? 'checked="checked"':'' ?> /> 单字段
</label>
<label class="radio inline">
<input type="radio" name="visual_timefield_model" id="model-multiple" value="multiple" <?= isset($this->info['visual_timefield_model']) && $this->info['visual_timefield_model']=='multiple' ? 'checked="checked"':'' ?> /> 多字段拼接
</label>
<label class="radio inline">
<input type="radio" name="visual_timefield_model" id="model-custom" value="custom" <?= isset($this->info['visual_timefield_model']) && $this->info['visual_timefield_model']=='custom' ? 'checked="checked"':'' ?>/> 自定义
</label>
<p class="help-block">时间字段支持单字段或者“年月日“字段拼接模式</p>
</div>
</div>
<div class="control-group time-field-select">
<label class="control-label">时间字段</label>
<!-- 单字段 -->
<div class="controls" id="field-time" style="<?= isset($this->info['visual_timefield_model']) && $this->info['visual_timefield_model']!='single' && !empty($this->info['visual_timefield_model']) ? 'display:none':'' ?>">
</div>
<!-- 多字段 -->
<div class="controls" id="field-time-multiple" style="<?= (isset($this->info['visual_timefield_model']) && $this->info['visual_timefield_model']!='multiple') || empty($this->info['visual_timefield_model']) ? 'display:none':'' ?>">
<input type="text" name="visual_timefield_year" placeholder="年字段" value="<?= isset($this->info['visual_timefield_year']) ? $this->info['visual_timefield_year']:'' ?>" /> -
<input type="text" name="visual_timefield_month" placeholder="月字段" value="<?= isset($this->info['visual_timefield_month']) ? $this->info['visual_timefield_month']:'' ?>" /> -
<input type="text" name="visual_timefield_day" placeholder="日字段" value="<?= isset($this->info['visual_timefield_day']) ? $this->info['visual_timefield_day']:'' ?>" />
<p class="help-block">请填写正确的字段名称,如果没有对应字段请留空(<a href="javascript:void(0);" id="open-field-helper">查看字段提示</a>)</p>
</div>
<!-- 自定义 -->
<div class="controls" id="field-time-custom" style="<?= (isset($this->info['visual_timefield_model']) && $this->info['visual_timefield_model']!='custom') || empty($this->info['visual_timefield_model']) ? 'display:none':'' ?>">
<input type="text" name="visual_timefield_custom" placeholder="时间字段读取SQL" class="input-block-level" value="<?= isset($this->info['visual_timefield_custom']) ? $this->info['visual_timefield_custom']:'' ?>" />
<p class="help-block">例如: times , (year||'-'||month||'-1')::timestamp without time zone ,不需要在最外层加括号或者双引号</p>
</div>
</div>
<div class="control-group">
<label class="control-label" for="inputData">数据读取SQL或表名</label>
<div class="controls">
<textarea name="data" rows="4" class="input-block-level" id="inputData"><?= !isset($this->info['data']) ? "":$this->info['data']?></textarea>
<p class="help-block">如果填写了数据表SQL程序将自动从这个SQL</p>
</div>
</div>
<div class="control-group">
<label class="control-label" for="inputValuefilter">过滤值</label>
<div class="controls">
<input type="text" name="visual_valuefilter" class="" id="inputValuefilter" value="<?= !isset($this->info['visual_valuefilter']) ? "":$this->info['visual_valuefilter']?>" />
<p class="help-block">不予显示的值,仅数字</p>
</div>
</div>
<?php if(!empty($this->info['vars'])) { ?>
<?php $vars = array() ?> <?php $vars = array() ?>
<?php $encoder = new \Westdc\Visual\VariableEncoder; ?> <?php $encoder = new \Westdc\Visual\VariableEncoder; ?>
<?php $vars = $encoder->decode($this->info['vars']);?> <?php $vars = $encoder->decode($this->info['vars']);?>
<?php foreach($vars as $k=>$v) { ?> <?php foreach($vars as $k=>$v) { ?>
<div class="control-group"> <div class="control-group var-group">
<label class="control-label" for="inputVariable">可视化要素 <small><a href="javascript:void(0);" onclick="delVar(this)">删除</a></small></label> <label class="control-label" for="inputVariable">可视化要素 <small><a href="javascript:void(0);" onclick="delVar(this)">删除</a></small></label>
<div class="controls"> <div class="controls">
<input type="text" id="inputVariable" placeholder="Variable" class="input-block-level" name="var[]" value="<?= $v ?>"> 字段<input type="text" name="var[<?=$k?>][field]" value="<?= $v['field'] ?>" readonly />
显示名<input type="text" name="var[<?= $k ?>][name]" value="<?= $v['name'] ?>">
</div> </div>
</div> </div>
<?php } ?> <?php } ?>
<?php } ?> <?php } ?>
<div class="control-group" id="last-control-group"> <div class="control-group" id="last-control-group">
<div class="controls"> <div class="controls">
<input type="hidden" name="submit" value="1" /> <input type="hidden" name="submit" value="1" />
@ -90,16 +165,146 @@
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
$('#addVariable').click(function(e) { var fieldData,fieldHtml,varHtml,current_count;
html = '<div class="control-group">'
+ '<label class="control-label" for="inputVariable">可视化要素 <small><a href="javascript:void(0);" onclick="delVar(this)">删除</a></small></label>' function makeVarSelectHtml(field_data){
+ '<div class="controls">'
+ '<input type="text" id="inputVariable" placeholder="Variable" class="input-block-level" name="var[]">' current_count = $('.var-group').length;
+ '</div>'
+'</div>'; fieldHtml = []
$('#last-control-group').prepend(html);
}); for(i in field_data)
{
fieldHtml.push('<option value="'+ fieldData[i] +'">'+ fieldData[i] +'</option>');
}
varHtml = '<select name="var['+current_count+'][field]">' + fieldHtml.join('') + '</select>';
html = '<div class="control-group var-group">'
+ '<label class="control-label" for="inputVariable">可视化要素 <small><a href="javascript:void(0);" onclick="delVar(this)">删除</a></small></label>'
+ '<div class="controls">'
+ '字段' + varHtml
+ ' 显示名 <input type="text" placeholder="Variable" class="input-small" name="var['+current_count+'][name]">'
+ '</div>'
+'</div>';
return html;
}
function delVar(dom){ function delVar(dom){
$(dom).parent().parent().parent('.control-group').remove(); $(dom).parent().parent().parent('.control-group').remove();
} };
$(document).ready(function(){
$('#data-table').change(function(){
$('.var-group').remove();
$.ajax({
type:"POST",
url:'',
data:'tablename='+ $(this).val(),
success:function(data){
fieldData = data;
html = [];
for(i in data)
{
html.push('<option value="' + data[i] + '">' + data[i] + '</option>');
}
html = '<select name="visual_timefield">' + html.join('')+'</select>';
$('#field-time').html(html);
},
beforeSend:function(){
$('#field-time').html('加载中');
}
});
});
<?php if(!empty($this->info['ts_created'])) { ?>
$.ajax({
type:"POST",
url:'',
data:'tablename=<?= $this->info['visual_datatable'] ?>',
success:function(data){
fieldData = data;
html = [];
for(i in data)
{
if('<?= $this->info['visual_timefield'] ?>' == data[i])
html.push('<option value="' + data[i] + '" selected="selected">' + data[i] + '</option>');
else
html.push('<option value="' + data[i] + '">' + data[i] + '</option>');
}
html = '<select name="visual_timefield">' + html.join('')+'</select>';
$('#field-time').html(html);
},
beforeSend:function(){
$('#field-time').html('加载中');
}
});
<?php } ?>
$('#addVariable').click(function(e) {
if(null == fieldData || $('#data-table').val() == '0')
{
alert('请先选择数据表和时间字段');
return false;
}
if($('#var-group').length > 0)
$('#var-group').append(makeVarSelectHtml(fieldData));
else
$('#last-control-group').prepend(makeVarSelectHtml(fieldData));
});
$('#model-single').change(function(){
if($(this).checked = "checked")
{
$('#field-time').show();
$('#field-time-multiple').hide();
$('#field-time-custom').hide();
}
});
$('#model-multiple').change(function(){
if($(this).checked = "checked")
{
$('#field-time').hide();
$('#field-time-multiple').show();
$('#field-time-custom').hide();
}
});
$('#model-custom').change(function(){
if($(this).checked = "checked")
{
$('#field-time').hide();
$('#field-time-multiple').hide();
$('#field-time-custom').show();
}
});
$('#open-field-helper').click(function(){
if(null == fieldData || $('#data-table').val() == '0')
{
alert('请先选择数据表和时间字段');
return false;
}
$('.modal-body p').html(fieldData.join(','));
$('#modal-show-field').modal('show');
});
});
</script> </script>
<div id="modal-show-field" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">字段列表</h3>
</div>
<div class="modal-body">
<p></p>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">关闭</button>
<button class="btn btn-primary">Save changes</button>
</div>
</div>

View File

@ -27,7 +27,7 @@
<p class="content"><?= $item['description']; ?></p> <p class="content"><?= $item['description']; ?></p>
<p> <p>
操作: 操作:
<a href="/admin/data/visual/uuid/<?php echo $item['uuid'];?>">编辑可视化要素</a> | <a href="/admin/data/visual/uuid/<?php echo $item['uuid'];?>">编辑可视化要素</a> |
<a href="/visual/view/uuid/<?= $item['uuid'] ?>">前台预览</a> <a href="/visual/view/uuid/<?= $item['uuid'] ?>">前台预览</a>
</p> </p>
</li> </li>

View File

@ -50,12 +50,9 @@ class VisualController extends Zend_Controller_Action
$this->_helper->layout->disableLayout(); $this->_helper->layout->disableLayout();
$uuid = $this->_getParam("uuid"); $uuid = $this->_getParam("uuid");
$record_type = $this->_getParam("dataset"); //$record_type = $this->_getParam("dataset");
$record_subset = $this->_getParam("subdataset"); $record_subset = $this->_getParam("subdataset");
if(empty($record_type))
return true;
$record = new Visual\Record($uuid,$record_subset); $record = new Visual\Record($uuid,$record_subset);
//$record = Visual\Factory::Bootstrap($record_type); //$record = Visual\Factory::Bootstrap($record_type);

View File

@ -18,8 +18,8 @@ $this->nav[] = array('link'=>"/data/visual",'title'=>'可视化数据列表');
<div class="row-fluid"> <div class="row-fluid">
<div class="span6"> <div class="span6">
<div class="btn-group linetypes" data-toggle="buttons-radio"> <div class="btn-group linetypes" data-toggle="buttons-radio">
<button type="button" class="btn active" value="line">折线图</button> <button type="button" class="btn<?= (isset($this->data['visual_type']) && $this->data['visual_type'] == 'line') || empty($this->data['visual_type']) ? " active":"" ?>" value="line">折线图</button>
<button type="button" class="btn" value="column">柱状图</button> <button type="button" class="btn<?= isset($this->data['visual_type']) && $this->data['visual_type'] == 'column' ? " active":"" ?>" value="column">柱状图</button>
</div> </div>
</div> </div>
<div class="span6 text-right"> <div class="span6 text-right">
@ -31,9 +31,10 @@ $this->nav[] = array('link'=>"/data/visual",'title'=>'可视化数据列表');
<hr /> <hr />
<?php $vars = (new \Westdc\Visual\VariableEncoder)->normaldecode($this->data['vars']);?> <?php $vars = (new \Westdc\Visual\VariableEncoder)->normaldecode($this->data['vars']);?>
<?php foreach($vars as $k=>$v) { ?> <?php foreach($vars as $k=>$v) { ?>
<a class="btn btn-default control-btn" href="javascript:void(0);" data-dataset="<?= $v['dataset'] ?>" data-subdataset="<?= $v['subdataset'] ?>" data-seriename="<?= $v['seriename'] ?>"> <a class="btn btn-default control-btn" href="javascript:void(0);" data-dataset="" data-subdataset="<?= $v['field'] ?>" data-seriename="<?= $v['name'] ?>">
<?= $v['seriename'] ?> <?= $v['name'] ?>
</a> </a>
<?php } ?> <?php } ?>
@ -51,6 +52,13 @@ _this = {};
_this.linetype = 'line'; _this.linetype = 'line';
_this.utctimezone = false; _this.utctimezone = false;
$(function() { $(function() {
$('.linetypes button').each(function(){
if($(this).hasClass('active'))
{
_this.linetype = $(this).val();
}
});
$('.linetypes button').click(function(e) { $('.linetypes button').click(function(e) {
_this.linetype = $(this).val(); _this.linetype = $(this).val();
@ -88,7 +96,7 @@ $(function() {
week: '%Y<br/>%m-%d', week: '%Y<br/>%m-%d',
month: '%Y-%m', month: '%Y-%m',
year: '%Y' year: '%Y'
}, }
}, },

View File

@ -0,0 +1,35 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2014/12/4
* Time: 11:31
*/
namespace Westdc\Visual;
class DataTableControl extends Database{
function __construct()
{
parent::__construct();
}
public function readTables()
{
$sql = "SELECT tablename FROM pg_tables WHERE tablename LIKE 'data_%' ORDER BY tablename ";
$rs = $this->db->query($sql);
$row = $rs->fetchAll(\PDO::FETCH_COLUMN);
return $row;
}
public function readFields($tableName)
{
$sql = "select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='$tableName'";
$rs = $this->db->query($sql);
return $rs->fetchAll(\PDO::FETCH_COLUMN);
}
}

View File

@ -0,0 +1,34 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2014/12/4
* Time: 11:28
*/
namespace Westdc\Visual;
class Database {
public $db;
function __construct()
{
$this->initDatabase();
}
public function initDatabase()
{
$config = \Zend_Registry::get('config');
$dsn = "pgsql:host={$config->visual_db->hostname};"
."port={$config->visual_db->port};"
."dbname={$config->visual_db->database};"
."user={$config->visual_db->username};"
."password={$config->visual_db->password}";
$this->db = new \PDO($dsn);
}
}

View File

@ -1,106 +1,155 @@
<?php <?php
namespace Westdc\Visual; namespace Westdc\Visual;
class Record class Record extends Database
{ {
public $db; public $subdataset,$valueFilter;
public $subdataset; public $timeFiled = "utctime";
public $timeFiled = "utctime"; private $sql;
private $sql; function __construct($uuid = NULL,$identifier = "")
{
function __construct($uuid = NULL,$identifier = "") parent::__construct();
{
$this->initDatabase(); if(!empty($identifier))
{
if(!empty($identifier)) $this->subdataset = $identifier;
{ }
$this->subdataset = $identifier;
} if(!empty($uuid) && !empty($identifier))
{
if(!empty($uuid) && !empty($identifier)) $this->initVisual($uuid);
{ }
$this->initVisual($uuid); }
}
} public function __invoke()
{
public function __invoke() return $this->getData();
{ }
return $this->getData();
} public function initVisual($uuid)
{
public function initDatabase() $visual = new Visual;
{
$config = \Zend_Registry::get('config'); $var_data = $visual->getVisualVars($uuid);
$dsn = "pgsql:host={$config->visual_db->hostname};" if(!empty($var_data['visual_valuefilter']))
."port={$config->visual_db->port};" $this->valueFilter = (float)$var_data['visual_valuefilter'];
."dbname={$config->visual_db->database};"
."user={$config->visual_db->username};" if($var_data['visual_timefield_model'] == 'single') {
."password={$config->visual_db->password}"; $this->timeFiled = '"' . $var_data['visual_timefield'] . '"';
}//single
$this->db = new \PDO($dsn); elseif($var_data['visual_timefield_model'] == 'multiple'){
} $timefield_temp = "(";
if(!empty($var_data['visual_timefield_year']))
public function initVisual($uuid) {
{ $timefield_temp .= $var_data['visual_timefield_year'] . "::character varying||";
$visual = new Visual; }
$var_data = $visual->getVisualVars($uuid); $timefield_temp .= "'-'";
$this->sql = $this->makeSql($var_data['data'],$this->subdataset); if(!empty($var_data['visual_timefield_month']))
{
//echo $this->sql;exit(); $timefield_temp .= "||".$var_data['visual_timefield_month']."::character varying||";
} }else{
$timefield_temp .= '1';
public function getSql() }
{
return $this->sql; $timefield_temp .= "'-";
}
if(!empty($var_data['visual_timefield_day']))
public function getData() {
{ $timefield_temp .= "'||".$var_data['visual_timefield_day'] . '::character varying';
$rs = $this->db->query($this->sql); }else{
$timefield_temp .= "1'";
$data = []; }
while($row = $rs->fetch(\PDO::FETCH_ASSOC))
{ $timefield_temp .= ")";
$row['utctime'] = $this->utcMsTime(strtotime($row['utctime'])); $timefield_temp .= "::timestamp without time zone";
//var_dump($row);
$data[] = array( $this->timeFiled = $timefield_temp;
$row['utctime'], }//multiple
$row['value'] elseif($var_data['visual_timefield_model'] == 'custom'){
); $this->timeFiled = $var_data['visual_timefield_model'];
} }//custom
return $data; //时间字段为空的bug
} if(empty($var_data['visual_timefield_model'])){
$this->timeFiled = "utctime";
public function makeSql($table,$fieldValue) }else{
{ if($var_data['visual_timefield_model'] == 'single' && empty($var_data['visual_timefield'])){
$sql = "SELECT $this->timeFiled = "utctime";
{$this->timeFiled} as utctime , \"$fieldValue\" as value }elseif($var_data['visual_timefield_model'] == 'multiple' && empty($var_data['visual_timefield_year'])){
FROM $table $this->timeFiled = "utctime";
ORDER BY }elseif($var_data['visual_timefield_model'] == 'custom' && empty($var_data['visual_timefield_custom'])) {
extract(YEAR from \"{$this->timeFiled}\") ASC, $this->timeFiled = "utctime";
extract(MONTH from \"{$this->timeFiled}\") ASC, }
extract(DAY from \"{$this->timeFiled}\") ASC, }
extract(HOUR from \"{$this->timeFiled}\") ASC,
extract(MINUTE from \"{$this->timeFiled}\") ASC, if(isset($var_data['data']) && !empty($var_data['data']))
extract(SECOND from \"{$this->timeFiled}\") ASC $this->sql = $this->makeSql($var_data['data'],$this->subdataset);
"; else
$this->sql = $this->makeSql($var_data['visual_datatable'],$this->subdataset);
return $sql;
} //echo $this->sql;exit();
}
public function utcMsTime($time=''){
if(empty($time)) public function getSql()
return (time()+8*3600)*1000; {
else return $this->sql;
return $time*1000; }
}
public function getData()
{
$rs = $this->db->query($this->sql);
$data = [];
while($row = $rs->fetch(\PDO::FETCH_ASSOC))
{
$row['utctime'] = $this->utcMsTime(strtotime($row['utctime']));
//var_dump($row);
$data[] = array(
$row['utctime'],
$row['value']
);
}
return $data;
}
public function makeSql($table,$fieldValue)
{
$wheresql = "";
if(!empty($this->valueFilter))
{
$wheresql = " WHERE \"$fieldValue\"<>".$this->valueFilter .' ';
}
$sql = "SELECT
{$this->timeFiled} as utctime , \"$fieldValue\" as value
FROM $table as tbl
$wheresql
ORDER BY
extract(YEAR from {$this->timeFiled}) ASC,
extract(MONTH from {$this->timeFiled}) ASC,
extract(DAY from {$this->timeFiled}) ASC,
extract(HOUR from {$this->timeFiled}) ASC,
extract(MINUTE from {$this->timeFiled}) ASC,
extract(SECOND from {$this->timeFiled}) ASC
";
return $sql;
}
public function utcMsTime($time=''){
if(empty($time))
return (time()+8*3600)*1000;
else
return ($time)*1000;
}
} }

View File

@ -15,25 +15,13 @@ class VariableEncoder
public function encode($vars) public function encode($vars)
{ {
$arr = []; return json_encode($vars);
foreach($vars as $k=>$v)
{
$names = explode("|",$v);
$arr[] = [ 'dataset' => $names[0], 'subdataset' => $names[1],'seriename' => $names[2]];
}
return json_encode($arr);
} }
public function decode($json) public function decode($json)
{ {
$arr = json_decode($json,true); $arr = json_decode($json,true);
//var_dump($arr); return $arr;
$data = [];
foreach($arr as $k=>$v)
{
$data[$k] = join("|",$v);
}
return $data;
} }
public function normaldecode($json) public function normaldecode($json)