表格使用ReactJs编写的树形表格。
表格功能:
以树形表格的格式显示数据;
每条数据的右击菜单根据这条数据中不同的属性标示,可控制对应的类型是否可以下钻;
数据对应的地域下钻之后,点击地域前面的小三角可进行本省份下的地市下钻。
reportTreeTable.js文件
/**
* Created by Administrator on 2016/12/12 0012.
*/
import React from 'react'
import './reportTreeTable.less'
require('../../node_modules/webpack-dev-server/client/web_modules/jquery/jquery-1.8.1');
var gIndex = -1;
export default class ReportTreeTable extends React.Component {
constructor(props) {
super(props);
this.state = {
thData: ["指标名称", "本月值", "日均环比增幅", "本年累计", "累计同比增幅"],
/*datalist: [
{title: "测试数据", pid: "-1", id: '1', "space": "2",region_drill:"0", user_drill:"0",channel_drill:"0",contract_drill:"0", values: ["", "", "", ""]}
],*/
datalist: [
{title: "测试数据", pid: "-1", id: '1', "space": "0",region_drill:"0", user_drill:"0",channel_drill:"0",contract_drill:"0", values: ["", "", "", ""]},
{title: "测试数据11", pid: "1", id: '2', "space": "0",region_drill:"0", user_drill:"0",channel_drill:"0",contract_drill:"0", values: ["", "", "", ""]},
{title: "测试数据12", pid: "1", id: '3', "space": "0",region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"1",values: ["", "-220", "", "100%"]},
{title: "测试数据22", pid: "2", id: '4', "space": "0",region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"0", values: ["20", "220", "20%", "100%"]},
{title: "测试数据21", pid: "2", id: '5', "space": "1",region_drill:"0", user_drill:"0",channel_drill:"0",contract_drill:"1", values: ["30", "220", "20%", "100%"]},
{title: "测试数据23", pid: "2", id: '6', "space": "2", region_drill:"0", user_drill:"1",channel_drill:"0",contract_drill:"0",values: ["40", "-220", "20%", "100%"]},
{title: "测试数据111", pid: "1", id: '7', "space": "1",region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"1", values: ["50", "220", "20%", "100%"]},
{title: "测试数据123", pid: "1", id: '8', "space": "2",region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"1", values: ["60", "220", "20%", "100%"]},
{title: "测试数据223", pid: "-1", id: '9', "space": "0",region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"1", values: ["", "", "", ""]},
{title: "测试数据321", pid: "9", id: '10', "space": "0", region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"1",values: ["20", "-220", "20%", "100%"]},
{title: "测试数据002", pid: "9", id: '11', "space": "0",region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"1", values: ["", "220", "", "100%"]},
{title: "测试数据234", pid: "11", id: '12', "space": "0",region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"1", values: ["20", "220", "20%", "100%"]},
{title: "测试数据43", pid: "11", id: '13', "space": "1", region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"1",values: ["30", "-220", "20%", "100%"]},
{title: "测试数据54", pid: "11", id: '14', "space": "2",region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"1", values: ["40", "220", "20%", "100%"]},
{title: "测试数据12345", pid: "9", id: '15', "space": "0",region_drill:"1", user_drill:"1",channel_drill:"1",contract_drill:"1", values: ["50", "220", "20%", "100%"]},
{title: "测试数据54321", pid: "9", id: '16', "space": "0",region_drill:"0", user_drill:"0",channel_drill:"0",contract_drill:"0", values: ["60", "220", "20%", "100%"]}
],
pid: "",
clickId: "",
area: this.props.area,
city: this.props.city,
date: this.props.date,
rightClickKpiCode:"",
client: '',
channel: '',
contract: this.props.contract
}
}
static defaultProps={
rightMenuItems:[
{itemName:"地域",itemId:"region"},
{itemName:"客户类型",itemId:"userType"},
{itemName:"渠道类型",itemId:"channelType"},
{itemName:"合约类型",itemId:"contractType"}
]
};
componentWillReceiveProps(nextProps){
//debugger;
if(nextProps&&nextProps.tabledata!=null&&nextProps.tabledata.datalist!=undefined&&nextProps.tabledata.datalist.length>0){
this.setState({datalist:nextProps.tabledata.datalist,thData:nextProps.tabledata.title});
}
}
/**
* 递归获取table的合并行数,即rowspan
* @param data
* @returns {number} rowspan的值
*/
getDepth(data) {
var depth = 0;
for (var i = 0; i < data.length; i++) {
var _data = data[i];
if (_data.title == undefined || _data.title == "") {
depth++;
}
else {
// _data.title有值,说明还有还有子table数据结构
var _depth = this.getDepth(_data.data);
depth += _depth;
}
}
return depth;
}
/**
* table后四td的style
* @param index
* @returns {string}
*/
setNormalTdStyle(index,_down_drill) {//_down_drill(为false时)标示数据是否是下钻的数据,若是下钻的数据则鼠标变为默认箭头样式
// debugger;
if(_down_drill!=undefined){
if(_down_drill==false){
return index % 2 == 0 ? "bg-white mouse-icon-default" : "bg-blue mouse-icon-default";
}
}else {
return index % 2 == 0 ? "bg-white mouse-icon-pointer" : "bg-blue mouse-icon-pointer";
}
// return index % 2 == 0 ? "bg-white" : "bg-blue"+" "+_down_drill==false?"mouse-icon-default":"mouse-icon-pointer";
}
handleLeftClick(kid, _down_drill) {
// debugger
if (_down_drill == undefined) {
// debugger
this.props.callbackParent(kid);
} else if (_down_drill != undefined && _down_drill == false) {
return;
}
}
handleRightMenuClick(event) {
// var moveId = event.target.id;
var moveId = event.id;
var pid = this.state.pid;
var clickId = this.state.clickId;
var kpi_code=this.state.rightClickKpiCode;
var area = this.props.tableParams.area;
var client = this.props.tableParams.user;
var channel = this.props.tableParams.channel;
var contract = this.props.tableParams.contract;
var date=this.props.tableParams.date;
var province_code=this.props.tableParams.pro;
var city_code=this.props.tableParams.city;
var _data = this.state.datalist;
var _index = 0;
var tableType = this.props.tableType;
for (var i = 0; i < _data.length; i++) {
if (_data[i].id == clickId) {
_index = i + 1;
}
}
var right_click_drill_url = "";
var _self = this;
switch (moveId) {
case 'region':
var _region_data = [
{title: "河北", pid: pid, id: '20', province: "1", "space":"1",values: ["5555", "55551", "225555", "222555555"]},
{title: "北京", pid: pid, id: '21', province: "1","space":"1", values: ["666", "55551", "225555", "222555555"]},
{title: "山西", pid: pid, id: '22', province: "1","space":"1", values: ["7777", "55551", "225555", "222555555"]},
{title: "山东", pid: pid, id: '23', province: "1","space":"1", values: ["888", "55551", "225555", "222555555"]},
];
for (var i = 0; i < _region_data.length; i++) {
// _region_data[i].id=20+i+"";
_region_data[i].pid = pid;
_region_data[i].deleteMark = clickId;//插入的数据加入clickId(所点击行的id)标示,删除插入的数据时用此标识删除。
_region_data[i].bid = clickId;
_region_data[i].down_drill = false;//插入的数据加入down_drill标示,标示插入的数据不能下钻,不出现右击菜单。
_data.splice(_index + i, 0, _region_data[i]);
}
_self.setState({datalist: _data});
break;
case 'userType':
var _user_type_data = [
{title: "公众", pid: pid, id: '24',"space":"1", values: ["89", "55551", "225555", "222555555"]},
{title: "集客", pid: pid, id: '25', "space":"1",values: ["56", "55551", "225555", "222555555"]},
];
for (var j = 0; j < _user_type_data.length; j++) {
_user_type_data[j].pid = pid;
_user_type_data[j].deleteMark = clickId;
_user_type_data[j].bid = clickId;
_user_type_data[j].down_drill = false;//插入的数据加入down_drill标示,标示插入的数据不能下钻,不出现右击菜单。
_data.splice(_index + j, 0, _user_type_data[j]);
}
_self.setState({datalist: _data});
break;
case 'channelType':
var _channel_type_data = [
{title: "营业渠道", pid: pid, id: '26',"space":"1", values: ["89", "55551", "225555", "222555555"]},
{title: "社会渠道", pid: pid, id: '27', "space":"1",values: ["56", "55551", "225555", "222555555"]},
];
for (var k = 0; k < _channel_type_data.length; k++) {
_channel_type_data[k].pid = pid;
_channel_type_data[k].deleteMark = clickId;
_channel_type_data[k].bid = clickId;
_channel_type_data[k].down_drill = false;//插入的数据加入down_drill标示,标示插入的数据不能下钻,不出现右击菜单。
_data.splice(_index + k, 0, _channel_type_data[k]);
}
_self.setState({datalist: _data});
break;
case 'contractType':
var _contract_type_data = [
{title: "存费送机", pid: pid, id: '28',"space":"1", values: ["89", "55551", "225555", "222555555"]},
{title: "存费送费", pid: pid, id: '29',"space":"1", values: ["56", "55551", "225555", "222555555"]},
];
for (var h = 0; h < _contract_type_data.length; h++) {
_contract_type_data[h].pid = pid;
_contract_type_data[h].deleteMark = clickId;
_contract_type_data[h].bid = clickId;
_contract_type_data[h].down_drill = false;//插入的数据加入down_drill标示,标示插入的数据不能下钻,不出现右击菜单。
_data.splice(_index + h, 0, _contract_type_data[h]);
}
_self.setState({datalist: _data});
break;
}
// event.preventDefault();
// event.stopPropagation();
var menu = document.getElementById('rightMenuBox');
menu.style.visibility = "hidden";
}
clearRightMenuTable(menuTable){
var tr_len=menuTable.children.length;
if(tr_len>0){
for(var i=tr_len-1;i>=0;i--){
var tr = menuTable.children[i];
tr.parentNode.removeChild(tr);
}
}
}
createRightMenuItems(self,menuTable,data){
var flag = [0, 0, 0, 0];
var city = this.props.tableParams.city;
var client = this.props.tableParams.user;
var channel = this.props.tableParams.channel;
var contract = this.props.tableParams.contract;
/*var city = -1;
var client = ["1"];
var channel = ["-1"];
var contract = ["-1"];*/
if (city != "-1") {
flag[0] = 1
}
if (client.length == 1) {
if (client[0] != "-1") {
flag[1] = 1
}
}
if (channel.length == 1) {
if (channel[0] != "-1") {
flag[2] = 1
}
}
if (contract.length == 1) {
if (contract[0] != "-1") {
flag[3] = 1
}
}
var _right_menu_items=this.props.rightMenuItems;
var _region_drill=data.region_drill,_user_drill=data.user_drill,_channel_drill=data.channel_drill,_contract_drill=data.contract_drill;
var _row;
var _cell;
for(var j = 0; j <_right_menu_items.length; j++) {
_row = document.createElement("tr");
menuTable.appendChild(_row);
_cell = document.createElement("td");
_cell.id = _right_menu_items[j].itemId;
_cell.innerText = _right_menu_items[j].itemName;
if(_region_drill=="1"&&_right_menu_items[j].itemId=="region"&&flag[0]=="0"){//当单个指标地域可以下钻时,筛选条件的地域没有具体到地市时右击菜单可下钻
_cell.className = "rightMenuTd";
_cell.onclick = function () {
self.handleRightMenuClick(this)
}; //为每个单元格增加单击事件
}
else if(_user_drill=="1"&&_right_menu_items[j].itemId=="userType"&&flag[1]=="0"){//当单个指标用户类型可以下钻时,筛选条件的用户类型为全部或者选择了两个以上时右击菜单可下钻
_cell.className = "rightMenuTd";
_cell.onclick = function () {
self.handleRightMenuClick(this)
}; //为每个单元格增加单击事件
}
else if(_channel_drill=="1"&&_right_menu_items[j].itemId=="channelType"&&flag[2]=="0"){//当单个指标渠道类型可以下钻时,筛选条件的渠道类型为全部或者选择了两个以上时右击菜单可下钻
_cell.className = "rightMenuTd";
_cell.onclick = function () {
self.handleRightMenuClick(this)
}; //为每个单元格增加单击事件
}
else if(_contract_drill=="1"&&_right_menu_items[j].itemId=="contractType"&&flag[3]=="0"){//当单个指标合约类型可以下钻时,筛选条件的合约类型为全部或者选择了两个以上时右击菜单可下钻
_cell.className = "rightMenuTd";
_cell.onclick = function () {
self.handleRightMenuClick(this)
}; //为每个单元格增加单击事件
}else {
_cell.className = "norightMenuTd";
}
_row.appendChild(_cell);
}
}
handleRightClick(pId, clickItemId, data, event) {
//debugger;
this.setState({pid: pId, clickId: clickItemId,rightClickKpiCode:data.kpiCode});
// this.setState({pid: pId, clickId: clickItemId});
var _down_drill = data.down_drill;
if (event.button == 2) {
var _data = this.state.datalist;
var _index = -1; // clickItemId在 datalist的索引
for (var i = _data.length - 1; i > 0; i--) {
if (_data[i].delete_city_mark != undefined) {
if (_data[i].delete_city_mark == clickItemId) {
_data.splice(i, 1); // 根据id删除地市
}
}
}
for (var j = _data.length - 1; j > 0; j--) {
if (_data[j].deleteMark != undefined) {
if (_data[j].deleteMark == clickItemId) {
_data.splice(j, 1); // 根据id删除(省,客户类型,渠道类型,合约类型)
}
}
}
if (_down_drill == undefined) {
var contextMenu = document.getElementById("rightMenuBox");
var menuTable=document.getElementById("rightMenuTable");
this.clearRightMenuTable(menuTable);//清除右击菜单表格的所有tr
let xOffset = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
let yOffset = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
this.createRightMenuItems(this,menuTable,data);//生成右击菜单表格的所有tr。
contextMenu.style.cssText =
'left: ' + (event.clientX + xOffset-30 ) + 'px;' +
'top: ' + (event.clientY + yOffset-45) + 'px;' +
'visibility: visible;';
} else if (_down_drill != undefined && _down_drill == false) {
return;
}
event.preventDefault();
event.stopPropagation();
var tableId = this.props.tableId;
var reportTreeTable = document.getElementById(tableId);
reportTreeTable.oncontextmenu = function () {
return false;
}
} else if (event.button == 0) {
this.handleLeftClick(data.kpiCode, _down_drill);
}
}
/**
* 箭头是否显示
* @param isProvince -1:不显示,0: 显示并且不展开,1: 显示并且展开
* @returns {string} 箭头style
*/
setIconStyle(isProvince) {
var arrowStyle = "rtt-icon rtt-icon";
if (isProvince == -1) {
arrowStyle += "-none";
} else if (isProvince == 0) {
arrowStyle += "-def"
} else if (isProvince == 1) {
arrowStyle += "-changed";
} else {
arrowStyle += "-none";
}
return arrowStyle;
}
handleProvinceClick(pId, clickItemId, bid, event) {//clickItemId当前点击的省的id
var self = this;
var tar = event.target;
var className = tar.className;
if (className.indexOf("rtt-icon") != -1) {
if (className.indexOf("rtt-icon-changed") != -1) {
tar.className = "rtt-icon rtt-icon-def";
var _data_ = this.state.datalist;
var _index = -1; // clickItemId在 datalist的索引
for (var i = ( _data_.length - 1); i > 0; i--) {
if (_data_[i].id == clickItemId && _data_[i].bid == bid) {
_index = i; // 当前点击项clickItemId的在datalist的index
}
if (_data_[i].city != undefined) {
if (_data_[i].city == clickItemId && _data_[i].bid == bid) {
_data_.splice(i, 1); // 根据id删除
}
}
}
var _child_data = null;
if (_index != -1) {
_child_data = _data_[_index]; // 根据_index拿到当前clickItemId的数据项,把箭头状态改为false
_child_data.arrowSelected = false;
}
this.setState({datalist: _data_});
} else {
tar.className = "rtt-icon rtt-icon-changed";
var kpi_code=this.state.rightClickKpiCode;
var area = this.props.tableParams.area;
var client = this.props.tableParams.user;
var channel = this.props.tableParams.channel;
var contract = this.props.tableParams.contract;
var date=this.props.tableParams.date;
var province_code=this.props.tableParams.pro;
var city_code=this.props.tableParams.city;
var body="area="+area+"&prov="+province_code+"&city="+city_code+"&date="+date+"&client="+client+"&channel="+channel+"&contract="+contract+"&kid="+kpi_code;
this.setState({pid: pId, clickId: clickItemId}, function () {
// debugger;
var pid = this.state.pid;
var clickId = this.state.clickId;
var _data = this.state.datalist;
var deleteCityMark = '';
var _index = 0; // 当前点击项,要开始插入数据的位置
for (var i = 0; i < _data.length; i++) {
if (_data[i].id == clickId && _data[i].bid == bid) {
_index = i + 1;
deleteCityMark = _data[i].deleteMark;//插入省时点击的那一行指标名的id,(此标识用来标示地市所在指标名称)
}
}
var _child_data = _data[_index - 1]; // 当前点击的数据项 (_index-1)当前点击项在datalist的索引
_child_data.arrowSelected = true; // 将当前箭头状态改为展开
// debugger;
var tableType = this.props.tableType;
var city_url = "";
var _region_data_ = [
{
title: "石家庄",
// city: clickId,//clickId是点击的省的id,标示该城市属于哪个省
pid: pid,
id: '40',
"space":"2",
values: ["5555", "55551", "225555", "222555555"]
},
{
title: "邯郸",
// city: clickId,
pid: pid,
id: '41',
"space":"2",
values: ["666", "55551", "225555", "222555555"]
},
{
title: "保定",
// city: clickId,
pid: pid,
id: '42',"space":"2",
values: ["7777", "55551", "225555", "222555555"]
},
{
title: "承德",
// city: clickId,
pid: pid,
id: '43',"space":"2",
values: ["888", "55551", "225555", "222555555"]
},
];
for (var i = 0; i < _region_data_.length; i++) {
_region_data_[i].pid = pid;
_region_data_[i].bid = bid;
_region_data_[i].city = clickId; //clickId是点击的省的id,标示该城市属于哪个省
_region_data_[i].delete_city_mark = deleteCityMark;//插入省时点击的那一行指标名的id,(此标识用来标示地市所在指标名称)
_region_data_[i].down_drill = false;//插入的数据加入down_drill标示,标示插入的数据不能下钻,不出现右击菜单。
_data.splice(_index + i, 0, _region_data_[i]);
}
self.setState({datalist: _data});
});
}
}
}
/**
* 生成table需要的tr,td结构
* @param table 数组用来存放生成的tr数据
* @param title 合并行td显示的数据
* @param data 生成table的数据
* @param level 控制嵌套table结构的深度 目前只有2级 level = {1|2}
* @param ptitle 父合并行td显示的数据,当嵌套talbe在首位的时候需要
* @param pdepth 父合并行的合并行数
*/
getTableNode(table, title, data, level, ptitle, pdepth) {
var _normal_td_width=0,_rowspan_td_width=0,_colspan_td_width=0,kpi_name_td_width=0;
switch (window.screen.width){
case 1366:
_normal_td_width=100;
_rowspan_td_width=80;
_colspan_td_width=330;
kpi_name_td_width=240;
break;
case 1920:
_normal_td_width=180;
_rowspan_td_width=120;
_colspan_td_width=430;
kpi_name_td_width=310;
break;
}
if(data.length>0){
data.map((d, index)=> {
var _data = d;
var obj = null;
var isProvince = -1; // -1 不展示 0 展示不展开 1 展示并展开
if (_data.province != undefined) {
if (_data.province == '1') {
// datalist数据项默认没有arrowSelected 只有在调用
// handleProvinceClick 方法{
// var _child_data = _data[_index - 1];
// _child_data.arrowSelected = true;
//} 才会生成
if (_data.arrowSelected == undefined || _data.arrowSelected == false) {
isProvince = 0;
} else {
isProvince = 1;
}
}
}
if (_data.values != undefined && _data.values.length > 0) {
var pId = _data.pid;
var clickItemId = _data.id;
var bid = _data.bid;
gIndex++;
if(_data.values.length>0){
var _down_drill=_data.down_drill;
var normalTd = _data.values.map((d, index)=> {
if (index == 1) {
if (d.length === 1) {
return <td width={_normal_td_width}
style={{color: 'black'}}
className={this.setNormalTdStyle(gIndex, _down_drill)}
onMouseDown={this.handleRightClick.bind(this, pId, clickItemId, _data)}>{d}</td>
} else {
if (d.toString().substr(0, 1) == '-') {
return <td width={_normal_td_width}
style={{color: 'red'}}
className={this.setNormalTdStyle(gIndex, _down_drill)}
onMouseDown={this.handleRightClick.bind(this, pId, clickItemId, _data)}>{d}</td>
} else {
return <td width={_normal_td_width}
style={{color: 'green'}}
className={this.setNormalTdStyle(gIndex, _down_drill)}
onMouseDown={this.handleRightClick.bind(this, pId, clickItemId, _data)}>{d}</td>
}
}
} else {
return <td width={_normal_td_width}
className={this.setNormalTdStyle(gIndex,_down_drill)}
onMouseDown={this.handleRightClick.bind(this, pId, clickItemId, _data)}>{d}</td>
}
});
}
}
if (index == 0) { // 合并行tr走此逻辑
//data是处理后的数据,以此来计算这条数据中包括几行,然后第一列合并多少行
var depth = this.getDepth(data);
//是否有嵌套table是否在首位
//_data.title == undefined || _data.title == "" 表示无嵌套table
// 否则有嵌套table
if (_data.title == undefined || _data.title == "") {
if (ptitle != undefined && ptitle != "") { // 当嵌套table在首位时走此逻辑
obj = <tr>
<td rowSpan={pdepth} width={_rowspan_td_width} className="kpi-bg">{ptitle}</td>
<td rowSpan={depth} width={_rowspan_td_width} className="kpi-bg-two">{title}</td>
<td width={level > 1 ? kpi_name_td_width : _colspan_td_width} colSpan={level == 1 ? 2 : 1}
className="kpi-bg">
<img src="../src/reportTable/images/hide.png"
className={this.setIconStyle(isProvince)}
onClick={this.handleProvinceClick.bind(this, pId, clickItemId, bid)}/>
{_data.kpi_name}
</td>
{normalTd}
</tr>
} else { // 无嵌套table,或者嵌套table不在首位
obj = <tr>
<td rowSpan={depth} width={_rowspan_td_width} className="kpi-bg-two">{title}</td>
<td width={level > 1 ? kpi_name_td_width : _colspan_td_width} colSpan={level == 1 ? 2 : 1}
className="kpi-bg" style={{'paddingLeft':5}}>
<img src="../src/reportTable/images/hide.png"
className={this.setIconStyle(isProvince)}
onClick={this.handleProvinceClick.bind(this, pId, clickItemId, bid)}/>
{_data.kpi_name}
</td>
{normalTd}
</tr>
}
} else { //有嵌套table走此逻辑,并且当嵌套table在首位时走此逻辑
this.getTableNode(table, _data.title, _data.data, ++level, title, depth);
--level;
}
} else if (_data.title != undefined && _data.title != "") { //有嵌套table走此逻辑,嵌套table在不在首位时走此逻辑
this.getTableNode(table, _data.title, _data.data, ++level, "", 0);
--level;
} else { // 不需要合并行的tr
//根据space设置空格
var space=_data.space*10+5+'px'
obj = <tr>
{/* <td width={level > 1 ? 240 : 330} colSpan={level == 1 ? 2 : 1} // 根据level判断是否要合并列
className={classname}>*/}
<td width={level > 1 ? kpi_name_td_width : _colspan_td_width} colSpan={level == 1 ? 2 : 1} // 根据level判断是否要合并列
className='kpi-bg' style={{'paddingLeft':space}}>
<img src="../src/reportTable/images/hide.png"
className={this.setIconStyle(isProvince)}
onClick={this.handleProvinceClick.bind(this, pId, clickItemId, bid)}/>
{_data.kpi_name}
</td>
{normalTd}
</tr>
}
if (obj) {
table.push(obj);
}
})
}
}
/**
* 生成table
* @param table
* @param data
*/
getTable(table, data) {
var _normal_td_width=0;
switch (window.screen.width){
case 1366:
_normal_td_width=100;
break;
case 1920:
_normal_td_width=180;
break;
}
var level = 1;
if(data.length>0){
data.map((d, index)=> {
var _data = d.data;
var title = d.title;
if(_data!=undefined){
this.getTableNode(table, title, _data, level, "", 0);
}
else {
gIndex++;
var isProvince = -1; // -1 不展示 0 展示不展开 1 展示并展开
if (d.province != undefined) {
if (d.province == '1') {
// datalist数据项默认没有arrowSelected 只有在调用
// clickProvince 方法{
// var _child_data = _data[_index - 1];
// _child_data.arrowSelected = true;
//} 才会生成
if (d.arrowSelected == undefined || d.arrowSelected == false) {
isProvince = 0;
} else {
isProvince = 1;
}
}
}
if(d.values.length>0){
var _space=d.space*10;
var _down_drill=d.down_drill;
var normalTd1 = d.values.map((data, index)=> {
return <td width={_normal_td_width}
className={this.setNormalTdStyle(gIndex,_down_drill)}
onMouseDown={this.handleRightClick.bind(this, d.pid, d.id,d)}>{data}</td>
});
}
var trObj=<tr>
<td className="kpi-bg" colSpan="3" style={{paddingLeft:_space}}>
{/*<td className="kpi-bg" colSpan="3">*/}
<img src="../src/reportTable/images/hide.png"
className={this.setIconStyle(isProvince)}
onClick={this.handleProvinceClick.bind(this, d.pid, d.id,d.bid)}/>{d.kpi_name}</td>
{normalTd1}
</tr>;
table.push(trObj);
}
})
}
}
setThBg(index) {
return index == 0 ? 'kpi-bg' : '';
}
componentDidMount(){
// debugger
$("#report-table").mouseleave(function(){
var menu = document.getElementById('rightMenuBox');
menu.style.visibility = "hidden";
});
}
/**
* 数据数据
* @param pid 父id
* @param data
* @returns {Array}
*/
build(pid, data) {
var parentList = [];
for (var i = 0; i < data.length; i++) {
var _data = data[i];
if (_data.pid == pid) {
var childList = this.build(_data.id, data);
if (childList.length == 0) { // childList.length==0 说明_data没有子项
parentList.push({
kpi_name: _data.title,
kpiCode:_data.kpiCode,
pid: _data.pid,
id: _data.id,
bid: _data.bid,
down_drill: _data.down_drill,
delete_city_mark: _data.delete_city_mark,
deleteMark: _data.deleteMark,
province: _data.province,
region_drill:_data.region_drill,
user_drill:_data.user_drill,
channel_drill:_data.channel_drill,
contract_drill:_data.contract_drill,
arrowSelected: _data.arrowSelected,// 箭头是否展示 true :展开 false:收起
values: _data.values,
space: _data.space,
});
} else {
// _data有子项 将_data数据和childList压入数组
parentList.push({title: _data.title, pid: _data.pid, id: _data.id, data: childList});
}
}
}
return parentList;
}
componentDidMount(){
$("#report-table").mouseleave(function(){
var menu = document.getElementById('rightMenuBox');
menu.style.visibility = "hidden";
});
}
render() {
var tree = [];
var thData = this.state.thData;
// var data = this.state.data; //第一次定义的数据格式
var dataList = this.state.datalist;
var list = this.build(-1, dataList);
var th = thData.map((d, index)=> {
return <th className="tab-th" colSpan={index == 0 ? 3 : 1}>{d}</th>
});
gIndex = -1;
this.getTable(tree, list);
var tableId = this.props.tableId;
var treeTableStyle=null;
switch (window.screen.width){
case 1366:
treeTableStyle={
borderSpacing: '0px',
borderCollapse: 'collapse',
fontFamily: 'Microsoft YaHei',
fontWeight: '400',
fontStyle: 'normal',
fontSize: '14px',
marginBottom:'20px'
};
break;
case 1920:
treeTableStyle={
borderSpacing: '0px',
borderCollapse: 'collapse',
fontFamily: 'Microsoft YaHei',
fontWeight: '400',
fontStyle: 'normal',
fontSize: '18px',
marginBottom:'20px'
};
break;
}
return (
<div id="report-table">
<table style={treeTableStyle} id={tableId}>
<thead>
<tr>{th}</tr>
</thead>
<tbody>
{tree}
</tbody>
</table>
<div id="rightMenuBox">
<table id="rightMenuTable">
</table>
</div>
</div>
);
}
}
reportTreeTable.less文件
.bg-blue{
//cursor: pointer;
background-color: #EDF1F6;
text-align: center;
}
.tab-th{
height: 40px;
color: #333333;
text-align: center;
}
.bg-white{
//cursor: pointer;
background-color: #ffffff;
text-align: center;
}
.mouse-icon-pointer{
cursor: pointer;
}
.mouse-icon-default{
cursor: default;
//cursor: not-allowed;
}
.kpi-bg{
color:#FFF7F6;
height: 48px;
border: solid 1px #AEBECF;
background-color: #B7CDE5;
}
.kpi-bg-two{
color:#FFF7F6;
height: 48px;
padding-left: 10px;
padding-right: 10px;
border: solid 1px #AEBECF;
background-color: #B7CDE5;
}
.kpi-bg-onespace {
color:#FFF7F6;
border: solid 1px #AEBECF;
height: 48px;
padding-left: 10px;
background-color: #B7CDE5;
}
.kpi-bg-twospace {
color:#FFF7F6;
border: solid 1px #AEBECF;
height: 48px;
padding-left: 20px;
background-color: #B7CDE5;
}
.kpi-bg-threespace {
color:#FFF7F6;
border: solid 1px #AEBECF;
height: 48px;
padding-left: 30px;
background-color: #B7CDE5;
}
.kpi-bg-fourspace {
color:#FFF7F6;
border: solid 1px #AEBECF;
height: 48px;
padding-left: 40px;
background-color: #B7CDE5;
}
@media only screen and (min-width:961px) and (max-width: 1366px){
.rightMenuTd {
cursor: default;
border: solid 1px #cfcfcf;
font-family: 'MicrosoftYaHei', 'Microsoft YaHei';
font-size: 14px;
width: 100px;
height: 38px;
text-align: center;
background-color: #F0F0F0;
}
.norightMenuTd{
cursor: no-drop;
border: solid 1px #cfcfcf;
font-family: 'MicrosoftYaHei', 'Microsoft YaHei';
font-size: 14px;
width: 100px;
height: 38px;
text-align: center;
color: #9999FF;
background-color: #F0F0F0;
}
}
//右击菜单在1080p样式
@media only screen and (min-width:1367px) and (max-width: 1920px){
.rightMenuTd {
cursor: default;
border: solid 1px #cfcfcf;
font-family: 'MicrosoftYaHei', 'Microsoft YaHei';
font-size: 18px;
width: 130px;
height: 45px;
text-align: center;
background-color: #F0F0F0;
}
.norightMenuTd{
cursor: no-drop;
border: solid 1px #cfcfcf;
font-family: 'MicrosoftYaHei', 'Microsoft YaHei';
font-size: 18px;
width: 130px;
height: 45px;
text-align: center;
color: #9999FF;
background-color: #F0F0F0;
}
}
.rightMenuTd:hover{
background-color:#4A9AFB;
//cursor: not-allowed;
}
#rightMenuBox {
position: absolute;
visibility: hidden;
z-index: 1000;
}
.rtt-icon{
width: 10px;
height: 10px;
cursor: pointer;
}
.rtt-icon-none{
width: 15px;
height: 15px;
display: none;
}
.rtt-icon-def{
-webkit-transform: rotateZ(0deg);
}
.rtt-icon-changed{
-webkit-transform: rotateZ(90deg);
transform:rotateZ(90deg);
-ms-transform:rotateZ(90deg); /* IE 9 */
-moz-transform:rotateZ(90deg); /* Firefox */
-webkit-transform:rotateZ(90deg); /* Safari 和 Chrome */
-o-transform:rotateZ(90deg); /* Opera */
}
表格截图:
初始显示:
任意数据右击:
点击右击菜单插入数据:
点击省份前面的小三角插入数据: