效果如下:
页面介绍,页面分成四个部分,左侧树结构,顶端 查询条件栏,中间表格展示,下方可折叠面板;
准备工作:
新建Ext 文件夹,Models 文件夹,Pages 文件夹 按照下图创建好页面。
TreeModel 数据模型表示数据库表的结构,具体内容如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ExtExample.Models
{
[Serializable]
public class TreeModel
{
private int deviceId = 0;
public int DeviceId
{
get { return deviceId; }
set { deviceId = value; }
}
private string deviceName = "";
public string DeviceName
{
get { return deviceName; }
set { deviceName = value; }
}
//PID
private int thepid =0;
public int Thepid
{
get { return thepid; }
set { thepid = value; }
}
}
}
TreeStruct 表示自定义的树形结构,具体内容如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ExtExample.Models
{
public class TreeStruct
{
public string id; //必须唯一
public string text; //显示文本
public bool leaf; //是否叶子节点
public bool expanded; //是否展开
public object @checked; //是否可勾选,不需要显示勾选框时设置为null
public object icon; //节点图标路径,不需要显示图标时设置为null
public string qtip; //提示
public List<TreeStruct> children = new List<TreeStruct>(); //该树节点的子节点
}
}
TreeAndGrid.aspx.cs 为后台交互方法实现部分,打开如下所示,其他多余部分请删除;只保留头部
F7 进入后台代码编辑,主要内容如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ExtExample.Models;
using System.IO;
using System.Text;
using System.Web.Script.Serialization;
using System.Reflection;
using System.Collections;
namespace ExtExample.Pages
{
public partial class TreeAndGrid : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
String methodName = Request["method"]; //方法名称
MethodInfo method = this.GetType().GetMethod(methodName);
if (method == null)
throw new Exception("method is null");
try
{
method.Invoke(this, null); //方法调用
}
catch
{
}
}
//获取所有设备树
public void GetAllTree()
{
//数据源
//#region 顶层父节点
//List<Models.TreeModel> types = new List<Models.TreeModel>(); //设备类型
//Models.TreeModel model = new Models.TreeModel();
//model.DeviceId = 1;
//model.DeviceName = "软件开发";
//model.Thepid = 0;
//types.Add(model);
//#endregion
#region 叶节点
List<Models.TreeModel> typeModels = new List<Models.TreeModel>();//设备
Models.TreeModel model1 = new Models.TreeModel();
model1.DeviceId = 2;
model1.DeviceName = "需求分析";
model1.Thepid = 1;
typeModels.Add(model1);
Models.TreeModel model2 = new Models.TreeModel();
model2.DeviceId = 3;
model2.DeviceName = "客户需求调研";
model2.Thepid = 2;
typeModels.Add(model2);
Models.TreeModel model3 = new Models.TreeModel();
model3.DeviceId = 4;
model3.DeviceName = "生成需求文档";
model3.Thepid = 2;
typeModels.Add(model3);
Models.TreeModel model4 = new Models.TreeModel();
model4.DeviceId = 5;
model4.DeviceName = "系统分析";
model4.Thepid = 1;
typeModels.Add(model4);
Models.TreeModel model5 = new Models.TreeModel();
model5.DeviceId = 6;
model5.DeviceName = "数据库设计";
model5.Thepid = 5;
typeModels.Add(model5);
#endregion
#region 叶节点或父节点树结构生成
List<TreeStruct> nodes = new List<TreeStruct>(); //树节点
ArrayList typeIdAry = new ArrayList(); //根节点的类型Id
foreach (Models.TreeModel md in typeModels)
{
TreeStruct node = new TreeStruct();
//获取对象的属性值
int ariId = md.DeviceId;
string ariName = md.DeviceName;
node.id = ariId.ToString();
node.text = ariName;
node.leaf = true; //暂定为叶子节点
node.expanded = false;
nodes.Add(node);
bool hasExist = false;
for (int i = 0; i < typeIdAry.Count; i++)
{
if (md.Thepid.ToString() == typeIdAry[i].ToString())
{
hasExist = true;
break;
}
}
if (hasExist == false)
{
typeIdAry.Add(md.Thepid.ToString());
}
}
#endregion
#region 将子节点加入父节点生成最终树
List<TreeStruct> typeNodes = new List<TreeStruct>(); //类型树节点
foreach (Models.TreeModel mod in typeModels)
{
TreeStruct typeNode = new TreeStruct();
typeNode.id = "p" + mod.DeviceId;
typeNode.text = mod.DeviceName;
typeNode.leaf = false;
typeNode.expanded = true;
bool hasChild = false;
for (int i = 0; i < nodes.Count; i++)
{
int typeId = 0;
foreach (Models.TreeModel factoryModel in typeModels)
{
if (nodes[i].id == factoryModel.DeviceId.ToString())
{
typeId = factoryModel.Thepid;
break;
}
}
if (typeId == mod.DeviceId)
{
hasChild = true;
typeNode.children.Add(nodes[i]);
}
}
if (hasChild == true)
{
typeNodes.Add(typeNode);
}
}
#endregion
//树结构json字符串传到前端接收
string json = JsonListToString(typeNodes);
Response.Write(json);
}
private String JsonListToString(List<TreeStruct> list)
{
JavaScriptSerializer Serializerx = new JavaScriptSerializer();
string changestr = Serializerx.Serialize(list);
return changestr;
}
}
}
前台新建html 如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<meta charset="utf-8" />
<link href="../Ext/resources/css/ext-all.css" rel="stylesheet" />
<script src="Scripts/bootExtJS.js"></script>
<script src="../Ext/ext-all.js"></script>
<script src="../Ext/ext-lang-zh_CN.js"></script>
<script src="Scripts/TreeAndGrid.js"></script>
</head>
<body>
</body>
</html>
TreeAndGrid.js 文件编辑如下:
Ext.onReady(function () {
/设备列表树/
//树结构
var treeStore = Ext.create('Ext.data.TreeStore', {
proxy: {
type: "ajax",
actionMethods: { read: "POST" },
url: "TreeAndGrid.aspx?method=GetAllTree",
reader: { type: 'json' }
}
});
treeStore.load();
var tree = new Ext.create('Ext.tree.Panel', {
title: '设备列表',
rootVisible: false,//隐藏根节点。
store: treeStore,
listeners: {
itemclick: function (ee, record, item) //单击
{
var theId = tree.getSelectionModel().getLastSelected().data["id"]; //所选中树节点的Id
var tootSelected = tree.getSelectionModel().getLastSelected().data["parentId"];
var timeBegin = Ext.getCmp('theDate').getValue();
var check = Ext.getCmp('isWholeMonth').getValue();
if (tootSelected == "root") {
Panel1Show();
Ext.Ajax.request({
url: "EquipmentEnergyInfo.aspx?method=GetOneEquipmentParam",
method: 'POST',
params: {
ariId: theId,
typeAriId: tootSelected,
timeBegin: Ext.Date.format(timeBegin, 'Y-m-d'),
check: check,
}
});
}
else {
Panel2Show();
Ext.Ajax.request({
url: "EquipmentEnergyInfo.aspx?method=GetOneEquipmentParam",
method: 'POST',
params: {
ariId: theId,
typeAriId: tootSelected,
timeBegin: Ext.Date.format(timeBegin, 'Y-m-d'),
check: check,
}
});
}
//通过ajax方式获取指标信息
}
}
});
function btnOKClick() {
var record = tree.getSelectionModel().getLastSelected(); //获取选中行
var tootSelected;
if (record == null) {
WarningMsg('请在设备列表中选择设备!');
return;
}
else {
tootSelected = tree.getSelectionModel().getLastSelected().data["parentId"];
}
var timeBegin = Ext.getCmp('theDate').getValue();
var check = Ext.getCmp('isWholeMonth').getValue();
if (tootSelected == "root") {
Ext.MessageBox.wait("正在获取数据,请稍等..."); //显示进度条
Ext.Ajax.request({
url: 'EquipmentEnergyInfo.aspx?method=GetEquipmentEnergyTableRoot',
method: 'POST',
timeout: 300000, //default 30000 milliseconds
params: {
id: record.data["id"],
check: check,
timeBegin: Ext.Date.format(timeBegin, 'Y-m-d'),
},
success: function (response) {
if (response.responseText != null) {
Ext.MessageBox.hide(); //隐藏进度条
var json = eval('(' + response.responseText + ')'); //字符串转换为JSON
var jsonStore = Ext.create('Ext.data.JsonStore', {
data: json,
fields: ['deviceName', 'productnum', 'theEveryEle', 'theEleTable', 'theAvgEle', 'theProductEle', 'theProductEleP', 'theNProductEle', 'theNProductEleP', 'theAutoEle', 'theAutoEleP', 'theChangeModelEle', 'theChangeModelEleP'],
autoLoad: true
});
gridStore1.load();
}
else {
ErrorMsg('查询失败!');
}
}
});
var chartPanel1 = Ext.getCmp("chartPanel1");
chartPanel1.removeAll();
}
else {
Ext.MessageBox.wait("正在获取数据,请稍等..."); //显示进度条
Ext.Ajax.request({
url: 'EquipmentEnergyInfo.aspx?method=GetEquipmentEnergyTable',
method: 'POST',
timeout: 300000, //default 30000 milliseconds
params: {
id: record.data["id"],
check: check,
timeBegin: Ext.Date.format(timeBegin, 'Y-m-d'),
},
success: function (response) {
if (response.responseText != null) {
Ext.MessageBox.hide(); //隐藏进度条
var json = eval('(' + response.responseText + ')'); //字符串转换为JSON
var jsonStore = Ext.create('Ext.data.JsonStore', {
data: json,
fields: ['deviceName', 'productName', 'theQAD', 'theStartTime', 'theEndTime', 'productnum', 'theEle', 'theEveryEle'],
autoLoad: true
});
gridStore2.load();
}
else {
ErrorMsg('查询失败!');
}
}
});
//曲线
Ext.Ajax.request({
url: 'EquipmentEnergyInfo.aspx?method=GetChartData',
method: 'POST',
timeout: 300000, //default 30000 milliseconds
params: {
tagId: record.data["id"],
//timeType: Ext.getCmp('timeType').getValue(),
//timeBegin: Ext.Date.format(timeBegin, 'Y-m-d H:i'),
//timeEnd: Ext.Date.format(timeEnd, 'Y-m-d H:i'),
//isBase: record.data["isBase"],
//floatNum: Ext.getCmp("floatNum").getValue()
},
success: function (response) {
//var unit = record.data["theUnit"]; //单位
//var theSum = "(合计:0 " + unit + ")"; //合计
if (response.responseText != "") {
//Ext.MessageBox.hide(); //隐藏进度条
var chartPanel1 = Ext.getCmp("chartPanel1");
chartPanel1.removeAll();
//Ext.getCmp("theSum").setValue("");
return;
}
// //添加盛放图形的div
var echarts1 = document.getElementById('echarts1');
if (echarts1 == null || echarts1 == undefined) {
echarts1 = document.createElement("div"); //<DIV>
echarts1.id = "echarts1";
var chartPanel1 = Ext.getCmp("chartPanel1");
chartPanel1.removeAll();
chartPanel1.add(echarts1);
}
// //曲线数据
// var thePos = response.responseText.indexOf("@");
// //theSum = "(合计:" + response.responseText.substr(0, thePos) + " " + unit + ")";
// Ext.getCmp("theSum").setValue(response.responseText.substr(0, thePos));
// var jsons = eval('(' + response.responseText.substr(thePos + 1) + ')'); //字符串转换为JSON
// var timeAry = new Array();
// var dataAry = new Array();
// for (var index in jsons) {
// timeAry.push(jsons[index]["theTime"]);
// dataAry.push(jsons[index]["theValue"]);
// }
// //倍率
// var eleCoef = "";
// if (record.data["eleCoef"] != "")
// eleCoef = "(倍率:" + record.data["eleCoef"] + ")";
//路径配置
require.config({
paths: {
echarts: '../../Scripts/ECharts/dist'
}
});
//画曲线
require(
[
'echarts',
'echarts/chart/line'
],
function (ec) {
var myChart = ec.init(document.getElementById('echarts1')); //基于准备好的dom,初始化echarts图表
option6 = {
title: {
text: '当月能耗趋势',
subtext: '按日统计',
x: 'left',
padding: [10, 0, 5, 40],
textStyle: {
fontSize: 14
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
y: 'bottom',
data: ['煤', '电', '水', '原油', '天然气']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: ['04月28日', '04月29日', '04月30日', '05月01日', '05月02日', '05月03日', '05月04日']
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '煤',
type: 'line',
stack: '总量',
areaStyle: { normal: {} },
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '电',
type: 'line',
stack: '总量',
areaStyle: { normal: {} },
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '水',
type: 'line',
stack: '总量',
areaStyle: { normal: {} },
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: '原油',
type: 'line',
stack: '总量',
areaStyle: { normal: {} },
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: '天然气',
type: 'line',
stack: '总量',
label: {
normal: {
show: true,
position: 'top'
}
},
areaStyle: { normal: {} },
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
};
// var option =
// {
// backgroundColor: "#f1f1f1",
// title:
// {
// x: 'left',
// text: record.data["theDesc"] + '(' + Ext.getCmp("timeType").getRawValue() + ')趋势曲线' + eleCoef,
// padding: [10, 5, 5, 15],
// textStyle:
// {
// fontSize: 14,
// color: "#3d3b4f"
// },
// subtext: Ext.Date.format(timeBegin, 'Y-m-d') + ' 至 ' + Ext.Date.format(timeEnd, 'Y-m-d'),
// subtextStyle:
// {
// color: "#3d3b4f"
// }
// },
// dataZoom: {
// show: true,
// realtime: true,
// height: 20,
// start: 0,
// end: 100
// },
// tooltip:
// {
// trigger: 'axis',
// borderRadius: 4,
// formatter: function (params, ticket, callback) {
// var res = '时间: ' + params[0].name + '<br/>' + '数值: ' + params[0].value;
// return res;
// }
// },
// xAxis:
// [
// {
// type: 'category',
// boundaryGap: false,
// data: timeAry
// }
// ],
// yAxis:
// [
// {
// type: 'value',
// axisLabel:
// {
// formatter: '{value} ' + unit
// }
// }
// ],
// series:
// [
// {
// name: '实绩值',
// type: 'line',
// data: dataAry,
// clickable: false,
// markPoint:
// {
// data:
// [
// { type: 'max', name: '最大值', symbol: 'emptyCircle', symbolSize: 6, itemStyle: { normal: { color: '#FF0000', label: { position: 'top' } } } },
// { type: 'min', name: '最小值', symbol: 'emptyCircle', symbolSize: 6, itemStyle: { normal: { color: '#FF0000', label: { position: 'top' } } } }
// ]
// },
// markLine:
// {
// data:
// [
// { type: 'average', name: '平均值', itemStyle: { normal: { color: '#1E90FF' } } }
// ]
// },
// itemStyle: {
// normal: {
// color: echartsColorAry[0]
// }
// }
// }
// ]
// };
//为echarts对象加载数据
myChart.setOption(option6, true);
theECharts = myChart; //暂存,用于后面改变大小
}
);
// Ext.MessageBox.hide(); //隐藏进度条
}
});
}
}
var tb1 = Ext.create('Ext.toolbar.Toolbar', {
region: 'north',
border: '0 0 0 0',
height: 34
});
tb1.add(
{
xtype: 'datefield',
id: 'theDate',
editable: false,
labelWidth: 65,
labelAlign: 'right',
fieldLabel: '日期',
width: 180,
format: 'Y-m-d',
listeners: {
render: function (ee) {
ee.setValue(Ext.Date.parse(Ext.Date.format(new Date(), 'Y-m') + "-01", 'Y-m-d'));
}
}
},
{
xtype: 'checkbox',
id: 'isWholeMonth',
hideLabels: true,
boxLabel: '全月',
checked: false,
listeners: {
change: function () {
var record = tree.getSelectionModel().getLastSelected(); //获取选中行
if (record == null) {
Ext.getCmp("isWholeMonth").setValue(false);
WarningMsg('请在设备列表中选择设备!');
return;
}
btnOKClick();
}
}
},
'->',
{
xtype: 'splitbutton',
text: '查询',
width: 70,
handler: function () {
btnOKClick();
},
menu: [
{
icon: '../Public/Images/excel.png',
text: '导出到Excel',
handler: function () {
var excelName = "设备生产能源记录-" + Ext.Date.format(new Date(), "Ymd");
var tootSelected = tree.getSelectionModel().getLastSelected().data["parentId"];
if (tootSelected == "root") {
ExportToExcel(grid1, excelName);
}
else {
ExportToExcel(grid2, excelName);
}
}
}
]
},
' ',
' '
);
function Panel1Show() {
var items = Ext.getCmp('changepanel').items;
console.info(items.keys[0]);
var changepanel = Ext.getCmp('changepanel');
console.info(changepanel);
Ext.getCmp('changepanel').remove(items.keys[0], false);
//改动在此
var panel1 = Ext.create('Ext.panel.Panel', {
itemId: 'panel1',
border: false,
items: grid1,
frame: true
});
//改动结束
Ext.getCmp('changepanel').add(panel1);
}
function Panel2Show() {
var items = Ext.getCmp('changepanel').items;
console.info(items.keys[0]);
var changepanel = Ext.getCmp('changepanel');
console.info(changepanel);
Ext.getCmp('changepanel').remove(items.keys[0], false);
//改动在此
var panel2 = Ext.create('Ext.panel.Panel', {
itemId: 'panel2',
items: grid2,
border: false,
frame: true
});
//改动结束
Ext.getCmp('changepanel').add(panel2);
}
var theECharts = null;
var panel2 = new Ext.Panel({
itemId: 'panel2',
border: false,
items: grid2,
title: 'panel2',
frame: true
});
var panel1 = new Ext.Panel({
itemId: 'panel1',
items: grid1,
border: false,
frame: true
});
var gridStore1 = Ext.create('Ext.data.Store', {
proxy: {
type: "ajax",
actionMethods: { read: "POST" },
url: "EquipmentEnergyInfo.aspx?method=GetEquipmentEnergyTableRoot",
reader: { type: "json" }
},
fields: ['deviceName', 'productnum', 'theEveryEle', 'theEleTable', 'theAvgEle', 'theProductEle', 'theProductEleP', 'theNProductEle', 'theNProductEleP', 'theAutoEle', 'theAutoEleP', 'theChangeModelEle', 'theChangeModelEleP']
});
var grid1 = Ext.create('Ext.grid.Panel', {
forceFit: true,
columnLines: true,
scroll: 'vertical',
border: 0,
store: gridStore1,
columns: [
new Ext.grid.RowNumberer(),
{
text: '设备名称',
width: 25,
dataIndex: 'deviceName',
align: 'left',
},
{
text: '产量(件)',
align: 'center',
width: 20,
dataIndex: 'productnum',
},
{
text: '每件单耗(kwh)',
width: 20,
align: 'center',
dataIndex: 'theEveryEle'
},
{
text: '总用电量',
width: 25,
align: 'center',
dataIndex: 'theEleTable'
},
{
text: '小时平均耗能',
align: 'center',
width: 20,
dataIndex: 'theAvgEle'
},
{
text: '生产耗能',
//align: 'center',
columns: [
{
text: 'kwh',
width: 80,
align: 'center',
dataIndex: 'theProductEle',
//renderer: setColor
},
{
text: '%',
width: 80,
align: 'center',
dataIndex: 'theProductEleP',
//renderer: setColor
}
]
},
{
text: '非生产耗能',
//align: 'center',
columns: [
{
text: 'kwh',
width: 80,
align: 'center',
dataIndex: 'theNProductEle',
//renderer: setColor
},
{
text: '%',
width: 80,
align: 'center',
dataIndex: 'theNProductEleP',
// renderer: setColor
}
]
},
{
text: '自动状态耗能',
//align: 'center',
columns: [
{
text: 'kwh',
width: 80,
align: 'center',
dataIndex: 'theAutoEle',
//renderer: setBold
},
{
text: '%',
width: 80,
align: 'center',
dataIndex: 'theAutoEleP',
//renderer: setBold
}
]
},
{
text: '换模状态耗能',
//align: 'center',
columns: [
{
text: 'kwh',
width: 80,
align: 'center',
dataIndex: 'theChangeModelEle',
//renderer: setBold
},
{
text: '%',
width: 80,
align: 'center',
dataIndex: 'theChangeModelEleP',
//renderer: setBold
}
]
}
]
});
//叶节点数据源
var gridStore2 = Ext.create('Ext.data.Store', {
proxy: {
type: "ajax",
actionMethods: { read: "POST" },
url: "EquipmentEnergyInfo.aspx?method=GetEquipmentEnergyTable",
reader: { type: "json" }
},
fields: ['deviceName', 'productName', 'theQAD', 'theStartTime', 'theEndTime', 'productnum', 'theEle', 'theEveryEle']
});
var grid2 = Ext.create('Ext.grid.Panel', {
forceFit: true,
columnLines: true,
scroll: 'vertical',
border: 1,
store: gridStore2,
columns: [
new Ext.grid.RowNumberer(),
{
text: '设备名称',
width: 100,
dataIndex: 'deviceName',
align: 'left',
//renderer: setBold
},
{
text: '产品名称',
align: 'center',
width: 100,
dataIndex: 'productName',
//renderer: showTip
},
{
text: 'QAD代码',
width: 80,
align: 'center',
dataIndex: 'theQAD'
},
{
text: '开始时间',
width: 80,
align: 'left',
dataIndex: 'theStartTime'
},
{
text: '结束时间',
align: 'left',
width: 80,
dataIndex: 'theEndTime'
},
{
text: '产量(件)',
width: 60,
align: 'center',
dataIndex: 'productnum',
//renderer: setColor
},
{
text: '总耗能(kw/h)',
width: 80,
align: 'center',
dataIndex: 'theEle',
//tooltip: '节超比例=(考核指标-实际值)/考核指标*100%',
//renderer: setColor
},
{
text: '每件耗能(kw/h)',
width: 100,
align: 'center',
dataIndex: 'theEveryEle',
}
]
});
//页面总布局
var viewport = Ext.create('Ext.container.Viewport', {
layout: 'border',
items: [
{
region: 'center',
border: 0,
bodyStyle: 'padding: 6px;',
layout: 'border',
items: [
{
region: 'west',
width: 250,
border: 0,
layout: 'fit',
split: true,
items: tree
},
{
region: 'center',
layout: 'border',
border: 0,
items: [
{
region: 'north',
title: '生产能源信息',
split: true,
items: tb1 //公共导航查询栏
},
{
region: 'center',
layout: 'border',
border: 0,
items: [
{
id: 'changepanel',
region: 'center',
layout: 'fit',
items: panel1 //默认界面
},
{
region: 'south',
id: 'chartPanel1',
layout: 'fit',
height: '40%',
split: true,
collapsible: true,
collapsed: false,
listeners: {
resize: function () {
if (theECharts != null)
theECharts.resize(); //改变大小
}
}
}
]
}
]
}
]
}
]
});
});
当然,树的数据源和便规定也可以分开进行,这个个以实现点击不同标签刷新树:
//树结构
var treeStore = new Ext.create('Ext.data.TreeStore', {
root: {
text: '请选择能源平衡名',
expanded: true
},
autoLoad: false
});
treeStore.setProxy({
type: 'ajax',
url: 'Energy.aspx?method=GetAllConfig',
extraParams: { balanceId: theRecord.data["id"] },
reader: {
type: 'json'
}
});
treeStore.load();
源代码下载:点此下载