Browse Source

细节调整:
①chart图添加额外的配置,调整自适应逻辑。
②面板标题高度正确获取。

zhuth 8 years ago
parent
commit
68befb28bd

+ 2 - 5
kanban-client/app/component/Table.dev.jsx

@@ -165,19 +165,17 @@ class TableModel extends React.Component {
 		}
 
 		this.dataArr = result;
-		console.log(this.dataArr);
 		this.dataIndex = 0;
 	}
 
 	setRefresh() {
 		this.changeData();
 		if (this.dataArr.length > 1) {
-			console.log('setRefresh');
 			this.timing({
 				intervalFunction: function () {
 					this.changeData();
 				}.bind(this),
-				intervalTime: this.newProps.refreshInterval * 1000 || this.rowCount * this.columns.length * 200
+				intervalTime: this.newProps.refreshInterval * 1000 || 5000
 			});
 		}
 	}
@@ -197,7 +195,6 @@ class TableModel extends React.Component {
 	clearInterval() {
 		for (let index in this.timerKeys) {
 			clearInterval(this.timerKeys[index]);
-			console.log('移除' + this.timerKeys[index]);
 			this.timerKeys.splice(index, 1);
 		}
 	}
@@ -248,7 +245,7 @@ class TableModel extends React.Component {
 	render() {
 		const { fontSize } = this.newProps;
 		return (
-			<div ref='body' style={{ height: '100%', overflow: 'hidden', padding: '0px' }}>
+			<div ref='body' style={{ height: '100%', overflow: 'hidden', fontSize: fontSize, padding: '0px' }}>
 				<Table
 					prefixCls={this.newProps.prefixCls || 'rc-table'}
 					className={this.newProps.className}

+ 2 - 1
kanban-client/app/component/Table.jsx

@@ -98,6 +98,7 @@ class TableModel extends React.Component {
 		thead.getElementsByTagName('th')[0].style.height = `${trHeight}px` ;
 		let count = this.state.data.length;
 		if (count == 0) { return; }
+		// let trs = node.getElementsByClassName('fade-enter').length == 0 ? (node.getElementsByClassName('rc-table-row')) : node.getElementsByClassName('fade-enter');
 		let trs = node.getElementsByClassName('rc-table-row');
 		for (let i = 0; i < trs.length; i++) {
 			trs[i].style.fontSize = trFontSize;
@@ -223,7 +224,7 @@ class TableModel extends React.Component {
 	}
 
 	shouldComponentUpdate(nextProps, nextState) {
-			return true;
+		return true;
 	}
 	getBodyWrapper(body) {
 		return (

+ 282 - 81
kanban-client/app/component/converter.dev.js

@@ -16,6 +16,8 @@ function converter(data) {
             return lineConfig(v);
         } else if (type == 'pie') {
             return pieConfig(v);
+        } else if(type == 'mixchart') {
+            return mixChartConfig(v);
         } else {
 
         }
@@ -112,18 +114,28 @@ function tableConfig(model) {
 
 function barConfig(model) {
     let { type, config, layout } = model;
-    let { fontSize, title, subtitle, xtitle, xtype, xfields, ytitle, ytype, yfields, series, legendconfig, areaconfig, color } = config;
+    let { fontSize, title, subtitle, xtitle, xtype, xfields, xconfig, ytitle, ytype, yfields, series, yconfig,
+        legendconfig, areaconfig, barconfig, color } = config;
 
+    xconfig = parseObjectStr(xconfig);
+    yconfig = parseObjectStr(yconfig);
     legendconfig = parseObjectStr(legendconfig);
     areaconfig = parseObjectStr(areaconfig);
+    barconfig = parseObjectStr(barconfig);
+    
     color = eval(color);
     series = series ? ((series instanceof Array) ? series : [series]) : [];
     let xf = (xfields instanceof Array) ? xfields : (xfields.replace(['['], '').replace([']'], '').split(',')),
-        legendTop = legendconfig.top ? (legendconfig.top)+'%' : null,
-        itemGap = legendconfig.itemGap ? Number(legendconfig.itemGap) : layout.w / 10,
-        itemWidth = legendconfig.itemWidth ? Number(legendconfig.itemWidth) : 25,
-        itemHeight = legendconfig.itemHeight ? Number(legendconfig.itemHeight) : 14;
-    
+        areaLeft = Number(areaconfig.left)>=0 ? areaconfig.left+'%' : '5%',
+        areaRight = Number(areaconfig.right)>=0 ? areaconfig.right+'%' : '5%',
+        areaTop = Number(areaconfig.top)>=0 ? areaconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '35%' : '28%'),
+        areaBottom = Number(areaconfig.bottom)>=0 ? areaconfig.bottom+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '16%'),
+        
+        legendLeft = Number(legendconfig.left)>=0 ? legendconfig.left+'%' : null,
+        legendTop = Number(legendconfig.top)>=0 ? legendconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '18%'),
+        itemGap = Number(legendconfig.itemGap)>=0 ? Number(legendconfig.itemGap) : layout.w / 10,
+        itemWidth = Number(legendconfig.itemWidth)>=0 ? Number(legendconfig.itemWidth) : 25,
+        itemHeight = Number(legendconfig.itemHeight)>=0 ? Number(legendconfig.itemHeight) : 14;
     let o = {
         type: 'charts',
         config: {
@@ -137,17 +149,14 @@ function barConfig(model) {
                 },
                 grid: {
                     containLabel: true,
-                    top_: areaconfig.top ? areaconfig.top+'%' : null,
-                    bottom_: areaconfig.bottom ? areaconfig.bottom+'%' : null,
-                    left_: areaconfig.left ? areaconfig.left+'%' : null,
-                    right_: areaconfig.right ? areaconfig.right+'%' : null,
-                    top: layout.h * getScreenSize().height / 100 < 310 ? '35%' : '28%',
-                    bottom: layout.h * getScreenSize().height / 100 < 310 ? '20%' : '16%',
+                    left: areaLeft,
+                    right: areaRight,
+                    top: areaTop,
+                    bottom: areaBottom
                 },
                 legend: {
                     show: !legendconfig.hide,
-                    top_: legendTop,
-                    top: (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '18%'),
+                    top: legendTop,
                     padding: 0,
                     orient: legendconfig.orient || 'horizontal',
                     itemGap: itemGap,
@@ -164,14 +173,15 @@ function barConfig(model) {
                     type: xtype,
                     data: xf,
                     name: xtitle,
-                    nameGap: 5,
-                    nameRotate: 270,
-                    nameLocation: 'end',
+                    position: xconfig.position || 'bottom',
+                    nameGap: xconfig.nameGap || 5,
+                    nameRotate: xconfig.nameRotate || 0,
+                    nameLocation: xconfig.nameLocation || 'end',
                     nameTextStyle: {
                         fontSize: getFontSize() * .7
                     },
                     axisLabel: {
-                        rotate: getScreenSize().width * layout.w / xf.length / 100 < 80 ? 45 : 0,
+                        rotate: Number(xconfig.labelRotate)>=0 ? Number(xconfig.labelRotate) : (getScreenSize().width * layout.w / xf.length / 100 < 80 ? 45 : 0),
                         interval: 0,
                         textStyle: {
                             fontSize: getFontSize() * .7
@@ -180,7 +190,10 @@ function barConfig(model) {
                 }],
                 yAxis: [{
                     name: ytitle,
-                    nameRotate: .1,
+                    nameRotate: yconfig.nameRotate || 0,
+                    position: yconfig.position || 'left',
+                    nameLocation: yconfig.nameLocation || 'end',
+                    nameGap: yconfig.nameGap || 15,
                     type: ytype == 'numeric' ? 'value' : ytype,
                     nameTextStyle: {
                         fontSize: getFontSize() * .7
@@ -191,7 +204,7 @@ function barConfig(model) {
                         }
                     }
                 }],
-                series: getBarSeries(fontSize, layout, series, areaconfig)
+                series: getBarSeries(fontSize, layout, series, barconfig)
             }
         },
         layout: getLayout(layout)
@@ -199,27 +212,33 @@ function barConfig(model) {
     if(color && color.length > 0) {
         o.config.option.color = color;
     }
-    if(Number(legendconfig.left) >= 0) {
-        o.config.option.legend.left = Number(legendconfig.left)+'%';
-    }else {
-        o.config.option.legend.right = '5%';
-    }
+    legendLeft ? (o.config.option.legend.left = legendLeft) : (o.config.option.legend.right = '5%');
     return o;
 }
 
 function lineConfig(model) {
     let { type, config, layout } = model;
-    let { fontSize, title, subtitle, xtitle, xtype, xfields, ytitle, ytype, yfields, series, legendconfig, areaconfig, color } = config;
+    let { fontSize, title, subtitle, xtitle, xtype, xfields, xconfig, ytitle, ytype, yfields, yconfig,
+        series, legendconfig, areaconfig, lineconfig, color } = config;
     
+    xconfig = parseObjectStr(xconfig);
+    yconfig = parseObjectStr(yconfig);
     legendconfig = parseObjectStr(legendconfig);
     areaconfig = parseObjectStr(areaconfig);
+    lineconfig = parseObjectStr(lineconfig);
     color = eval(color);
     series = series ? ((series instanceof Array) ? series : [series]) : [];
     let xf = (xfields instanceof Array) ? xfields : (xfields.replace(['['], '').replace([']'], '').split(',')),
-        legendTop = legendconfig.top ? (legendconfig.top)+'%' : null,
-        itemGap = legendconfig.itemGap ? Number(legendconfig.itemGap) : layout.w / 10,
-        itemWidth = legendconfig.itemWidth ? Number(legendconfig.itemWidth) : 25,
-        itemHeight = legendconfig.itemHeight ? Number(legendconfig.itemHeight) : 14;
+        areaLeft = Number(areaconfig.left)>=0 ? areaconfig.left+'%' : '5%',
+        areaRight = Number(areaconfig.right)>=0 ? areaconfig.right+'%' : '5%',
+        areaTop = Number(areaconfig.top)>=0 ? areaconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '35%' : '28%'),
+        areaBottom = Number(areaconfig.bottom)>=0 ? areaconfig.bottom+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '16%'),
+        
+        legendLeft = Number(legendconfig.left)>=0 ? legendconfig.left+'%' : null,
+        legendTop = Number(legendconfig.top)>=0 ? legendconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '18%'),
+        itemGap = Number(legendconfig.itemGap)>=0 ? Number(legendconfig.itemGap) : layout.w / 10,
+        itemWidth = Number(legendconfig.itemWidth)>=0 ? Number(legendconfig.itemWidth) : 25,
+        itemHeight = Number(legendconfig.itemHeight)>=0 ? Number(legendconfig.itemHeight) : 14;
 
     let o = {
         type: 'charts',
@@ -231,17 +250,14 @@ function lineConfig(model) {
                 },
                 grid: {
                     containLabel: true,
-                    top_: areaconfig.top ? areaconfig.top+'%' : null,
-                    bottom_: areaconfig.bottom ? areaconfig.bottom+'%' : null,
-                    left_: areaconfig.left ? areaconfig.left+'%' : null,
-                    right_: areaconfig.right ? areaconfig.right+'%' : null,
-                    top: layout.h * getScreenSize().height / 100 < 310 ? '35%' : '28%',
-                    bottom: layout.h * getScreenSize().height / 100 < 310 ? '20%' : '16%',
+                    left: areaLeft,
+                    right: areaRight,
+                    top: areaTop,
+                    bottom: areaBottom
                 },
                 legend: {
                     show: !legendconfig.hide,
-                    top_: legendTop,
-                    top: (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '18%'),
+                    top: legendTop,
                     padding: 0,
                     orient: legendconfig.orient || 'horizontal',
                     itemGap: itemGap,
@@ -258,14 +274,15 @@ function lineConfig(model) {
                     type: xtype,
                     data: xf,
                     name: xtitle,
-                    nameRotate: 270,
-                    nameLocation: 'end',
-                    nameGap: 5,
+                    position: xconfig.position || 'bottom',
+                    nameRotate: xconfig.nameRotate || 0,
+                    nameLocation: xconfig.nameLocation || 'end',
+                    nameGap: xconfig.nameGap || 15,
                     nameTextStyle: {
                         fontSize: fontSize || getFontSize() * .7
                     },
                     axisLabel: {
-                        rotate: getScreenSize().width * layout.w / xf.length / 100 < 80 ? 45 : 0,
+                        rotate: Number(xconfig.labelRotate)>=0 ? Number(xconfig.labelRotate) : (getScreenSize().width * layout.w / xf.length / 100 < 80 ? 45 : 0),
                         interval: 0,
                         textStyle: {
                             fontSize: fontSize || getFontSize() * .7
@@ -274,7 +291,10 @@ function lineConfig(model) {
                 }],
                 yAxis: [{
                     name: ytitle,
-                    nameRotate: .1,
+                    nameRotate: yconfig.nameRotate || 0,
+                    position: yconfig.position || 'left',
+                    nameLocation: yconfig.nameLocation || 'end',
+                    nameGap: yconfig.nameGap || 15,
                     type: ytype == 'numeric' ? 'value' : ytype,
                     nameTextStyle: {
                         fontSize: fontSize || getFontSize() * .7
@@ -285,7 +305,7 @@ function lineConfig(model) {
                         }
                     }
                 }],
-                series: getLineSeries(fontSize, series, areaconfig),
+                series: getLineSeries(fontSize, series, lineconfig),
                 dataZoom: series.length > 0 ? [
                     {
                         type: 'slider',
@@ -302,11 +322,127 @@ function lineConfig(model) {
     if(color && color.length > 0) {
         o.config.option.color = color;
     }
-    if(Number(legendconfig.left) >= 0) {
-        o.config.option.legend.left = Number(legendconfig.left)+'%';
-    }else {
-        o.config.option.legend.right = '5%';
-    }
+    legendLeft ? (o.config.option.legend.left = legendLeft) : (o.config.option.legend.right = '5%');
+    return o;
+}
+
+function mixChartConfig(model) {
+    let { type, config, layout } = model;
+    let { fontSize, title, subtitle, xtitle, xtype, xfields, xconfig, ybar, yline, series, legendconfig,
+        areaconfig, barconfig, lineconfig, barcolor, linecolor } = config;
+
+    xconfig = parseObjectStr(xconfig);
+    ybar = parseObjectStr(ybar);
+    ybar.config = parseObjectStr(ybar.config);
+    yline = parseObjectStr(yline);
+    yline.config = parseObjectStr(yline.config);
+    
+    legendconfig = parseObjectStr(legendconfig);
+    areaconfig = parseObjectStr(areaconfig);
+    barconfig = parseObjectStr(barconfig);
+    lineconfig = parseObjectStr(lineconfig);
+    barcolor = eval(barcolor);
+    linecolor = eval(linecolor);
+    series = series ? ((series instanceof Array) ? series : [series]) : [];
+
+    let xf = (xfields instanceof Array) ? xfields : (xfields.replace(['['], '').replace([']'], '').split(',')),
+        areaLeft = Number(areaconfig.left)>=0 ? areaconfig.left+'%' : '5%',
+        areaRight = Number(areaconfig.right)>=0 ? areaconfig.right+'%' : '5%',
+        areaTop = Number(areaconfig.top)>=0 ? areaconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '35%' : '28%'),
+        areaBottom = Number(areaconfig.bottom)>=0 ? areaconfig.bottom+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '16%'),
+        
+        legendLeft = Number(legendconfig.left)>=0 ? legendconfig.left+'%' : null,
+        legendTop = Number(legendconfig.top)>=0 ? legendconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '18%'),
+        itemGap = Number(legendconfig.itemGap)>=0 ? Number(legendconfig.itemGap) : layout.w / 10,
+        itemWidth = Number(legendconfig.itemWidth)>=0 ? Number(legendconfig.itemWidth) : 25,
+        itemHeight = Number(legendconfig.itemHeight)>=0 ? Number(legendconfig.itemHeight) : 14;
+    var o = {
+        type: 'charts',
+        config: {
+            option: {
+                title: getChartsTitle(fontSize, layout, title, subtitle),
+                tooltip: {
+                    trigger: 'axis'
+                },
+                legend: {
+                    show: !legendconfig.hide,
+                    top: legendTop,
+                    padding: 0,
+                    orient: legendconfig.orient || 'horizontal',
+                    itemGap: itemGap,
+                    itemWidth: itemWidth,
+                    itemHeight: itemHeight,
+                    textStyle: {
+                        fontSize: fontSize || getFontSize() * 0.7
+                    },
+                    data: series.map((v, i) => {
+                        return v.name
+                    })
+                },
+                grid: {
+                    containLabel: true,
+                    top: areaTop,
+                    bottom: areaBottom,
+                    left: areaLeft,
+                    right: areaRight
+                },
+                xAxis: [{
+                    type: xtype,
+                    data: xf,
+                    name: xtitle,
+                    position: xconfig.position || 'bottom',
+                    nameGap: xconfig.nameGap || 15,
+                    nameRotate: xconfig.nameRotate || 0,
+                    nameLocation: xconfig.nameLocation || 'end',
+                    nameTextStyle: {
+                        fontSize: getFontSize() * .7
+                    },
+                    axisLabel: {
+                        rotate: Number(xconfig.labelRotate)>=0 ? xconfig.labelRotate : (getScreenSize().width * layout.w / xf.length / 100 < 80 ? 45 : 0),
+                        interval: 0,
+                        textStyle: {
+                            fontSize: getFontSize() * .7
+                        }
+                    }
+                }],
+                yAxis: [{
+                    name: ybar.title,
+                    position: ybar.config ? (ybar.config.position || 'left') : 'left',
+                    nameRotate: ybar.config ? (ybar.config.nameRotate || 0) : 0,
+                    nameLocation: ybar.config ? (ybar.config.nameLocation || 'end') : 'end',
+                    nameGap: ybar.config ? (ybar.config.nameGap || 15) : 15,
+                    type: ybar.type == 'numeric' ? 'value' : ytype,
+                    nameTextStyle: {
+                        fontSize: getFontSize() * .7
+                    },
+                    axisLabel: {
+                        textStyle: {
+                            fontSize: getFontSize() * .7
+                        }
+                    }
+                },{
+                    name: yline.title,
+                    position: yline.config ? (yline.config.position || 'right') : 'right',
+                    nameRotate: yline.config ? (yline.config.nameRotate || 0) : 0,
+                    nameLocation: yline.config ? (yline.config.nameLocation || 'end') : 'end',
+                    nameGap: yline.config ? (yline.config.nameGap || 15) : 15,
+                    type: yline.type == 'numeric' ? 'value' : ytype,
+                    nameTextStyle: {
+                        fontSize: getFontSize() * .7
+                    },
+                    axisLabel: {
+                        textStyle: {
+                            fontSize: getFontSize() * .7
+                        }
+                    }
+                }],
+                series: getMixChartSeries(fontSize, layout, series, barconfig, lineconfig, barcolor, linecolor)
+            }
+        },
+        layout: getLayout(layout)
+    };
+    legendLeft ? (o.config.option.legend.left = legendLeft) : (o.config.option.legend.right = '5%');
+
     return o;
 }
 
@@ -371,34 +507,26 @@ function getChartsTitle(fontSize, layout, title, subtitle) {
     return title;
 }
 
-function getBarSeries(fontSize, layout, series, areaconfig) {
+function getBarSeries(fontSize, layout, series, barconfig) {
     let s = [];
     const model = {
         type: 'bar',
         label: {
             normal: {
-                show: !areaconfig.hideLabel,
-                position: areaconfig.labelPosition || 'top',
-                distance: areaconfig.labelDistance ? Number(areaconfig.labelDistance) : 5,
-                formatter: areaconfig.labelFormatter || '{c}',
+                show: !barconfig.hideLabel,
+                position: barconfig.labelPosition || 'top',
+                distance: barconfig.labelDistance ? Number(barconfig.labelDistance) : 5,
+                formatter: barconfig.labelFormatter || '{c}',
                 textStyle: {
                     fontSize: fontSize || getFontSize() * .7
                 }
             }
         },
-        barGap: '10%'
-    }
-    if(areaconfig.barMaxWidth) {
-        model.barMaxWidth = areaconfig.barMaxWidth;
-    }
-    if(areaconfig.barWidth) {
-        model.barWidth = areaconfig.barWidth;
-    }
-    if(areaconfig.barMinHeight) {
-        model.barMinHeight = areaconfig.barMinHeight;
-    }
-    if(areaconfig.barGap) {
-        model.barGap = areaconfig.barGap+"%";
+        barGap: '10%',
+        barMaxWidth: barconfig.barMaxWidth || undefined,
+        barWidth: barconfig.barWidth || undefined,
+        barMinHeight: barconfig.barMinHeight || undefined,
+        barGap: barconfig.barGap || undefined
     }
     s = series.map((v, i) => {
         let m = Object.assign({}, model);
@@ -410,15 +538,15 @@ function getBarSeries(fontSize, layout, series, areaconfig) {
     return s;
 }
 
-function getLineSeries(fontSize, series, areaconfig) {
+function getLineSeries(fontSize, series, lineconfig) {
     let s = [];
     const model = {
         type: 'line',
-        smooth: areaconfig.smooth || false,
+        smooth: lineconfig.smooth || false,
         lineStyle: {
             normal: {
-                width: areaconfig.lineWidth || 2,
-                type: areaconfig.lineType || 'solid'
+                width: lineconfig.lineWidth || 2,
+                type: lineconfig.lineType || 'solid'
             }
         },
         markLine: {
@@ -434,15 +562,15 @@ function getLineSeries(fontSize, series, areaconfig) {
                 xAxis: ''
             }]
         },
-        symbol: areaconfig.symbol || 'circle',
-        symbolSize: areaconfig.symbolSize || 4,
-        showSymbol: !areaconfig.hideSymbol,
+        symbol: lineconfig.symbol || 'circle',
+        symbolSize: lineconfig.symbolSize || 4,
+        showSymbol: !lineconfig.hideSymbol,
         label: {
             normal: {
-                show: !areaconfig.hideLabel,
-                position: areaconfig.labelPosition || 'top',
-                distance: areaconfig.labelDistance ? Number(areaconfig.labelDistance) : 5,
-                formatter: areaconfig.labelFormatter || '{c}',
+                show: !lineconfig.hideLabel,
+                position: lineconfig.labelPosition || 'top',
+                distance: lineconfig.labelDistance ? Number(lineconfig.labelDistance) : 5,
+                formatter: lineconfig.labelFormatter || '{c}',
                 textStyle: {
                     fontSize: fontSize || getFontSize() * .7
                 }
@@ -474,7 +602,7 @@ function getPieSeries(fontSize, layout, series, pieconfig) {
                 textStyle: {
                     fontSize: fontSize || getFontSize() * 0.7
                 },
-                formatter: '{b}:  {c} \n {d}%'
+                formatter: pieconfig.labelFormatter || '{b}:  {c} \n {d}%'
             }
         }
     }
@@ -503,7 +631,7 @@ function getPieSeries(fontSize, layout, series, pieconfig) {
 }
 
 function getPieLegend(fontSize, layout, series, legendconfig) {
-    let hide = legendconfig.hide == 'true',
+    let hide = legendconfig.hide === 'true' || legendconfig.hide === true,
         top = legendconfig.top ? (legendconfig.top)+'%' : null,
         left = legendconfig.left ? legendconfig.left+'%' : null,
         itemGap = legendconfig.itemGap ? Number(legendconfig.itemGap) : layout.w / 10,
@@ -511,7 +639,7 @@ function getPieLegend(fontSize, layout, series, legendconfig) {
         itemHeight = legendconfig.itemHeight ? Number(legendconfig.itemHeight) : 14;
 
     let legend = {
-        hide_: hide,
+        show: !hide,
         top_: top,
         left_: left,
         width: legendconfig.width,
@@ -534,6 +662,79 @@ function getPieLegend(fontSize, layout, series, legendconfig) {
     return legend;
 }
 
+function getMixChartSeries(fontSize, layout, series, barconfig, lineconfig, barcolor, linecolor) {
+    let s = [];
+    const barmodel = {
+        type: 'bar',
+        label: {
+            normal: {
+                show: !barconfig.hideLabel,
+                position: barconfig.labelPosition || 'top',
+                distance: barconfig.labelDistance ? Number(barconfig.labelDistance) : 5,
+                formatter: barconfig.labelFormatter || '{c}',
+                textStyle: {
+                    fontSize: fontSize || getFontSize() * .7
+                }
+            }
+        },
+        barGap: '10%',
+        barMaxWidth: barconfig.barMaxWidth || undefined,
+        barWidth: barconfig.barWidth || undefined,
+        barMinHeight: barconfig.barMinHeight || undefined,
+        barGap: barconfig.barGap || undefined
+    }
+    const linemodel = {
+        type: 'line',
+        yAxisIndex: 1,
+        smooth: lineconfig.smooth || false,
+        lineStyle: {
+            normal: {
+                width: lineconfig.lineWidth || 2,
+                type: lineconfig.lineType || 'solid'
+            }
+        },
+        markLine: {
+            symbol: '',
+            label: {
+                normal: {
+                    show: false
+                }
+            },
+            data: [{
+                name: '起始位置',
+                yAxis: null,
+                xAxis: ''
+            }]
+        },
+        symbol: lineconfig.symbol || 'circle',
+        symbolSize: lineconfig.symbolSize || 4,
+        showSymbol: !lineconfig.hideSymbol,
+        label: {
+            normal: {
+                show: !lineconfig.hideLabel,
+                position: lineconfig.labelPosition || 'top',
+                distance: lineconfig.labelDistance ? Number(lineconfig.labelDistance) : 5,
+                formatter: lineconfig.labelFormatter || '{c}',
+                textStyle: {
+                    fontSize: fontSize || getFontSize() * .7
+                }
+            }
+        }
+    }
+
+    s = series.map((v, i) => {
+        let type = v.type;
+        let m = Object.assign({}, eval(`${type}model`));
+        m.name = v.name;
+        m.data = v.data instanceof Array ? v.data : [v.data];
+        let c = [eval(`${type}color`) ? eval(`${type}color`).shift() : undefined];
+        m.color = c;
+        return m;
+    });
+
+    return s;
+}
+
 function getLayout(layout) {
     let l = {};
     for (let k in layout) {

+ 282 - 81
kanban-client/app/component/converter.js

@@ -16,6 +16,8 @@ function converter(data) {
             return lineConfig(v);
         } else if (type == 'pie') {
             return pieConfig(v);
+        } else if(type == 'mixchart') {
+            return mixChartConfig(v);
         } else {
 
         }
@@ -112,18 +114,28 @@ function tableConfig(model) {
 
 function barConfig(model) {
     let { type, config, layout } = model;
-    let { fontSize, title, subtitle, xtitle, xtype, xfields, ytitle, ytype, yfields, series, legendconfig, areaconfig, color } = config;
+    let { fontSize, title, subtitle, xtitle, xtype, xfields, xconfig, ytitle, ytype, yfields, series, yconfig,
+        legendconfig, areaconfig, barconfig, color } = config;
 
+    xconfig = parseObjectStr(xconfig);
+    yconfig = parseObjectStr(yconfig);
     legendconfig = parseObjectStr(legendconfig);
     areaconfig = parseObjectStr(areaconfig);
+    barconfig = parseObjectStr(barconfig);
+    
     color = eval(color);
     series = series ? ((series instanceof Array) ? series : [series]) : [];
     let xf = (xfields instanceof Array) ? xfields : (xfields.replace(['['], '').replace([']'], '').split(',')),
-        legendTop = legendconfig.top ? (legendconfig.top)+'%' : null,
-        itemGap = legendconfig.itemGap ? Number(legendconfig.itemGap) : layout.w / 10,
-        itemWidth = legendconfig.itemWidth ? Number(legendconfig.itemWidth) : 25,
-        itemHeight = legendconfig.itemHeight ? Number(legendconfig.itemHeight) : 14;
-    
+        areaLeft = Number(areaconfig.left)>=0 ? areaconfig.left+'%' : '5%',
+        areaRight = Number(areaconfig.right)>=0 ? areaconfig.right+'%' : '5%',
+        areaTop = Number(areaconfig.top)>=0 ? areaconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '35%' : '28%'),
+        areaBottom = Number(areaconfig.bottom)>=0 ? areaconfig.bottom+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '16%'),
+        
+        legendLeft = Number(legendconfig.left)>=0 ? legendconfig.left+'%' : null,
+        legendTop = Number(legendconfig.top)>=0 ? legendconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '18%'),
+        itemGap = Number(legendconfig.itemGap)>=0 ? Number(legendconfig.itemGap) : layout.w / 10,
+        itemWidth = Number(legendconfig.itemWidth)>=0 ? Number(legendconfig.itemWidth) : 25,
+        itemHeight = Number(legendconfig.itemHeight)>=0 ? Number(legendconfig.itemHeight) : 14;
     let o = {
         type: 'charts',
         config: {
@@ -137,17 +149,14 @@ function barConfig(model) {
                 },
                 grid: {
                     containLabel: true,
-                    top_: areaconfig.top ? areaconfig.top+'%' : null,
-                    bottom_: areaconfig.bottom ? areaconfig.bottom+'%' : null,
-                    left_: areaconfig.left ? areaconfig.left+'%' : null,
-                    right_: areaconfig.right ? areaconfig.right+'%' : null,
-                    top: layout.h * getScreenSize().height / 100 < 310 ? '35%' : '28%',
-                    bottom: layout.h * getScreenSize().height / 100 < 310 ? '20%' : '16%',
+                    left: areaLeft,
+                    right: areaRight,
+                    top: areaTop,
+                    bottom: areaBottom
                 },
                 legend: {
                     show: !legendconfig.hide,
-                    top_: legendTop,
-                    top: (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '18%'),
+                    top: legendTop,
                     padding: 0,
                     orient: legendconfig.orient || 'horizontal',
                     itemGap: itemGap,
@@ -164,14 +173,15 @@ function barConfig(model) {
                     type: xtype,
                     data: xf,
                     name: xtitle,
-                    nameGap: 5,
-                    nameRotate: 270,
-                    nameLocation: 'end',
+                    position: xconfig.position || 'bottom',
+                    nameGap: xconfig.nameGap || 5,
+                    nameRotate: xconfig.nameRotate || 0,
+                    nameLocation: xconfig.nameLocation || 'end',
                     nameTextStyle: {
                         fontSize: getFontSize() * .7
                     },
                     axisLabel: {
-                        rotate: getScreenSize().width * layout.w / xf.length / 100 < 80 ? 45 : 0,
+                        rotate: Number(xconfig.labelRotate)>=0 ? Number(xconfig.labelRotate) : (getScreenSize().width * layout.w / xf.length / 100 < 80 ? 45 : 0),
                         interval: 0,
                         textStyle: {
                             fontSize: getFontSize() * .7
@@ -180,7 +190,10 @@ function barConfig(model) {
                 }],
                 yAxis: [{
                     name: ytitle,
-                    nameRotate: .1,
+                    nameRotate: yconfig.nameRotate || 0,
+                    position: yconfig.position || 'left',
+                    nameLocation: yconfig.nameLocation || 'end',
+                    nameGap: yconfig.nameGap || 15,
                     type: ytype == 'numeric' ? 'value' : ytype,
                     nameTextStyle: {
                         fontSize: getFontSize() * .7
@@ -191,7 +204,7 @@ function barConfig(model) {
                         }
                     }
                 }],
-                series: getBarSeries(fontSize, layout, series, areaconfig)
+                series: getBarSeries(fontSize, layout, series, barconfig)
             }
         },
         layout: getLayout(layout)
@@ -199,27 +212,33 @@ function barConfig(model) {
     if(color && color.length > 0) {
         o.config.option.color = color;
     }
-    if(Number(legendconfig.left) >= 0) {
-        o.config.option.legend.left = Number(legendconfig.left)+'%';
-    }else {
-        o.config.option.legend.right = '5%';
-    }
+    legendLeft ? (o.config.option.legend.left = legendLeft) : (o.config.option.legend.right = '5%');
     return o;
 }
 
 function lineConfig(model) {
     let { type, config, layout } = model;
-    let { fontSize, title, subtitle, xtitle, xtype, xfields, ytitle, ytype, yfields, series, legendconfig, areaconfig, color } = config;
+    let { fontSize, title, subtitle, xtitle, xtype, xfields, xconfig, ytitle, ytype, yfields, yconfig,
+        series, legendconfig, areaconfig, lineconfig, color } = config;
     
+    xconfig = parseObjectStr(xconfig);
+    yconfig = parseObjectStr(yconfig);
     legendconfig = parseObjectStr(legendconfig);
     areaconfig = parseObjectStr(areaconfig);
+    lineconfig = parseObjectStr(lineconfig);
     color = eval(color);
     series = series ? ((series instanceof Array) ? series : [series]) : [];
     let xf = (xfields instanceof Array) ? xfields : (xfields.replace(['['], '').replace([']'], '').split(',')),
-        legendTop = legendconfig.top ? (legendconfig.top)+'%' : null,
-        itemGap = legendconfig.itemGap ? Number(legendconfig.itemGap) : layout.w / 10,
-        itemWidth = legendconfig.itemWidth ? Number(legendconfig.itemWidth) : 25,
-        itemHeight = legendconfig.itemHeight ? Number(legendconfig.itemHeight) : 14;
+        areaLeft = Number(areaconfig.left)>=0 ? areaconfig.left+'%' : '5%',
+        areaRight = Number(areaconfig.right)>=0 ? areaconfig.right+'%' : '5%',
+        areaTop = Number(areaconfig.top)>=0 ? areaconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '35%' : '28%'),
+        areaBottom = Number(areaconfig.bottom)>=0 ? areaconfig.bottom+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '16%'),
+        
+        legendLeft = Number(legendconfig.left)>=0 ? legendconfig.left+'%' : null,
+        legendTop = Number(legendconfig.top)>=0 ? legendconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '18%'),
+        itemGap = Number(legendconfig.itemGap)>=0 ? Number(legendconfig.itemGap) : layout.w / 10,
+        itemWidth = Number(legendconfig.itemWidth)>=0 ? Number(legendconfig.itemWidth) : 25,
+        itemHeight = Number(legendconfig.itemHeight)>=0 ? Number(legendconfig.itemHeight) : 14;
 
     let o = {
         type: 'charts',
@@ -231,17 +250,14 @@ function lineConfig(model) {
                 },
                 grid: {
                     containLabel: true,
-                    top_: areaconfig.top ? areaconfig.top+'%' : null,
-                    bottom_: areaconfig.bottom ? areaconfig.bottom+'%' : null,
-                    left_: areaconfig.left ? areaconfig.left+'%' : null,
-                    right_: areaconfig.right ? areaconfig.right+'%' : null,
-                    top: layout.h * getScreenSize().height / 100 < 310 ? '35%' : '28%',
-                    bottom: layout.h * getScreenSize().height / 100 < 310 ? '20%' : '16%',
+                    left: areaLeft,
+                    right: areaRight,
+                    top: areaTop,
+                    bottom: areaBottom
                 },
                 legend: {
                     show: !legendconfig.hide,
-                    top_: legendTop,
-                    top: (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '18%'),
+                    top: legendTop,
                     padding: 0,
                     orient: legendconfig.orient || 'horizontal',
                     itemGap: itemGap,
@@ -258,14 +274,15 @@ function lineConfig(model) {
                     type: xtype,
                     data: xf,
                     name: xtitle,
-                    nameRotate: 270,
-                    nameLocation: 'end',
-                    nameGap: 5,
+                    position: xconfig.position || 'bottom',
+                    nameRotate: xconfig.nameRotate || 0,
+                    nameLocation: xconfig.nameLocation || 'end',
+                    nameGap: xconfig.nameGap || 15,
                     nameTextStyle: {
                         fontSize: fontSize || getFontSize() * .7
                     },
                     axisLabel: {
-                        rotate: getScreenSize().width * layout.w / xf.length / 100 < 80 ? 45 : 0,
+                        rotate: Number(xconfig.labelRotate)>=0 ? Number(xconfig.labelRotate) : (getScreenSize().width * layout.w / xf.length / 100 < 80 ? 45 : 0),
                         interval: 0,
                         textStyle: {
                             fontSize: fontSize || getFontSize() * .7
@@ -274,7 +291,10 @@ function lineConfig(model) {
                 }],
                 yAxis: [{
                     name: ytitle,
-                    nameRotate: .1,
+                    nameRotate: yconfig.nameRotate || 0,
+                    position: yconfig.position || 'left',
+                    nameLocation: yconfig.nameLocation || 'end',
+                    nameGap: yconfig.nameGap || 15,
                     type: ytype == 'numeric' ? 'value' : ytype,
                     nameTextStyle: {
                         fontSize: fontSize || getFontSize() * .7
@@ -285,7 +305,7 @@ function lineConfig(model) {
                         }
                     }
                 }],
-                series: getLineSeries(fontSize, series, areaconfig),
+                series: getLineSeries(fontSize, series, lineconfig),
                 dataZoom: series.length > 0 ? [
                     {
                         type: 'slider',
@@ -302,11 +322,127 @@ function lineConfig(model) {
     if(color && color.length > 0) {
         o.config.option.color = color;
     }
-    if(Number(legendconfig.left) >= 0) {
-        o.config.option.legend.left = Number(legendconfig.left)+'%';
-    }else {
-        o.config.option.legend.right = '5%';
-    }
+    legendLeft ? (o.config.option.legend.left = legendLeft) : (o.config.option.legend.right = '5%');
+    return o;
+}
+
+function mixChartConfig(model) {
+    let { type, config, layout } = model;
+    let { fontSize, title, subtitle, xtitle, xtype, xfields, xconfig, ybar, yline, series, legendconfig,
+        areaconfig, barconfig, lineconfig, barcolor, linecolor } = config;
+
+    xconfig = parseObjectStr(xconfig);
+    ybar = parseObjectStr(ybar);
+    ybar.config = parseObjectStr(ybar.config);
+    yline = parseObjectStr(yline);
+    yline.config = parseObjectStr(yline.config);
+    
+    legendconfig = parseObjectStr(legendconfig);
+    areaconfig = parseObjectStr(areaconfig);
+    barconfig = parseObjectStr(barconfig);
+    lineconfig = parseObjectStr(lineconfig);
+    barcolor = eval(barcolor);
+    linecolor = eval(linecolor);
+    series = series ? ((series instanceof Array) ? series : [series]) : [];
+
+    let xf = (xfields instanceof Array) ? xfields : (xfields.replace(['['], '').replace([']'], '').split(',')),
+        areaLeft = Number(areaconfig.left)>=0 ? areaconfig.left+'%' : '5%',
+        areaRight = Number(areaconfig.right)>=0 ? areaconfig.right+'%' : '5%',
+        areaTop = Number(areaconfig.top)>=0 ? areaconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '35%' : '28%'),
+        areaBottom = Number(areaconfig.bottom)>=0 ? areaconfig.bottom+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '16%'),
+        
+        legendLeft = Number(legendconfig.left)>=0 ? legendconfig.left+'%' : null,
+        legendTop = Number(legendconfig.top)>=0 ? legendconfig.top+'%' : (layout.h * getScreenSize().height / 100 < 310 ? '20%' : '18%'),
+        itemGap = Number(legendconfig.itemGap)>=0 ? Number(legendconfig.itemGap) : layout.w / 10,
+        itemWidth = Number(legendconfig.itemWidth)>=0 ? Number(legendconfig.itemWidth) : 25,
+        itemHeight = Number(legendconfig.itemHeight)>=0 ? Number(legendconfig.itemHeight) : 14;
+    var o = {
+        type: 'charts',
+        config: {
+            option: {
+                title: getChartsTitle(fontSize, layout, title, subtitle),
+                tooltip: {
+                    trigger: 'axis'
+                },
+                legend: {
+                    show: !legendconfig.hide,
+                    top: legendTop,
+                    padding: 0,
+                    orient: legendconfig.orient || 'horizontal',
+                    itemGap: itemGap,
+                    itemWidth: itemWidth,
+                    itemHeight: itemHeight,
+                    textStyle: {
+                        fontSize: fontSize || getFontSize() * 0.7
+                    },
+                    data: series.map((v, i) => {
+                        return v.name
+                    })
+                },
+                grid: {
+                    containLabel: true,
+                    top: areaTop,
+                    bottom: areaBottom,
+                    left: areaLeft,
+                    right: areaRight
+                },
+                xAxis: [{
+                    type: xtype,
+                    data: xf,
+                    name: xtitle,
+                    position: xconfig.position || 'bottom',
+                    nameGap: xconfig.nameGap || 15,
+                    nameRotate: xconfig.nameRotate || 0,
+                    nameLocation: xconfig.nameLocation || 'end',
+                    nameTextStyle: {
+                        fontSize: getFontSize() * .7
+                    },
+                    axisLabel: {
+                        rotate: Number(xconfig.labelRotate)>=0 ? xconfig.labelRotate : (getScreenSize().width * layout.w / xf.length / 100 < 80 ? 45 : 0),
+                        interval: 0,
+                        textStyle: {
+                            fontSize: getFontSize() * .7
+                        }
+                    }
+                }],
+                yAxis: [{
+                    name: ybar.title,
+                    position: ybar.config ? (ybar.config.position || 'left') : 'left',
+                    nameRotate: ybar.config ? (ybar.config.nameRotate || 0) : 0,
+                    nameLocation: ybar.config ? (ybar.config.nameLocation || 'end') : 'end',
+                    nameGap: ybar.config ? (ybar.config.nameGap || 15) : 15,
+                    type: ybar.type == 'numeric' ? 'value' : ytype,
+                    nameTextStyle: {
+                        fontSize: getFontSize() * .7
+                    },
+                    axisLabel: {
+                        textStyle: {
+                            fontSize: getFontSize() * .7
+                        }
+                    }
+                },{
+                    name: yline.title,
+                    position: yline.config ? (yline.config.position || 'right') : 'right',
+                    nameRotate: yline.config ? (yline.config.nameRotate || 0) : 0,
+                    nameLocation: yline.config ? (yline.config.nameLocation || 'end') : 'end',
+                    nameGap: yline.config ? (yline.config.nameGap || 15) : 15,
+                    type: yline.type == 'numeric' ? 'value' : ytype,
+                    nameTextStyle: {
+                        fontSize: getFontSize() * .7
+                    },
+                    axisLabel: {
+                        textStyle: {
+                            fontSize: getFontSize() * .7
+                        }
+                    }
+                }],
+                series: getMixChartSeries(fontSize, layout, series, barconfig, lineconfig, barcolor, linecolor)
+            }
+        },
+        layout: getLayout(layout)
+    };
+    legendLeft ? (o.config.option.legend.left = legendLeft) : (o.config.option.legend.right = '5%');
+
     return o;
 }
 
@@ -371,34 +507,26 @@ function getChartsTitle(fontSize, layout, title, subtitle) {
     return title;
 }
 
-function getBarSeries(fontSize, layout, series, areaconfig) {
+function getBarSeries(fontSize, layout, series, barconfig) {
     let s = [];
     const model = {
         type: 'bar',
         label: {
             normal: {
-                show: !areaconfig.hideLabel,
-                position: areaconfig.labelPosition || 'top',
-                distance: areaconfig.labelDistance ? Number(areaconfig.labelDistance) : 5,
-                formatter: areaconfig.labelFormatter || '{c}',
+                show: !barconfig.hideLabel,
+                position: barconfig.labelPosition || 'top',
+                distance: barconfig.labelDistance ? Number(barconfig.labelDistance) : 5,
+                formatter: barconfig.labelFormatter || '{c}',
                 textStyle: {
                     fontSize: fontSize || getFontSize() * .7
                 }
             }
         },
-        barGap: '10%'
-    }
-    if(areaconfig.barMaxWidth) {
-        model.barMaxWidth = areaconfig.barMaxWidth;
-    }
-    if(areaconfig.barWidth) {
-        model.barWidth = areaconfig.barWidth;
-    }
-    if(areaconfig.barMinHeight) {
-        model.barMinHeight = areaconfig.barMinHeight;
-    }
-    if(areaconfig.barGap) {
-        model.barGap = areaconfig.barGap+"%";
+        barGap: '10%',
+        barMaxWidth: barconfig.barMaxWidth || undefined,
+        barWidth: barconfig.barWidth || undefined,
+        barMinHeight: barconfig.barMinHeight || undefined,
+        barGap: barconfig.barGap || undefined
     }
     s = series.map((v, i) => {
         let m = Object.assign({}, model);
@@ -410,15 +538,15 @@ function getBarSeries(fontSize, layout, series, areaconfig) {
     return s;
 }
 
-function getLineSeries(fontSize, series, areaconfig) {
+function getLineSeries(fontSize, series, lineconfig) {
     let s = [];
     const model = {
         type: 'line',
-        smooth: areaconfig.smooth || false,
+        smooth: lineconfig.smooth || false,
         lineStyle: {
             normal: {
-                width: areaconfig.lineWidth || 2,
-                type: areaconfig.lineType || 'solid'
+                width: lineconfig.lineWidth || 2,
+                type: lineconfig.lineType || 'solid'
             }
         },
         markLine: {
@@ -434,15 +562,15 @@ function getLineSeries(fontSize, series, areaconfig) {
                 xAxis: ''
             }]
         },
-        symbol: areaconfig.symbol || 'circle',
-        symbolSize: areaconfig.symbolSize || 4,
-        showSymbol: !areaconfig.hideSymbol,
+        symbol: lineconfig.symbol || 'circle',
+        symbolSize: lineconfig.symbolSize || 4,
+        showSymbol: !lineconfig.hideSymbol,
         label: {
             normal: {
-                show: !areaconfig.hideLabel,
-                position: areaconfig.labelPosition || 'top',
-                distance: areaconfig.labelDistance ? Number(areaconfig.labelDistance) : 5,
-                formatter: areaconfig.labelFormatter || '{c}',
+                show: !lineconfig.hideLabel,
+                position: lineconfig.labelPosition || 'top',
+                distance: lineconfig.labelDistance ? Number(lineconfig.labelDistance) : 5,
+                formatter: lineconfig.labelFormatter || '{c}',
                 textStyle: {
                     fontSize: fontSize || getFontSize() * .7
                 }
@@ -474,7 +602,7 @@ function getPieSeries(fontSize, layout, series, pieconfig) {
                 textStyle: {
                     fontSize: fontSize || getFontSize() * 0.7
                 },
-                formatter: '{b}:  {c} \n {d}%'
+                formatter: pieconfig.labelFormatter || '{b}:  {c} \n {d}%'
             }
         }
     }
@@ -503,7 +631,7 @@ function getPieSeries(fontSize, layout, series, pieconfig) {
 }
 
 function getPieLegend(fontSize, layout, series, legendconfig) {
-    let hide = legendconfig.hide == 'true',
+    let hide = legendconfig.hide === 'true' || legendconfig.hide === true,
         top = legendconfig.top ? (legendconfig.top)+'%' : null,
         left = legendconfig.left ? legendconfig.left+'%' : null,
         itemGap = legendconfig.itemGap ? Number(legendconfig.itemGap) : layout.w / 10,
@@ -511,7 +639,7 @@ function getPieLegend(fontSize, layout, series, legendconfig) {
         itemHeight = legendconfig.itemHeight ? Number(legendconfig.itemHeight) : 14;
 
     let legend = {
-        hide_: hide,
+        show: !hide,
         top_: top,
         left_: left,
         width: legendconfig.width,
@@ -534,6 +662,79 @@ function getPieLegend(fontSize, layout, series, legendconfig) {
     return legend;
 }
 
+function getMixChartSeries(fontSize, layout, series, barconfig, lineconfig, barcolor, linecolor) {
+    let s = [];
+    const barmodel = {
+        type: 'bar',
+        label: {
+            normal: {
+                show: !barconfig.hideLabel,
+                position: barconfig.labelPosition || 'top',
+                distance: barconfig.labelDistance ? Number(barconfig.labelDistance) : 5,
+                formatter: barconfig.labelFormatter || '{c}',
+                textStyle: {
+                    fontSize: fontSize || getFontSize() * .7
+                }
+            }
+        },
+        barGap: '10%',
+        barMaxWidth: barconfig.barMaxWidth || undefined,
+        barWidth: barconfig.barWidth || undefined,
+        barMinHeight: barconfig.barMinHeight || undefined,
+        barGap: barconfig.barGap || undefined
+    }
+    const linemodel = {
+        type: 'line',
+        yAxisIndex: 1,
+        smooth: lineconfig.smooth || false,
+        lineStyle: {
+            normal: {
+                width: lineconfig.lineWidth || 2,
+                type: lineconfig.lineType || 'solid'
+            }
+        },
+        markLine: {
+            symbol: '',
+            label: {
+                normal: {
+                    show: false
+                }
+            },
+            data: [{
+                name: '起始位置',
+                yAxis: null,
+                xAxis: ''
+            }]
+        },
+        symbol: lineconfig.symbol || 'circle',
+        symbolSize: lineconfig.symbolSize || 4,
+        showSymbol: !lineconfig.hideSymbol,
+        label: {
+            normal: {
+                show: !lineconfig.hideLabel,
+                position: lineconfig.labelPosition || 'top',
+                distance: lineconfig.labelDistance ? Number(lineconfig.labelDistance) : 5,
+                formatter: lineconfig.labelFormatter || '{c}',
+                textStyle: {
+                    fontSize: fontSize || getFontSize() * .7
+                }
+            }
+        }
+    }
+
+    s = series.map((v, i) => {
+        let type = v.type;
+        let m = Object.assign({}, eval(`${type}model`));
+        m.name = v.name;
+        m.data = v.data instanceof Array ? v.data : [v.data];
+        let c = [eval(`${type}color`) ? eval(`${type}color`).shift() : undefined];
+        m.color = c;
+        return m;
+    });
+
+    return s;
+}
+
 function getLayout(layout) {
     let l = {};
     for (let k in layout) {

+ 6 - 16
kanban-client/app/component/factory.dev.js

@@ -2,7 +2,7 @@ import React from 'react';
 import Container from './Layout.dev.js';
 import Title from '../src/Title/Title.dev.jsx';
 import MessageBox from '../src/MsgBox/MessageBox.jsx';
-import { converter } from './converter.dev.js';
+import { converter } from './converter.js';
 import URL from '../constants/url.dev.json';
 
 import tempdata from '../data/bug1.json';
@@ -84,24 +84,16 @@ class Factory extends React.Component {
             current: current,
             next: next
         };
-        // 刷新
         if (refresh.current) {
             if (refresh.current.enable) {
                 this.refreshThis = setInterval(function () {
-                    this.getModelConfig(this.props.code[0] + '?kanbanCode=' + codes[this.index]);
-                }.bind(this), refresh.current.interval * 1000 || 10000)
-            }
-        }
-        // 切换
-        if (refresh.next) {
-            if (refresh.next.enable) {
-                this.refreshNext = setInterval(function () {
-                    if (this.index >= codes.length - 1) {
+                    if (this.index == codes.length - 1) {
                         this.index = 0;
                     } else {
                         this.index++;
                     }
-                }.bind(this), refresh.next.interval * 1000 || 30000)
+                    this.getModelConfig(this.props.code[0] + '?kanbanCode=' + codes[this.index]);
+                }.bind(this), refresh.current.interval * 1000 || 10000)
             }
         }
     }
@@ -173,12 +165,10 @@ class Factory extends React.Component {
             items = fixedbox.items || [];
         }
 
-        const staticC = {
-        }
         return (
             <div ref='body'>
-                <Title static={staticC} setTitleHeight={this.setTitleHeight.bind(this)} {...titleConfig} />
-                <Container static={this.props.static} items={content.items} rowHeight={(window.innerHeight - titleHeight) / 10} />
+                <Title setTitleHeight={this.setTitleHeight.bind(this)} {...titleConfig} />
+                <Container items={content.items} rowHeight={(window.innerHeight - titleHeight) / 10} />
             </div>
         );
     }

+ 3 - 6
kanban-client/app/component/factory.js

@@ -96,7 +96,7 @@ class Factory extends React.Component {
     }
 
     onWindowResize() {
-        this.forceUpdate();
+        this.setTitleHeight(this.getTitleHeight());
     }
 
     componentDidUpdate() {
@@ -128,9 +128,6 @@ class Factory extends React.Component {
     }
 
     componentWillReceiveProps(nextProps) {
-        this.setState({
-            titleHeight: this.getTitleHeight()
-        });
     }
 
     render() {
@@ -150,8 +147,8 @@ class Factory extends React.Component {
         }
         return (
             <div>
-                <Title static={this.props.static} setTitleHeight={this.setTitleHeight.bind(this)} {...titleConfig} />
-                <Container static={this.props.static} items={content.items} rowHeight={(window.innerHeight - titleHeight) / 10} />
+                <Title setTitleHeight={this.setTitleHeight.bind(this)} {...titleConfig} />
+                <Container items={content.items} rowHeight={(window.innerHeight - titleHeight) / 10} />
             </div>
         );
     }

+ 38 - 53
kanban-client/app/data/testbar.json

@@ -1,58 +1,43 @@
 {
-    "data": [
-        {
-            "content": {
-                "items": {
-                    "layout": {
-                        "w": 100,
-                        "h": 100,
-                        "y": 0,
-                        "x": 0
-                    },
-                    "config": {
-                        "color": "[\"#CC99FF\",\"#FF0000\",\"#0000FF\",\"#99CC00\"]",
-                        "legendconfig": "{\"top\":\"50\",\"orient\":\"vertical\",\"itemWidth\":\"20\"}",
-                        "series": [
-                            {
-                                "name": "已启动",
-                                "data": [
-                                    10,
-                                    12,
-                                    5,
-                                    9,
-                                    7
-                                ]
-                            },
-                            {
-                                "name": "未启动",
-                                "data": [
-                                    6,
-                                    3,
-                                    0,
-                                    2,
-                                    9
-                                ]
-                            }
-                        ],
-                        "title": "按负责人统计项目启动个数",
-                        "ytype": "numeric",
-                        "xtitle": "项目负责人",
-                        "xtype": "category",
-                        "subtitle": "模拟数据",
-                        "ytitle": "项目数量统计",
-                        "xfields": "[张飞, 关羽, 诸葛亮, 曹操, 刘禅]"
-                    },
-                    "type": "bar"
+    "instance": {
+        "enabledKanbanCodes": ["712DCC77A16"],
+        "display": "AutoSwitch",
+        "switchFrequency": 3,
+        "refreshFrequency": 3,
+        "parameters": []
+    },
+    "data": [{
+        "content": {
+            "items": {
+                "layout": {
+                    "w": 100,
+                    "x": 0,
+                    "h": 100,
+                    "y": 0
+                },
+                "type": "bar",
+                "config": {
+                    "xfields": "[null, 王五, 张三, TEST0821, 晓兰, EMR01, 陈梦, 吴雨骁, 粟宇, 周兵, TX03, lptest, 黄俊, 陈炜, 赵六, 龙震坤, 测试人员, 刘萌冰, 卫立煌, 廖耀湘, 张玲萍, 李剑辉, 史晨如, 黄信, 詹国胜, 群, 熊志新, 陈庆之, 张文, 刘娇, 顾群2, 测试0103, EMR02, 张荣, 余慧, 陈劲松, 吴雨骁test, 黎旦阳, 陈虎, 顾群, 杨若楠, 陈金金, 易紫燕, USER0005, 龙晓兰, 李四, 国胜, 祝通鸿test, 徐健, TEST115, 王成雍]",
+                    "xtype": "category",
+                    "color": "[\"#CC99FF\",\"#FF0000\",\"#0000FF\",\"#99CC00\"]",
+                    "yconfig": "{\"position\":\"left\",\"nameLocation\":\"middle\"}",
+                    "title": "BAR标题",
+                    "ytype": "numeric",
+                    "areaconfig": "{\"left\":\"11\"}",
+                    "xconfig": "{\"position\":\"bottom\"}",
+                    "ytitle": "数量",
+                    "series": [{
+                        "data": [9, 4, 4, 0, 0, 1, 0, 1, 2, 2, 0, 0, 7, 1, 8, 0, 1, 0, 5, 5, 9, 0, 0, 5, 0, 1, 0, 5, 3, 1, 0, 0, 2, 0, 0, 0, 1, 5, 0, 1, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0],
+                        "name": "已启动"
+                    }, {
+                        "data": [0, 1, 0, 1, 1, 0, 1, 1, 2, 1, 1, 0, 9, 1, 5, 2, 0, 1, 1, 1, 2, 1, 0, 2, 10, 3, 1, 2, 1, 3, 1, 0, 0, 1, 1, 1, 0, 1, 5, 2, 1, 0, 4, 1, 1, 0, 2, 0, 0, 0, 1],
+                        "name": "未启动"
+                    }],
+                    "subtitle": "假装写个副标题",
+                    "xtitle": "姓名",
+                    "barconfig": "{\"hideLabel\":true}"
                 }
             }
         }
-    ],
-    "instance": {
-        "templateCodes": [
-            "51FBA074117"
-        ],
-        "switchFrequency": 5000,
-        "display": "AutoSwitch",
-        "refreshFrequency": 5000
-    }
+    }]
 }

+ 37 - 67
kanban-client/app/data/testline.json

@@ -1,71 +1,41 @@
 {
-    "data": [
-        {
-            "content": {
-                "items": [
-                    {
-                        "layout": {
-                            "w": 40,
-                            "h": 100,
-                            "y": 0,
-                            "x": 0
-                        },
-                        "config": {
-                            "color": "[\"#CC99FF\",\"#FF0000\",\"#0000FF\",\"#99CC00\"]",
-                            "series": [
-                                {
-                                    "name": "投入",
-                                    "data": [
-                                        100.71,
-                                        130.52,
-                                        106.34,
-                                        188.67,
-                                        133.54,
-                                        200.43,
-                                        183.23,
-                                        190.22,
-                                        200.56,
-                                        170.04,
-                                        152.23
-                                    ]
-                                },
-                                {
-                                    "name": "产出",
-                                    "data": [
-                                        320.32,
-                                        345.45,
-                                        200.08,
-                                        412.32,
-                                        401.11,
-                                        388.69,
-                                        375.01,
-                                        432.10,
-                                        333.78,
-                                        400.00,
-                                        393.45
-                                    ]
-                                }
-                            ],
-                            "title": "XXX公司2017年投入产出折线图",
-                            "ytype": "numeric",
-                            "xtitle": "月份",
-                            "xtype": "category",
-                            "subtitle": "模拟数据",
-                            "ytitle": "金额/万",
-                            "xfields": "[一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月]"
-                        },
-                        "type": "line"
-                    }
-                ]
-            }
-        }
-    ],
     "instance": {
-        "templateCodes": [
-            "506CFE6D911"
-        ],
-        "switchFrequency": 5000,
+        "enabledKanbanCodes": ["63AE858DE2B"],
         "display": "AutoSwitch",
-        "refreshFrequency": 5000
-    }
+        "switchFrequency": 3,
+        "refreshFrequency": 3,
+        "parameters": []
+    },
+    "data": [{
+        "content": {
+            "items": {
+                "layout": {
+                    "w": 100,
+                    "x": 0,
+                    "h": 100,
+                    "y": 0
+                },
+                "type": "line",
+                "config": {
+                    "xfields": "[null, 王五, 张三, TEST0821, 晓兰, EMR01, 陈梦, 吴雨骁, 粟宇, 周兵, TX03, lptest, 黄俊, 陈炜, 赵六, 龙震坤, 测试人员, 刘萌冰, 卫立煌, 廖耀湘, 张玲萍, 李剑辉, 史晨如, 黄信, 詹国胜, 群, 熊志新, 陈庆之, 张文, 刘娇, 顾群2, 测试0103, EMR02, 张荣, 余慧, 陈劲松, 吴雨骁test, 黎旦阳, 陈虎, 顾群, 杨若楠, 陈金金, 易紫燕, USER0005, 龙晓兰, 李四, 国胜, 祝通鸿test, 徐健, TEST115, 王成雍]",
+                    "xtype": "category",
+                    "color": "[]",
+                    "legendconfig": "{\"hide\":true,\"orient\":\"horizontal\"}",
+                    "yconfig": "{\"position\":\"right\",\"nameLocation\":\"middle\",\"nameGap\":\"50\",\"nameRotate\":\"-90\"}",
+                    "ytype": "numeric",
+                    "xconfig": "{\"position\":\"bottom\",\"nameLocation\":\"end\",\"nameGap\":\"40\",\"nameRotate\":\"30\",\"labelRotate\":\"45\"}",
+                    "ytitle": "数量",
+                    "lineconfig": "{\"smooth\":true,\"hideLabel\":true,\"labelFormatter\":\"{b}:{c}\"}",
+                    "series": [{
+                        "data": [9, 4, 4, 0, 0, 1, 0, 1, 2, 2, 0, 0, 7, 1, 8, 0, 1, 0, 5, 5, 9, 0, 0, 5, 0, 1, 0, 5, 3, 1, 0, 0, 2, 0, 0, 0, 1, 5, 0, 1, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0],
+                        "name": "已启动"
+                    }, {
+                        "data": [0, 1, 0, 1, 1, 0, 1, 1, 2, 1, 1, 0, 9, 1, 5, 2, 0, 1, 1, 1, 2, 1, 0, 2, 10, 3, 1, 2, 1, 3, 1, 0, 0, 1, 1, 1, 0, 1, 5, 2, 1, 0, 4, 1, 1, 0, 2, 0, 0, 0, 1],
+                        "name": "未启动"
+                    }],
+                    "xtitle": "姓名"
+                }
+            }
+        }
+    }]
 }

+ 22 - 16
kanban-client/app/src/Charts/ECharts.dev.js

@@ -64,23 +64,22 @@ export class ReactEchart extends React.Component {
         option.xAxis[0].data.push(option.xAxis[0].data[0]);
         option.xAxis[0].data.splice(0, 1);
         let node = this.echarts_react.echartsElement;
-        this.setState({
-            option: reset(option,node,this.showCount)
-        });
+        this.reset();
     }
 
     componentDidMount() {
         let { option } = this.state;
-        if(option.series.length > 0) {
-            if(option.series[0].type == 'line') {
-                this.splitData();
-                if(this.maxCount > this.showCount + 1) {
-                    this.fullData();
-                    this.RK = window.setInterval(this.scroll.bind(this), 1000);
-                }
-            }
-            this.reset();
-        }
+        // if(option.series.length == 1) { // line图超长滚动展示逻辑仅对单chart图生效
+        //     if(option.series[0].type == 'line') {
+        //         this.splitData();
+        //         if(this.maxCount > this.showCount + 1) {
+        //             this.fullData();
+        //             this.RK = window.setInterval(this.scroll.bind(this), 1000);
+        //         }
+        //     }
+        //     this.reset();
+        // }
+        this.reset();
     }
 
     componentDidUpdate() {
@@ -94,13 +93,20 @@ export class ReactEchart extends React.Component {
 
     componentWillReceiveProps(nextProps) {
         let d1 = nextProps.option.series.map(function(s) {
-            return s.data;
+            let x = {
+                data: s.data,
+                type: s.type
+            }
+            return x;
         });
         let d2 = this.newProps.option.series.map(function(s) {
-            return s.data;
+            let x = {
+                data: s.data,
+                type: s.type
+            }
+            return x;
         });
         if(!isEqual(d1, d2)) {
-            console.log('no equals');
             let echarts_instance = this.echarts_react.getEchartsInstance();
             echarts_instance.clear();
         }

+ 13 - 50
kanban-client/app/src/Charts/ECharts.js

@@ -19,61 +19,16 @@ export class ReactEchart extends React.Component {
         theme: 'dark',
         showCount: 0
     }
-    
-    fullData() {
-        let { option } = this.state;
-        option.series = option.series.map((s, i) => {
-            s.data.push(null);
-            return s;
-        });
-        option.xAxis[0].data.push('');
-    }
-
-    setShowCount() {
-        let { option } = this.state;
-        let node = this.echarts_react.echartsElement;
-        let cWidth = node.offsetWidth;
-        this.showCount = this.newProps.showCount == -1 ? option.series[0].data.length : (this.newProps.showCount || Math.round(cWidth / 60));
-        option.series.map((s, i) => {
-            this.maxCount = s.data.length > this.maxCount ? s.data.length : this.maxCount;
-        });
-    }
 
     reset() {
         let node = this.echarts_react.echartsElement;
+        let option = reset(this.newProps.option, node, this.showCount);
         this.setState({
-            option: reset(this.newProps.option, node, this.showCount)
-        });
-    }
-
-    scroll() {
-        let { option } = this.state;
-        let series = option.series.map((s, i) => {
-            s.data.push(s.data[0]);
-            s.data.splice(0, 1);
-            return s;
-        });
-        option.series = series;
-        option.xAxis[0].data.push(option.xAxis[0].data[0]);
-        option.xAxis[0].data.splice(0, 1);
-        let node = this.echarts_react.echartsElement;
-        this.setState({
-            option: reset(option,node,this.showCount)
+            option: option
         });
     }
-
     componentDidMount() {
-        let { option } = this.state;
-        if(option.series.length > 0) {
-            if(option.series[0].type == 'line') {
-                this.setShowCount();
-                if(this.maxCount > this.showCount + 1) {
-                    this.fullData();
-                    this.RK = window.setInterval(this.scroll.bind(this), 1000);
-                }
-            }
-            this.reset();
-        }
+        this.reset();
     }
 
     componentDidUpdate() {
@@ -87,10 +42,18 @@ export class ReactEchart extends React.Component {
 
     componentWillReceiveProps(nextProps) {
         let d1 = nextProps.option.series.map(function(s) {
-            return s.data;
+            let x = {
+                data: s.data,
+                type: s.type
+            }
+            return x;
         });
         let d2 = this.newProps.option.series.map(function(s) {
-            return s.data;
+            let x = {
+                data: s.data,
+                type: s.type
+            }
+            return x;
         });
         if(!isEqual(d1, d2)) {
             let echarts_instance = this.echarts_react.getEchartsInstance();

+ 17 - 18
kanban-client/app/src/Charts/ResetCharts.js

@@ -1,21 +1,22 @@
 export default function resetchart(option, node, sc) {
-    if(option.series.length == 0) {
-        return option;
-    }
-    let type = option.series[0].type;
-    if(type == 'bar') {
-        return resetBarOption(option, node);
-    }else if(type == 'line') {
-        return resetLineOption(option, node, sc);
-    }else if(type == 'pie') {
-        return resetPieOption(option, node);
+    if(option.series.length == 1) { // 布局自适应调整仅对单chart图生效
+        let type = option.series[0].type;
+        if(type == 'bar') {
+            return resetBarOption(option, node);
+        }else if(type == 'line') {
+            return resetLineOption(option, node, sc);
+        }else if(type == 'pie') {
+            return resetPieOption(option, node);
+        }else {
+            return option;
+        }
     }else {
         return option;
     }
 }
 
 function resetBarOption(option, node) {
-    option.title.subtext = node.offsetHeight < 300 ? '' : option.title.subtext,
+    /* option.title ? option.title.subtext = node.offsetHeight < 300 ? '' : option.title.subtext : '',
     option.grid.top = option.grid.top_ ? option.grid.top_ : (node.offsetHeight < 310 ? '35%' : '28%');
     option.grid.bottom = option.grid.bottom_ ? option.grid.bottom_ : (node.offsetHeight < 310 ? '20%' : '16%');
     option.grid.left = option.grid.left_ ? option.grid.left_ : '10%';
@@ -26,12 +27,12 @@ function resetBarOption(option, node) {
         option.xAxis[0].nameRotate = 0;
         option.xAxis[0].nameGap = node.offsetHeight/20;
     }
-    option.xAxis[0].axisLabel.rotate = node.offsetWidth / option.xAxis[0].data.length < 80 ? 45 : 0;
+    option.xAxis[0].axisLabel.rotate = node.offsetWidth / option.xAxis[0].data.length < 80 ? 45 : 0; */
     return option;
 }
 
 function resetLineOption(option, node, sc) {
-    option.grid.top = option.grid.top_ ? option.grid.top_ : (node.offsetHeight < 310 ? '35%' : '28%');
+    /* option.grid.top = option.grid.top_ ? option.grid.top_ : (node.offsetHeight < 310 ? '35%' : '28%');
     option.grid.bottom = option.grid.bottom_ ? option.grid.bottom_ : (node.offsetHeight < 310 ? '20%' : '16%');
     option.grid.left = option.grid.left_ ? option.grid.left_ : '10%';
     option.grid.right = option.grid.right_ ? option.grid.right_ : '10%';
@@ -42,21 +43,19 @@ function resetLineOption(option, node, sc) {
         option.xAxis[0].nameGap = node.offsetHeight/20;
     }
     option.xAxis[0].axisLabel.rotate = node.offsetWidth / option.xAxis[0].data.length < 80 ? 45 : 0;
-    option.dataZoom[0].endValue = sc >= option.xAxis[0].data.length ? option.xAxis[0].data.length - 1 : sc;
+    option.dataZoom[0].endValue = sc >= option.xAxis[0].data.length ? option.xAxis[0].data.length - 1 : sc; */
     return option;
 }
 
 function resetPieOption(option, node) {
     option.animation = true;
-    option.legend.show = (option.legend.hide_ == true) ? false : node.offsetHeight > 300;
     option.legend.top = option.legend.top_ ? option.legend.top_ : (node.offsetHeight > 300 ? '20%' : '15%');
+    option.legend.orient = option.legend.orient_ ? option.legend.orient_ : (node.offsetHeight > 300 ? 'horizontal' : 'vertical');
     if(option.legend.left_) {
         option.legend.left = option.legend.left_;
     }else {
-        option.legend.right = node.offsetHeight > 300 ? 'auto' : '15%';
+        option.legend.right = option.legend.orient == 'vertical' ? '10%' : (node.offsetHeight > 300 ? 'auto' : '10%');
     }
-    option.legend.orient = option.legend.orient_ ? option.legend.orient_ : (node.offsetHeight > 300 ? 'horizontal' : 'vertical');
-
 
     let cx = option.series[0].centerx ? option.series[0].centerx : '50%',
         cy = option.series[0].centery ? option.series[0].centery : (node.offsetHeight > 300 ? '65%' : '55%'),

+ 10 - 5
kanban-client/app/src/Title/Title.dev.jsx

@@ -24,9 +24,7 @@ export default class Title extends React.Component {
   }
 
   componentDidMount() {
-    let height = this.getTitleHeight();
-    this.props.setTitleHeight(height);
-    
+    this.setTitleHeight();
   }
   
   componentWillReceiveProps(nextProps) {
@@ -36,7 +34,7 @@ export default class Title extends React.Component {
     if(this.props.title == prevProps.title) {
       return;
     }
-    prevProps.setTitleHeight(this.getTitleHeight());
+    this.setTitleHeight();
   }
 
   getTitle() {
@@ -48,6 +46,13 @@ export default class Title extends React.Component {
     return this.refs.title.offsetHeight;
   }
 
+  setTitleHeight() {
+    window.setTimeout(() => {
+      let height = this.getTitleHeight();
+      this.props.setTitleHeight(height);
+    }, 500);
+  }
+
   render() {
     const props = this.props;
     const {prefixCls, fontSize} = props;
@@ -56,7 +61,7 @@ export default class Title extends React.Component {
 
     let title = this.getTitle();
     return (
-      <div ref='title' className={className} key={prefixCls} dangerouslySetInnerHTML={{ __html: title }}>
+      <div ref='title' className={className} style={{fontSize: fontSize}} key={prefixCls} dangerouslySetInnerHTML={{ __html: title }}>
       </div>
     );
   }

+ 11 - 5
kanban-client/app/src/Title/Title.jsx

@@ -24,18 +24,17 @@ export default class Title extends React.Component {
   }
 
   componentDidMount() {
-    let height = this.getTitleHeight();
-    this.props.setTitleHeight(height);
+    this.setTitleHeight();
   }
-
+  
   componentWillReceiveProps(nextProps) {
   }
-
+  
   componentDidUpdate(prevProps) {
     if(this.props.title == prevProps.title) {
       return;
     }
-    prevProps.setTitleHeight(this.getTitleHeight());
+    this.setTitleHeight();
   }
 
   getTitle() {
@@ -47,6 +46,13 @@ export default class Title extends React.Component {
     return this.refs.title.offsetHeight;
   }
 
+  setTitleHeight() {
+    window.setTimeout(() => {
+      let height = this.getTitleHeight();
+      this.props.setTitleHeight(height);
+    }, 500);
+  }
+
   render() {
     const props = this.props;
     const {prefixCls, fontSize} = props;

+ 6 - 11
kanban-client/app/utils/BaseUtils.js

@@ -76,7 +76,8 @@ function isEqual(a,b){
         for(var i=0;i<propsA.length;i++){
             var propName=propsA[i];
             //如果对应属性对应值不相等,则返回false
-            if(a[propName] !== b[propName]){
+            //if(a[propName] !== b[propName]){
+            if(!isEqual(a[propName], b[propName])){
                 return false;
             }
         }
@@ -85,18 +86,12 @@ function isEqual(a,b){
     //如果是数组类型
     if(classNameA == '[object Array]'){
         let i = 0;
-        for(i; i < a.length;) {
-            if(isEqual(a[i], b[i])) {
-                i++;
-            }else {
-                break;
+        for(i; i < a.length;i++) {
+            if(!isEqual(a[i], b[i])) {
+                return false;
             }
         }
-        if(i==a.length) {
-            return true;
-        }else {
-            return false;
-        }
+        return true;
     }
 }