You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by ha...@apache.org on 2018/01/08 16:13:28 UTC

[incubator-skywalking-ui] branch feature/5.0.0 updated (546e414 -> 354beb9)

This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a change to branch feature/5.0.0
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git.


    from 546e414  Time-Select component finish
     new 5a20076  Fetching dashboard data
     new a62a368  Fetching application data
     new 7682d98  Fetching server data
     new de65603  Fetching service data
     new 354beb9  Fetching alarm data

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/main/frontend/.roadhogrc.mock.js               | 111 ++++++-----
 src/main/frontend/src/models/alert.js              |  17 +-
 src/main/frontend/src/models/application.js        |  18 +-
 src/main/frontend/src/models/dashboard.js          |  28 ++-
 src/main/frontend/src/models/server.js             |  35 +++-
 src/main/frontend/src/models/service.js            |  26 ++-
 src/main/frontend/src/routes/Alert/Alert.js        |  67 +++----
 .../frontend/src/routes/Application/Application.js | 103 ++++-------
 .../frontend/src/routes/Dashboard/Dashboard.js     | 205 ++++++++-------------
 src/main/frontend/src/routes/Server/Server.js      | 121 +++++-------
 src/main/frontend/src/routes/Service/Service.js    | 140 +++++---------
 src/main/frontend/src/services/graphql.js          |   8 +
 src/main/frontend/src/utils/request.js             |   8 +-
 src/main/frontend/src/utils/utils.js               |   4 +
 14 files changed, 412 insertions(+), 479 deletions(-)
 create mode 100644 src/main/frontend/src/services/graphql.js

-- 
To stop receiving notification emails like this one, please contact
['"commits@skywalking.apache.org" <co...@skywalking.apache.org>'].

[incubator-skywalking-ui] 04/05: Fetching service data

Posted by ha...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch feature/5.0.0
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git

commit de65603af4af3f885983a66ca6bb35e49ff22448
Author: gaohongtao <ha...@gmail.com>
AuthorDate: Mon Jan 8 23:36:25 2018 +0800

    Fetching service data
---
 src/main/frontend/.roadhogrc.mock.js            |  15 ++-
 src/main/frontend/src/models/service.js         |  26 ++++-
 src/main/frontend/src/routes/Service/Service.js | 140 ++++++++----------------
 3 files changed, 79 insertions(+), 102 deletions(-)

diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index 7b4c343..d25ea2d 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -35,7 +35,6 @@ const proxy = mockjs.mock({
       'getServerThroughput|10': [{'key|+1': 1, 'name': '@name', 'tps|100-10000': 1}],
     }
   },
-
   'POST /api/server': {
     data: {
       'searchServer|5': [{}],
@@ -60,6 +59,20 @@ const proxy = mockjs.mock({
       },
     }
   },
+  'POST /api/service': {
+    data: {
+      'searchService|5': [{}],
+      getServiceResponseTimeTrend: {
+        'trendList|15': ['@natural(100, 1000)'],
+      },
+      getServiceTPSTrend: {
+        'trendList|15': ['@natural(500, 10000)'],
+      },
+      getServiceSLATrend: {
+        'trendList|15': ['@natural(80, 100)'],
+      },
+    }
+  },
 });
 
 export default noProxy ? {} : delay(proxy, 1000);
diff --git a/src/main/frontend/src/models/service.js b/src/main/frontend/src/models/service.js
index 3954394..0149b09 100644
--- a/src/main/frontend/src/models/service.js
+++ b/src/main/frontend/src/models/service.js
@@ -1,17 +1,35 @@
-// import { xxx } from '../services/xxx';
+import { query } from '../services/graphql';
+
 export default {
-  namespace: "service",
-  state: {},
+  namespace: 'service',
+  state: {
+    searchService: [],
+    getServiceResponseTimeTrend: {
+      trendList: [],
+    },
+    getServiceTPSTrend: {
+      trendList: [],
+    },
+    getServiceSLATrend: {
+      trendList: [],
+    },
+  },
   effects: {
     *fetch({ payload }, { call, put }) {
+      const response = yield call(query, 'service', payload);
+      yield put({
+        type: 'save',
+        payload: response,
+      });
     },
   },
+
   reducers: {
     save(state, action) {
       return {
         ...state,
+        ...action.payload.data,
       };
     },
   },
 };
-
diff --git a/src/main/frontend/src/routes/Service/Service.js b/src/main/frontend/src/routes/Service/Service.js
index e459d54..4e4fdc5 100644
--- a/src/main/frontend/src/routes/Service/Service.js
+++ b/src/main/frontend/src/routes/Service/Service.js
@@ -1,76 +1,39 @@
-import React, { PureComponent } from 'react';
+import React, { Component } from 'react';
 import { connect } from 'dva';
-import { Row, Col, Select, Card, Tooltip, Icon, Table } from 'antd';
-import moment from 'moment';
+import { Row, Col, Select, Card } from 'antd';
 import {
   ChartCard, MiniArea, MiniBar,
 } from '../../components/Charts';
+import { timeRange } from '../../utils/utils';
+
+const { Option } = Select;
 
 @connect(state => ({
   service: state.service,
+  duration: state.global.duration,
 }))
-export default class Dashboard extends PureComponent {
-  render() {
-    const visitData = [];
-    const beginDay = new Date().getTime();
-
-    const fakeY = [7, 5, 4, 2, 4, 7, 5, 6, 5, 9, 6, 3, 1, 5, 3, 6, 5];
-    for (let i = 0; i < fakeY.length; i += 1) {
-      visitData.push({
-        x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'),
-        y: fakeY[i],
+export default class Service extends Component {
+  shouldComponentUpdate(nextProps) {
+    if (this.props.duration !== nextProps.duration) {
+      this.props.dispatch({
+        type: 'service/fetch',
+        payload: {},
       });
     }
-    function handleChange(value) {
-      console.log(`selected ${value}`);
-    }
-    function handleBlur() {
-      console.log('blur');
-    }
-
-    function handleFocus() {
-      console.log('focus');
-    }
-    const tableColumns = [{
-      title: 'Time',
-      dataIndex: 'time',
-      key: 'time',
-    }, {
-      title: 'Entry',
-      dataIndex: 'name',
-      key: 'name',
-    }, {
-      title: 'Duration',
-      dataIndex: 'duration',
-      key: 'duration',
-    }];
-    const { Option } = Select;
-    const slowServiceData = [{
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }];
+    return this.props.service !== nextProps.service;
+  }
+  handleChange(serviceId) {
+    this.props.dispatch({
+      type: 'service/fetch',
+      payload: { serviceId },
+    });
+  }
+  avg = list => (list.length > 0 ?
+    (list.reduce((acc, curr) => acc + curr) / list.length).toFixed(2) : 0)
+  render() {
+    const { getServiceResponseTimeTrend, getServiceTPSTrend,
+      getServiceSLATrend } = this.props.service;
+    const timeRangeArray = timeRange(this.props.duration);
     return (
       <div>
         <Select
@@ -78,81 +41,64 @@ export default class Dashboard extends PureComponent {
           style={{ width: 200 }}
           placeholder="Select a service"
           optionFilterProp="children"
-          onChange={handleChange}
-          onFocus={handleFocus}
-          onBlur={handleBlur}
+          onChange={this.handleChange.bind(this)}
         >
           <Option value="Service1">Service1</Option>
-          <Option value="Service1">Service1</Option>
-          <Option value="Service1">Service1</Option>
+          <Option value="Service2">Service2</Option>
+          <Option value="Service3">Service3</Option>
         </Select>
         <Row gutter={24}>
           <Col xs={24} sm={24} md={24} lg={8} xl={8} style={{ marginTop: 24 }}>
             <ChartCard
               title="Avg Throughout"
-              action={<Tooltip title="Tip"><Icon type="info-circle-o" /></Tooltip>}
-              total="500 tps"
+              total={`${this.avg(getServiceTPSTrend.trendList)}`}
             >
               <MiniArea
+                animate={false}
                 color="#975FE4"
                 height={46}
-                data={visitData}
+                data={getServiceTPSTrend.trendList
+                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
               />
             </ChartCard>
           </Col>
           <Col xs={24} sm={24} md={24} lg={8} xl={8} style={{ marginTop: 24 }}>
             <ChartCard
               title="Avg Response Time"
-              action={<Tooltip title="Tip"><Icon type="info-circle-o" /></Tooltip>}
-              total="300 ms"
+              total={`${this.avg(getServiceResponseTimeTrend.trendList)} ms`}
             >
               <MiniArea
-                color="#975FE4"
+                animate={false}
                 height={46}
-                data={visitData}
+                data={getServiceResponseTimeTrend.trendList
+                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
               />
             </ChartCard>
           </Col>
           <Col xs={24} sm={24} md={24} lg={8} xl={8} style={{ marginTop: 24 }}>
             <ChartCard
               title="Avg SLA"
-              action={<Tooltip title="Tip"><Icon type="info-circle-o" /></Tooltip>}
-              total="95.5%"
+              total={`${this.avg(getServiceSLATrend.trendList)} %`}
             >
               <MiniBar
+                animate={false}
                 height={46}
-                data={visitData}
+                data={getServiceSLATrend.trendList
+                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
               />
             </ChartCard>
           </Col>
         </Row>
         <Row gutter={24}>
-          <Col xs={24} sm={24} md={24} lg={16} xl={16} style={{ marginTop: 24 }}>
+          <Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: 24 }}>
             <Card
               bordered={false}
               bodyStyle={{ padding: 0 }}
             >
-              <div Style="height: 430px">The toplogy of service dependencies</div>
-            </Card>
-          </Col>
-          <Col xs={24} sm={24} md={24} lg={8} xl={8} style={{ marginTop: 24 }}>
-            <Card
-              title="Slow Trace"
-              bordered={false}
-              bodyStyle={{ padding: 0 }}
-            >
-              <Table
-                columns={tableColumns}
-                dataSource={slowServiceData}
-                pagination={{
-                  style: { marginBottom: 0 },
-                  pageSize: 5,
-                }}
-              />
+              <div style={{ height: 430 }}>The toplogy of service dependencies</div>
             </Card>
           </Col>
         </Row>
-
       </div>
     );
   }

-- 
To stop receiving notification emails like this one, please contact
"commits@skywalking.apache.org" <co...@skywalking.apache.org>.

[incubator-skywalking-ui] 03/05: Fetching server data

Posted by ha...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch feature/5.0.0
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git

commit 7682d98a204e119c25d97b9a9574113ee5444c2c
Author: gaohongtao <ha...@gmail.com>
AuthorDate: Mon Jan 8 23:16:56 2018 +0800

    Fetching server data
---
 src/main/frontend/.roadhogrc.mock.js          |  29 +++++-
 src/main/frontend/src/models/server.js        |  35 +++++++-
 src/main/frontend/src/routes/Server/Server.js | 121 +++++++++-----------------
 3 files changed, 102 insertions(+), 83 deletions(-)

diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index 2efbc0e..7b4c343 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -20,10 +20,10 @@ const proxy = mockjs.mock({
         'numOfMQ|1-100': 1,
       },
       getAlarmTrend: {
-        'numOfAlarmRate|5': [5, 3, 2,],
+        'numOfAlarmRate|15': ['@natural(0, 99)'],
       },
       getConjecturalApps: {
-        'apps|3-5': [{'name|1':['Oracle', 'MySQL', 'ActiveMQ', 'Redis', 'Memcache', 'SQLServer'], 'num|1-20':10}],
+        'apps|3-5': [{'name|1':['Oracle', 'MySQL', 'ActiveMQ', 'Redis', 'Memcache', 'SQLServer'], 'num':'@natural(1, 20)'}],
       },
       'getTopNSlowService|10': [{'key|+1': 1, 'name': '@name', 'avgResponseTime|200-1000': 1}],
       'getTopNServerThroughput|10': [{'key|+1': 1, 'name': '@name', 'tps|100-10000': 1}],
@@ -35,6 +35,31 @@ const proxy = mockjs.mock({
       'getServerThroughput|10': [{'key|+1': 1, 'name': '@name', 'tps|100-10000': 1}],
     }
   },
+
+  'POST /api/server': {
+    data: {
+      'searchServer|5': [{}],
+      getServerResponseTimeTrend: {
+        'trendList|15': ['@natural(100, 1000)'],
+      },
+      getServerTPSTrend: {
+        'trendList|15': ['@natural(500, 10000)'],
+      },
+      getCPUTrend: {
+        'cost|15': ['@natural(0, 99)'],
+      },
+      getMemoryTrend: {
+        'heap|15': ['@natural(500, 900)'],
+        'maxHeap|15': ['@natural(900, 2000)'],
+        'noheap|15': ['@natural(100, 200)'],
+        'maxNoheap|15': ['@natural(200, 300)'],
+      },
+      getGCTrend: {
+        'youngGC|15': ['@natural(200, 300)'],
+        'oldGC|15': ['@natural(10,100)'],
+      },
+    }
+  },
 });
 
 export default noProxy ? {} : delay(proxy, 1000);
diff --git a/src/main/frontend/src/models/server.js b/src/main/frontend/src/models/server.js
index 241cd05..8f13809 100644
--- a/src/main/frontend/src/models/server.js
+++ b/src/main/frontend/src/models/server.js
@@ -1,15 +1,44 @@
-// import { xxx } from '../services/xxx';
+import { query } from '../services/graphql';
+
 export default {
-  namespace: "server",
-  state: {},
+  namespace: 'server',
+  state: {
+    searchServer: [],
+    getServerResponseTimeTrend: {
+      trendList: [],
+    },
+    getServerTPSTrend: {
+      trendList: [],
+    },
+    getCPUTrend: {
+      cost: [],
+    },
+    getMemoryTrend: {
+      heap: [],
+      maxHeap: [],
+      noheap: [],
+      maxNoheap: [],
+    },
+    getGCTrend: {
+      youngGC: [],
+      oldGC: [],
+    },
+  },
   effects: {
     *fetch({ payload }, { call, put }) {
+      const response = yield call(query, 'server', payload);
+      yield put({
+        type: 'save',
+        payload: response,
+      });
     },
   },
+
   reducers: {
     save(state, action) {
       return {
         ...state,
+        ...action.payload.data,
       };
     },
   },
diff --git a/src/main/frontend/src/routes/Server/Server.js b/src/main/frontend/src/routes/Server/Server.js
index 707fe8f..824be0e 100644
--- a/src/main/frontend/src/routes/Server/Server.js
+++ b/src/main/frontend/src/routes/Server/Server.js
@@ -1,79 +1,41 @@
-import React, { PureComponent } from 'react';
+import React, { Component } from 'react';
 import { connect } from 'dva';
-import { Row, Col, Select, Card, Tooltip, Icon, Table } from 'antd';
-import moment from 'moment';
+import { Row, Col, Select, Card } from 'antd';
 import {
   ChartCard, MiniArea, MiniBar, Line,
 } from '../../components/Charts';
 import DescriptionList from '../../components/DescriptionList';
+import { timeRange } from '../../utils/utils';
 
 const { Description } = DescriptionList;
+const { Option } = Select;
 
 @connect(state => ({
-  service: state.service,
+  server: state.server,
+  duration: state.global.duration,
 }))
-export default class Dashboard extends PureComponent {
-  render() {
-    const visitData = [];
-    const beginDay = new Date().getTime();
-
-    const fakeY = [7, 5, 4, 2, 4, 7, 5, 6, 5, 9, 6, 3, 1, 5, 3, 6, 5];
-    for (let i = 0; i < fakeY.length; i += 1) {
-      visitData.push({
-        x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'),
-        y: fakeY[i],
+export default class Server extends Component {
+  shouldComponentUpdate(nextProps) {
+    if (this.props.duration !== nextProps.duration) {
+      this.props.dispatch({
+        type: 'server/fetch',
+        payload: {},
       });
     }
-    function handleChange(value) {
-      console.log(`selected ${value}`);
-    }
-    function handleBlur() {
-      console.log('blur');
-    }
-
-    function handleFocus() {
-      console.log('focus');
-    }
-    const tableColumns = [{
-      title: 'Time',
-      dataIndex: 'time',
-      key: 'time',
-    }, {
-      title: 'Entry',
-      dataIndex: 'name',
-      key: 'name',
-    }, {
-      title: 'Duration',
-      dataIndex: 'duration',
-      key: 'duration',
-    }];
-    const { Option } = Select;
-    const slowServiceData = [{
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }];
+    return this.props.server !== nextProps.server;
+  }
+  handleChange(serverId) {
+    this.props.dispatch({
+      type: 'server/fetch',
+      payload: { serverId },
+    });
+  }
+  avg = list => (list.length > 0 ?
+    (list.reduce((acc, curr) => acc + curr) / list.length).toFixed(2) : 0)
+  render() {
+    const { getServerResponseTimeTrend, getServerTPSTrend,
+      getCPUTrend, getMemoryTrend, getGCTrend } = this.props.server;
+    const timeRangeArray = timeRange(this.props.duration);
     return (
       <div>
         <Select
@@ -81,13 +43,11 @@ export default class Dashboard extends PureComponent {
           style={{ width: 200 }}
           placeholder="Select a server"
           optionFilterProp="children"
-          onChange={handleChange}
-          onFocus={handleFocus}
-          onBlur={handleBlur}
+          onChange={this.handleChange.bind(this)}
         >
           <Option value="Server1">Server1</Option>
-          <Option value="Server1">Server1</Option>
-          <Option value="Server1">Server1</Option>
+          <Option value="Server2">Server2</Option>
+          <Option value="Server3">Server3</Option>
         </Select>
         <Card title="Info" style={{ marginTop: 24 }} bordered={false}>
           <DescriptionList>
@@ -101,25 +61,27 @@ export default class Dashboard extends PureComponent {
           <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
             <ChartCard
               title="Avg Response Time"
-              action={<Tooltip title="Tip"><Icon type="info-circle-o" /></Tooltip>}
-              total="300 ms"
+              total={`${this.avg(getServerResponseTimeTrend.trendList)} ms`}
             >
               <MiniArea
+                animate={false}
                 color="#975FE4"
                 height={46}
-                data={visitData}
+                data={getServerResponseTimeTrend.trendList
+                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
               />
             </ChartCard>
           </Col>
           <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
             <ChartCard
               title="Avg TPS"
-              action={<Tooltip title="Tip"><Icon type="info-circle-o" /></Tooltip>}
-              total="500"
+              total={`${this.avg(getServerTPSTrend.trendList)} ms`}
             >
               <MiniBar
+                animate={false}
                 height={46}
-                data={visitData}
+                data={getServerTPSTrend.trendList
+                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
               />
             </ChartCard>
           </Col>
@@ -133,7 +95,8 @@ export default class Dashboard extends PureComponent {
             >
               <Line
                 height={250}
-                data={visitData}
+                data={getCPUTrend.cost
+                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
               />
             </Card>
           </Col>
@@ -147,7 +110,8 @@ export default class Dashboard extends PureComponent {
             >
               <Line
                 height={250}
-                data={visitData}
+                data={getMemoryTrend.heap
+                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
               />
             </Card>
           </Col>
@@ -161,7 +125,8 @@ export default class Dashboard extends PureComponent {
             >
               <Line
                 height={250}
-                data={visitData}
+                data={getGCTrend.youngGC
+                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
               />
             </Card>
           </Col>

-- 
To stop receiving notification emails like this one, please contact
"commits@skywalking.apache.org" <co...@skywalking.apache.org>.

[incubator-skywalking-ui] 05/05: Fetching alarm data

Posted by ha...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch feature/5.0.0
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git

commit 354beb9b0a87bbce37e7d4bd77dac8ee4a818d31
Author: gaohongtao <ha...@gmail.com>
AuthorDate: Tue Jan 9 00:13:18 2018 +0800

    Fetching alarm data
---
 src/main/frontend/.roadhogrc.mock.js        |  5 +++
 src/main/frontend/src/models/alert.js       | 17 ++++++--
 src/main/frontend/src/routes/Alert/Alert.js | 67 ++++++++++++-----------------
 3 files changed, 46 insertions(+), 43 deletions(-)

diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index d25ea2d..8097007 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -73,6 +73,11 @@ const proxy = mockjs.mock({
       },
     }
   },
+  'POST /api/alert': {
+    data: {
+      'loadAlertList|100': [{'key|+1': 1, 'content':'@string(20)', 'startTime': '@datetime("yyyy-MM-dd HH:mm:ss")', 'alertType|1': ['APPLICATION', 'SERVER', 'SERVICE']}],
+    }
+  },
 });
 
 export default noProxy ? {} : delay(proxy, 1000);
diff --git a/src/main/frontend/src/models/alert.js b/src/main/frontend/src/models/alert.js
index ccd3380..c0a919b 100644
--- a/src/main/frontend/src/models/alert.js
+++ b/src/main/frontend/src/models/alert.js
@@ -1,17 +1,26 @@
-// import { xxx } from '../services/xxx';
+import { query } from '../services/graphql';
+
 export default {
-  namespace: "alert",
-  state: {},
+  namespace: 'alert',
+  state: {
+    loadAlertList: [],
+  },
   effects: {
     *fetch({ payload }, { call, put }) {
+      const response = yield call(query, 'alert', payload);
+      yield put({
+        type: 'save',
+        payload: response,
+      });
     },
   },
+
   reducers: {
     save(state, action) {
       return {
         ...state,
+        ...action.payload.data,
       };
     },
   },
 };
-
diff --git a/src/main/frontend/src/routes/Alert/Alert.js b/src/main/frontend/src/routes/Alert/Alert.js
index 34ea5b3..ba2d3b5 100644
--- a/src/main/frontend/src/routes/Alert/Alert.js
+++ b/src/main/frontend/src/routes/Alert/Alert.js
@@ -1,4 +1,4 @@
-import React, { PureComponent } from 'react';
+import React, { Component } from 'react';
 import { connect } from 'dva';
 import { Card, Table, Input } from 'antd';
 import styles from './Alert.less';
@@ -7,58 +7,47 @@ const { Search } = Input;
 
 @connect(state => ({
   alert: state.alert,
+  duration: state.global.duration,
 }))
-export default class Alert extends PureComponent {
+export default class Alert extends Component {
+  componentDidMount() {
+    this.props.dispatch({
+      type: 'alert/fetch',
+      payload: {},
+    });
+  }
+  shouldComponentUpdate(nextProps) {
+    if (this.props.duration !== nextProps.duration) {
+      this.props.dispatch({
+        type: 'alert/fetch',
+        payload: {},
+      });
+    }
+    return this.props.alert !== nextProps.alert;
+  }
   render() {
     const columns = [{
       title: 'Content',
       dataIndex: 'content',
     }, {
       title: 'Start Time',
-      dataIndex: 'time',
+      dataIndex: 'startTime',
     }, {
       title: 'Alert Type',
-      dataIndex: 'type',
+      dataIndex: 'alertType',
       filters: [{
-        text: 'Application',
-        value: 'Application',
+        text: 'APPLICATION',
+        value: 'APPLICATION',
       }, {
-        text: 'Server',
-        value: 'Server',
+        text: 'SERVER',
+        value: 'SERVER',
       }, {
-        text: 'Service',
-        value: 'Service',
+        text: 'SERVICE',
+        value: 'SERVICE',
       }],
       filterMultiple: false,
-      onFilter: (value, record) => record.type.indexOf(value) === 0,
+      onFilter: (value, record) => record.alertType.indexOf(value) === 0,
     }];
-
-    const data = [{
-      key: '1',
-      content: 'Application alert',
-      time: '19:30',
-      type: 'Application',
-    }, {
-      key: '2',
-      content: 'Server is down',
-      time: '13:30',
-      type: 'Server',
-    }, {
-      key: '3',
-      content: 'Server is slow',
-      time: '8:30',
-      type: 'Service',
-    }, {
-      key: '4',
-      content: 'Service sla is low',
-      time: '3:30',
-      type: 'Service',
-    }];
-
-    function onChange(pagination, filters, sorter) {
-      console.log('params', pagination, filters, sorter);
-    }
-
     const extraContent = (
       <div className={styles.extraContent}>
         <Search
@@ -76,7 +65,7 @@ export default class Alert extends PureComponent {
         extra={extraContent}
       >
         <div className={styles.tableList}>
-          <Table columns={columns} dataSource={data} onChange={onChange} />
+          <Table columns={columns} dataSource={this.props.alert.loadAlertList} />
         </div>
       </Card>
     );

-- 
To stop receiving notification emails like this one, please contact
"commits@skywalking.apache.org" <co...@skywalking.apache.org>.

[incubator-skywalking-ui] 01/05: Fetching dashboard data

Posted by ha...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch feature/5.0.0
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git

commit 5a20076f3e095619c0e29fc46ed3293b7b0bc17e
Author: gaohongtao <ha...@gmail.com>
AuthorDate: Mon Jan 8 21:16:17 2018 +0800

    Fetching dashboard data
---
 src/main/frontend/.roadhogrc.mock.js               |  60 ++----
 src/main/frontend/src/models/dashboard.js          |  28 ++-
 .../frontend/src/routes/Dashboard/Dashboard.js     | 205 ++++++++-------------
 src/main/frontend/src/services/graphql.js          |   8 +
 src/main/frontend/src/utils/request.js             |   8 +-
 src/main/frontend/src/utils/utils.js               |   4 +
 6 files changed, 134 insertions(+), 179 deletions(-)

diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index 11cfdbc..e85899f 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -8,51 +8,27 @@ import { delay } from 'roadhog-api-doc';
 const noProxy = process.env.NO_PROXY === 'true';
 
 // 代码中会兼容本地 service mock 以及部署站点的静态数据
-const proxy = {
+const proxy = mockjs.mock({
   // 支持值为 Object 和 Array
-  'GET /api/currentUser': {
-    $desc: "获取当前用户接口",
-    $params: {
-      pageSize: {
-        desc: '分页',
-        exp: 2,
+  'POST /api/dashboard': {
+    data: {
+      getClusterBrief: {
+        'numOfApplication|1-100': 1,
+        'numOfService|1-100': 1,
+        'numOfDatabase|1-100': 1,
+        'numOfCache|1-100': 1,
+        'numOfMQ|1-100': 1,
       },
-    },
-    $body: {
-      name: 'Serati Ma',
-      avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dRFVcIqZOYPcSNrlJsqQ.png',
-      userid: '00000001',
-      notifyCount: 12,
-    },
-  },
-  // GET POST 可省略
-  'GET /api/users': [{
-    key: '1',
-    name: 'John Brown',
-    age: 32,
-    address: 'New York No. 1 Lake Park',
-  }, {
-    key: '2',
-    name: 'Jim Green',
-    age: 42,
-    address: 'London No. 1 Lake Park',
-  }, {
-    key: '3',
-    name: 'Joe Black',
-    age: 32,
-    address: 'Sidney No. 1 Lake Park',
-  }],
-  'GET /api/rule': getRule,
-  'POST /api/rule': {
-    $params: {
-      pageSize: {
-        desc: '分页',
-        exp: 2,
+      getAlarmTrend: {
+        'numOfAlarmRate|5': [5, 3, 2,],
+      },
+      getConjecturalApps: {
+        'apps|3-5': [{'name|1':['Oracle', 'MySQL', 'ActiveMQ', 'Redis', 'Memcache', 'SQLServer'], 'num|1-20':10}],
       },
-    },
-    $body: postRule,
+      'getTopNSlowService|10': [{'key|+1': 1, 'name': '@name', 'avgResponseTime|200-1000': 1}],
+      'getTopNServerThroughput|10': [{'key|+1': 1, 'name': '@name', 'tps|100-10000': 1}],
+    }
   },
-  'GET /api/notices': getNotices,
-};
+});
 
 export default noProxy ? {} : delay(proxy, 1000);
diff --git a/src/main/frontend/src/models/dashboard.js b/src/main/frontend/src/models/dashboard.js
index 2e1190a..0796d23 100644
--- a/src/main/frontend/src/models/dashboard.js
+++ b/src/main/frontend/src/models/dashboard.js
@@ -1,15 +1,39 @@
-// import { xxx } from '../services/xxx';
+import { query } from '../services/graphql';
+
 export default {
   namespace: 'dashboard',
-  state: {},
+  state: {
+    getClusterBrief: {
+      numOfApplication: 0,
+      numOfService: 0,
+      numOfDatabase: 0,
+      numOfCache: 0,
+      numOfMQ: 0,
+    },
+    getAlarmTrend: {
+      numOfAlarmRate: [],
+    },
+    getConjecturalApps: {
+      apps: [],
+    },
+    getTopNSlowService: [],
+    getTopNServerThroughput: [],
+  },
   effects: {
     *fetch({ payload }, { call, put }) {
+      const response = yield call(query, 'dashboard', payload);
+      yield put({
+        type: 'save',
+        payload: response,
+      });
     },
   },
+
   reducers: {
     save(state, action) {
       return {
         ...state,
+        ...action.payload.data,
       };
     },
   },
diff --git a/src/main/frontend/src/routes/Dashboard/Dashboard.js b/src/main/frontend/src/routes/Dashboard/Dashboard.js
index 896c9b6..3400e24 100644
--- a/src/main/frontend/src/routes/Dashboard/Dashboard.js
+++ b/src/main/frontend/src/routes/Dashboard/Dashboard.js
@@ -1,79 +1,53 @@
-import React, { PureComponent } from 'react';
+import React, { Component } from 'react';
 import { connect } from 'dva';
-import { Row, Col, Icon, Tooltip, Card, Table } from 'antd';
-import moment from 'moment';
+import { Row, Col, Card, Table } from 'antd';
 import {
   ChartCard, Pie, MiniArea, Field,
 } from '../../components/Charts';
+import { timeRange } from '../../utils/utils';
 
 @connect(state => ({
   dashboard: state.dashboard,
+  duration: state.global.duration,
 }))
-export default class Dashboard extends PureComponent {
+export default class Dashboard extends Component {
+  componentDidMount() {
+    this.props.dispatch({
+      type: 'dashboard/fetch',
+      payload: {},
+    });
+  }
+  shouldComponentUpdate(nextProps) {
+    if (this.props.duration !== nextProps.duration) {
+      this.props.dispatch({
+        type: 'dashboard/fetch',
+        payload: {},
+      });
+    }
+    return this.props.dashboard !== nextProps.dashboard;
+  }
   render() {
     const visitData = [];
-    const beginDay = new Date().getTime();
-
-    const fakeY = [7, 5, 4, 2, 4, 7, 5, 6, 5, 9, 6, 3, 1, 5, 3, 6, 5];
-    for (let i = 0; i < fakeY.length; i += 1) {
-      visitData.push({
-        x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'),
-        y: fakeY[i],
+    const { numOfAlarmRate } = this.props.dashboard.getAlarmTrend;
+    let avg = 0;
+    let max = 0;
+    let min = 0;
+    if (numOfAlarmRate && numOfAlarmRate.length > 0) {
+      timeRange(this.props.duration).forEach((v, i) => {
+        visitData.push({ x: v, y: numOfAlarmRate[i] });
       });
+      avg = numOfAlarmRate.reduce((acc, curr) => acc + curr) / numOfAlarmRate.length;
+      max = numOfAlarmRate.reduce((acc, curr) => { return acc < curr ? curr : acc; });
+      min = numOfAlarmRate.reduce((acc, curr) => { return acc > curr ? curr : acc; });
     }
-    const databasePieData = [
-      {
-        x: 'MySQL',
-        y: 10,
-      },
-      {
-        x: 'Oracle',
-        y: 7,
-      },
-      {
-        x: 'SQLServer',
-        y: 3,
-      },
-    ];
     const tableColumns = [{
-      title: 'Time',
-      dataIndex: 'time',
-      key: 'time',
-    }, {
       title: 'Name',
       dataIndex: 'name',
       key: 'name',
     }, {
-      title: 'Duration',
-      dataIndex: 'duration',
-      key: 'duration',
-    }];
-
-    const slowServiceData = [{
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '2',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '3',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '4',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '5',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
+      title: 'Response Time',
+      dataIndex: 'avgResponseTime',
+      key: 'avgResponseTime',
     }];
 
     const applicationThroughputColumns = [{
@@ -85,101 +59,59 @@ export default class Dashboard extends PureComponent {
       dataIndex: 'tps',
       key: 'tps',
     }];
-
-    const applicationThroughputData = [{
-      key: '1',
-      name: 'App1',
-      tps: '500',
-    }, {
-      key: '2',
-      name: 'App1',
-      tps: '500',
-    }, {
-      key: '3',
-      name: 'App1',
-      tps: '500',
-    }, {
-      key: '4',
-      name: 'App1',
-      tps: '500',
-    }, {
-      key: '5',
-      name: 'App1',
-      tps: '500',
-    }];
-
-    const topColResponsiveProps = {
-      xs: 24,
-      sm: 12,
-      md: 12,
-      lg: 6,
-      xl: 6,
-      style: { marginBottom: 24 },
-    };
-    const middleColResponsiveProps = {
-      xs: 24,
-      sm: 24,
-      md: 24,
-      lg: 8,
-      xl: 8,
-      style: { marginBottom: 24, marginTop: 24 },
-    };
     return (
       <div>
         <Row gutter={24}>
-          <Col {...topColResponsiveProps}>
+          <Col xs={24} sm={24} md={12} lg={6} xl={6}>
             <ChartCard
-              title="Total Application"
+              title="App"
               avatar={<img style={{ width: 56, height: 56 }} src="app.svg" alt="app" />}
-              action={<Tooltip title="Tip"><Icon type="info-circle-o" /></Tooltip>}
-              total={25}
+              total={this.props.dashboard.getClusterBrief.numOfApplication}
             />
           </Col>
-          <Col {...topColResponsiveProps}>
+          <Col xs={24} sm={24} md={12} lg={6} xl={6}>
             <ChartCard
-              title="Total Service"
+              title="Service"
               avatar={<img style={{ width: 56, height: 56 }} src="service.svg" alt="service" />}
-              action={<Tooltip title="Tip"><Icon type="info-circle-o" /></Tooltip>}
-              total={525}
+              total={this.props.dashboard.getClusterBrief.numOfService}
             />
           </Col>
-          <Col {...topColResponsiveProps}>
+          <Col xs={24} sm={24} md={12} lg={6} xl={6}>
             <ChartCard
-              title="Total Database"
-              avatar={<img style={{ width: 56, height: 56 }} src="database.svg" alt="database" />}
-              action={<Tooltip title="Tip"><Icon type="info-circle-o" /></Tooltip>}
-              total={18}
+              title="Store"
+              avatar={<img style={{ width: 48, height: 56 }} src="database.svg" alt="database" />}
+              total={this.props.dashboard.getClusterBrief.numOfDatabase
+                + this.props.dashboard.getClusterBrief.numOfCache}
             />
           </Col>
-          <Col {...topColResponsiveProps}>
+          <Col xs={24} sm={24} md={12} lg={6} xl={6}>
             <ChartCard
-              title="Total Cache"
+              title="MQ"
               avatar={<img style={{ width: 56, height: 56 }} src="redis.svg" alt="redis" />}
-              action={<Tooltip title="Tip"><Icon type="info-circle-o" /></Tooltip>}
-              total={5}
+              total={this.props.dashboard.getClusterBrief.numOfMQ}
             />
           </Col>
         </Row>
         <Card
           bordered={false}
-          bodyStyle={{ padding: 0 }}
+          bodyStyle={{ padding: 0, marginTop: 24 }}
         >
           <div style={{ height: 480 }}>Topoloy</div>
         </Card>
         <Row gutter={24}>
-          <Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: 24 }}>
+          <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
             <ChartCard
-              title="Avg Application Alert"
+              title="Avg Application Alarm"
               avatar={<img style={{ width: 56, height: 56 }} src="alert.svg" alt="app" />}
-              action={<Tooltip title="Tip"><Icon type="info-circle-o" /></Tooltip>}
-              total="5%"
-              footer={<div><Field label="Max" value="10%" /> <Field label="Min" value="2%" /></div>}
+              total={`${avg.toFixed(2)}%`}
+              footer={<div><Field label="Max" value={`${max}%`} /> <Field label="Min" value={`${min}%`} /></div>}
             >
               <MiniArea
+                animate={false}
                 color="#D87093"
                 borderColor="#B22222"
                 line="true"
-                height={96}
+                height={143}
                 data={visitData}
                 yAxis={{
                   formatter(val) {
@@ -189,49 +121,58 @@ export default class Dashboard extends PureComponent {
               />
             </ChartCard>
           </Col>
-        </Row>
-        <Row gutter={24}>
-          <Col {...middleColResponsiveProps}>
+          <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
             <Card
               bordered={false}
               bodyStyle={{ padding: 0 }}
             >
               <Pie
+                animate={false}
                 hasLegend
                 title="Database"
                 subTitle="Total"
-                total={databasePieData.reduce((pre, now) => now.y + pre, 0)}
-                data={databasePieData}
+                total={this.props.dashboard.getConjecturalApps.apps
+                  .reduce((pre, now) => now.num + pre, 0)}
+                data={this.props.dashboard.getConjecturalApps.apps
+                  .map((v) => { return { x: v.name, y: v.num }; })}
                 height={300}
                 lineWidth={4}
               />
             </Card>
           </Col>
-          <Col {...middleColResponsiveProps}>
+        </Row>
+        <Row gutter={24}>
+          <Col xs={24} sm={24} md={24} lg={16} xl={16} style={{ marginTop: 24 }}>
             <Card
               title="Slow Service"
               bordered={false}
               bodyStyle={{ padding: 0 }}
             >
               <Table
+                size="small"
                 columns={tableColumns}
-                dataSource={slowServiceData}
+                dataSource={this.props.dashboard.getTopNSlowService}
                 pagination={{
                   style: { marginBottom: 0 },
-                  pageSize: 5,
+                  pageSize: 10,
                 }}
               />
             </Card>
           </Col>
-          <Col {...middleColResponsiveProps}>
+          <Col xs={24} sm={24} md={24} lg={8} xl={8} style={{ marginTop: 24 }}>
             <Card
               title="Application Throughput"
               bordered={false}
               bodyStyle={{ padding: 0 }}
             >
               <Table
+                size="small"
                 columns={applicationThroughputColumns}
-                dataSource={applicationThroughputData}
+                dataSource={this.props.dashboard.getTopNServerThroughput}
+                pagination={{
+                  style: { marginBottom: 0 },
+                  pageSize: 10,
+                }}
               />
             </Card>
           </Col>
diff --git a/src/main/frontend/src/services/graphql.js b/src/main/frontend/src/services/graphql.js
new file mode 100644
index 0000000..1201019
--- /dev/null
+++ b/src/main/frontend/src/services/graphql.js
@@ -0,0 +1,8 @@
+import request from '../utils/request';
+
+export async function query(namespace, playload) {
+  return request(`/api/${namespace}`, {
+    method: 'POST',
+    body: playload,
+  });
+}
diff --git a/src/main/frontend/src/utils/request.js b/src/main/frontend/src/utils/request.js
index 094f7fc..6f83dbf 100644
--- a/src/main/frontend/src/utils/request.js
+++ b/src/main/frontend/src/utils/request.js
@@ -6,7 +6,7 @@ function checkStatus(response) {
     return response;
   }
   notification.error({
-    message: `请求错误 ${response.status}: ${response.url}`,
+    message: `Request error ${response.status}: ${response.url}`,
     description: response.statusText,
   });
   const error = new Error(response.statusText);
@@ -37,7 +37,9 @@ export default function request(url, options) {
 
   return fetch(url, newOptions)
     .then(checkStatus)
-    .then(response => response.json())
+    .then((response) => {
+      return response.json();
+    })
     .catch((error) => {
       if (error.code) {
         notification.error({
@@ -47,7 +49,7 @@ export default function request(url, options) {
       }
       if ('stack' in error && 'message' in error) {
         notification.error({
-          message: `请求错误: ${url}`,
+          message: `Request error: ${url}`,
           description: error.message,
         });
       }
diff --git a/src/main/frontend/src/utils/utils.js b/src/main/frontend/src/utils/utils.js
index e0dfd71..e4060a1 100644
--- a/src/main/frontend/src/utils/utils.js
+++ b/src/main/frontend/src/utils/utils.js
@@ -92,3 +92,7 @@ export function digitUppercase(n) {
 
   return s.replace(/(零.)*零元/, '元').replace(/(零.)+/g, '零').replace(/^整$/, '零元整');
 }
+
+export function timeRange(duration) {
+  return Array(15).fill(0).map((v, i) => moment().subtract(i, 'minutes').format('YYYY-MM-DD HH:mm:ss'));
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@skywalking.apache.org" <co...@skywalking.apache.org>.

[incubator-skywalking-ui] 02/05: Fetching application data

Posted by ha...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch feature/5.0.0
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git

commit a62a3683e40df3caa974c8a30e072c7ce1b48267
Author: gaohongtao <ha...@gmail.com>
AuthorDate: Mon Jan 8 22:03:43 2018 +0800

    Fetching application data
---
 src/main/frontend/.roadhogrc.mock.js               |   6 ++
 src/main/frontend/src/models/application.js        |  18 +++-
 .../frontend/src/routes/Application/Application.js | 103 +++++++--------------
 3 files changed, 53 insertions(+), 74 deletions(-)

diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index e85899f..2efbc0e 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -29,6 +29,12 @@ const proxy = mockjs.mock({
       'getTopNServerThroughput|10': [{'key|+1': 1, 'name': '@name', 'tps|100-10000': 1}],
     }
   },
+  'POST /api/application': {
+    data: {
+      'getSlowService|10': [{'key|+1': 1, 'name': '@name', 'avgResponseTime|200-1000': 1}],
+      'getServerThroughput|10': [{'key|+1': 1, 'name': '@name', 'tps|100-10000': 1}],
+    }
+  },
 });
 
 export default noProxy ? {} : delay(proxy, 1000);
diff --git a/src/main/frontend/src/models/application.js b/src/main/frontend/src/models/application.js
index 2e1190a..d537e4a 100644
--- a/src/main/frontend/src/models/application.js
+++ b/src/main/frontend/src/models/application.js
@@ -1,15 +1,27 @@
-// import { xxx } from '../services/xxx';
+import { query } from '../services/graphql';
+
 export default {
-  namespace: 'dashboard',
-  state: {},
+  namespace: 'application',
+  state: {
+    getAllApplication: [],
+    getSlowService: [],
+    getServerThroughput: [],
+  },
   effects: {
     *fetch({ payload }, { call, put }) {
+      const response = yield call(query, 'application', payload);
+      yield put({
+        type: 'save',
+        payload: response,
+      });
     },
   },
+
   reducers: {
     save(state, action) {
       return {
         ...state,
+        ...action.payload.data,
       };
     },
   },
diff --git a/src/main/frontend/src/routes/Application/Application.js b/src/main/frontend/src/routes/Application/Application.js
index b316724..2beb24b 100644
--- a/src/main/frontend/src/routes/Application/Application.js
+++ b/src/main/frontend/src/routes/Application/Application.js
@@ -1,57 +1,38 @@
-import React, { PureComponent } from 'react';
+import React, { Component } from 'react';
 import { connect } from 'dva';
 import { Row, Col, Select, Card, Table } from 'antd';
 
+const { Option } = Select;
+
 @connect(state => ({
   application: state.application,
+  duration: state.global.duration,
 }))
-export default class Dashboard extends PureComponent {
-  render() {
-    function handleChange(value) {
-      console.log(`selected ${value}`);
-    }
-    function handleBlur() {
-      console.log('blur');
-    }
-
-    function handleFocus() {
-      console.log('focus');
+export default class Application extends Component {
+  shouldComponentUpdate(nextProps) {
+    if (this.props.duration !== nextProps.duration) {
+      this.props.dispatch({
+        type: 'application/fetch',
+        payload: {},
+      });
     }
+    return this.props.application !== nextProps.application;
+  }
+  handleChange(appId) {
+    this.props.dispatch({
+      type: 'application/fetch',
+      payload: { applicationId: appId },
+    });
+  }
+  render() {
     const tableColumns = [{
       title: 'Name',
       dataIndex: 'name',
       key: 'name',
     }, {
       title: 'Duration',
-      dataIndex: 'duration',
-      key: 'duration',
-    }];
-    const { Option } = Select;
-    const slowServiceData = [{
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
-    }, {
-      key: '1',
-      name: 'ServiceA',
-      time: '2017/12/11 19:22:32',
-      duration: '5000ms',
+      dataIndex: 'avgResponseTime',
+      key: 'avgResponseTime',
     }];
 
     const applicationThroughputColumns = [{
@@ -64,28 +45,6 @@ export default class Dashboard extends PureComponent {
       key: 'tps',
     }];
 
-    const applicationThroughputData = [{
-      key: '1',
-      name: 'Server1',
-      tps: '500',
-    }, {
-      key: '1',
-      name: 'Server1',
-      tps: '500',
-    }, {
-      key: '1',
-      name: 'Server1',
-      tps: '500',
-    }, {
-      key: '1',
-      name: 'Server1',
-      tps: '500',
-    }, {
-      key: '1',
-      name: 'Server1',
-      tps: '500',
-    }];
-
     const middleColResponsiveProps = {
       xs: 24,
       sm: 24,
@@ -101,9 +60,7 @@ export default class Dashboard extends PureComponent {
           style={{ width: 200 }}
           placeholder="Select a application"
           optionFilterProp="children"
-          onChange={handleChange}
-          onFocus={handleFocus}
-          onBlur={handleBlur}
+          onChange={this.handleChange.bind(this)}
         >
           <Option value="App1">App1</Option>
           <Option value="App2">App2</Option>
@@ -113,7 +70,9 @@ export default class Dashboard extends PureComponent {
           bordered={false}
           bodyStyle={{ padding: 0, marginTop: 24 }}
         >
-          <div Style="height: 400px">Application and externel resources(Db, Cache or MQ) Topoloy</div>
+          <div style={{ height: 400 }}>
+              Application and externel resources(Db, Cache or MQ) Topoloy
+          </div>
         </Card>
         <Row gutter={24}>
           <Col {...middleColResponsiveProps}>
@@ -123,11 +82,12 @@ export default class Dashboard extends PureComponent {
               bodyStyle={{ padding: 0 }}
             >
               <Table
+                size="small"
                 columns={tableColumns}
-                dataSource={slowServiceData}
+                dataSource={this.props.application.getSlowService}
                 pagination={{
                   style: { marginBottom: 0 },
-                  pageSize: 5,
+                  pageSize: 10,
                 }}
               />
             </Card>
@@ -139,11 +99,12 @@ export default class Dashboard extends PureComponent {
               bodyStyle={{ padding: 0 }}
             >
               <Table
+                size="small"
                 columns={applicationThroughputColumns}
-                dataSource={applicationThroughputData}
+                dataSource={this.props.application.getServerThroughput}
                 pagination={{
                   style: { marginBottom: 0 },
-                  pageSize: 5,
+                  pageSize: 10,
                 }}
               />
             </Card>

-- 
To stop receiving notification emails like this one, please contact
"commits@skywalking.apache.org" <co...@skywalking.apache.org>.