• 质量看板开发实践(七):使用旭日图汇总每个人的故事点


    想用一张图来展示一个冲刺中每个人分配的故事点数,而且能够按照前端、后端、测试等维度聚合,所以采用了旭日图

    效果如下

    echarts中关于旭日图的例子:https://echarts.apache.org/examples/zh/editor.html?c=sunburst-simple

    下面来介绍下具体实现过程

    首先来看下旭日图的数据结构

    类似这种:父节点Grandpa,它下面有2个子节点Uncle LeoFather,Uncle Leo下有3个子节点Cousin JackCousin MaryCousin Ben

    所以后端要构造出这种格式的数据

    后端数据处理

    可以从jira一个故事卡的原始数据中提取出 (前端工程师 and 前端故事点)(后端工程师 and 后端故事点)(测试负责人 and 测试故事点)

    由于每个公司的jira版本不同,上述字段在自己当前jira中对应的字段属性不尽相同,需要自己从原始数据中找到对应字段名

    下面是部分重点代码

        def get_sprint(self, project, sprint):
            """
            获取每个冲刺的数据,例如冲刺标题、每个人的故事点数
            :param project:
            :param sprint:
            :return:
            """
    
            try:
    if sprint == "" or sprint is None:  # 不传sprint会查询所有冲刺
                    jql = "project in ({}) AND issuetype = Story".format(project)
                else:
                    jql = "project in ({}) AND issuetype = Story AND Sprint in ({})".format(project, sprint)
    
                print("****************** 打印jql ******************")
                print("正在执行的jql=", jql)
    
                fields = "summary, priority, status, creator, created, customfield_12309, customfield_12307," \
                         "customfield_12310, customfield_12308, customfield_12400,customfield_11303, customfield_10006"
    
                issues = self.jira.search_issues(jql, fields=fields, maxResults=-1)
                # 前端故事点:customfield_12309;后端故事点:customfield_12310;测试故事点:customfield_12400;预估总点数:customfield_10006
                # 前端负责人:customfield_12307;后端负责人:customfield_12308;测试负责人:customfield_11303
    
                front_points = []  # 前端故事点
                fronter = []  # 故事对应的前端工程师
                server_points = []  # 后端故事点
                server = []  # 故事对应的后端工程师
                test_points = []  # 测试故事点
                tester = []  # 故事对应的测试工程师
    
                for i in issues:
    
                    # print(i.raw)  # 打印每个故事的原始信息
                    # 前端故事点
                    if i.raw["fields"]["customfield_12309"] is None:
                        front_points.append(0)
                    else:
                        front_points.append(i.raw["fields"]["customfield_12309"])
    
                    # 前端工程师
                    if i.raw["fields"]["customfield_12307"] is None:
                        fronter.append("未指派")
                    else:
                        fronter.append(i.raw["fields"]["customfield_12307"][0]["displayName"].split("(")[0])
    
                    # 后端故事点
                    if i.raw["fields"]["customfield_12310"] is None:
                        server_points.append(0)
                    else:
                        server_points.append(i.raw["fields"]["customfield_12310"])
    
                    # 后端工程师
                    if i.raw["fields"]["customfield_12308"] is None:
                        server.append("未指派")
                    else:
                        server.append(i.raw["fields"]["customfield_12308"][0]["displayName"].split("(")[0])
    
                    # 测试故事点
                    if i.raw["fields"]["customfield_12400"] is None:
                        test_points.append(0)
                    else:
                        test_points.append(i.raw["fields"]["customfield_12400"])
    
                    # 测试工程师
                    if i.raw["fields"]["customfield_11303"] is None:
                        tester.append("未指派")
                    else:
                        tester.append(i.raw["fields"]["customfield_11303"]["displayName"].split("(")[0])  # 提取名称,只保留中文
    
                print("打印前端故事点:", front_points)
                print("打印前端工程师:", fronter)
                # print("打印后端故事点:", server_points)
                # print("打印后端工程师:", server)
                # print("打印测试故事点:", test_points)
                # print("打印测试工程师:", tester)
    
                # 对前端、后端、测试各自的故事点数,以负责人维度进行聚合
                df1 = pd.DataFrame(data={'name': fronter, 'value': front_points})
                # groupby()之后,使用sum对相同元素求和 <class 'pandas.core.frame.DataFrame'>
                front_group = df1.groupby('name', as_index=True).sum()
                # print(front_group)
    
                front_dict = front_group.to_dict()["value"]
                front_list = self.data_to_pie(front_dict)  # 前端故事点旭日图所需数据
                print("打印前端故事点聚合数据", front_list)
    
                df2 = pd.DataFrame(data={'name': server, 'value': server_points})
                server_group = df2.groupby('name', as_index=True).sum()
                server_dict = server_group.to_dict()["value"]
                server_list = self.data_to_pie(server_dict)  # 后端故事点旭日图所需数据
                # print("打印后端故事点聚合数据", server_list)
    
                df3 = pd.DataFrame(data={'name': tester, 'value': test_points})
                tester_group = df3.groupby('name', as_index=True).sum()
                tester_dict = tester_group.to_dict()["value"]
                tester_list = self.data_to_pie(tester_dict)  # 测试故事点旭日图所需数据
                # print("打印测试故事点聚合数据", tester_list)
    
                points_total = sum(front_points + server_points + test_points)  # 前后端、测试故事点总数
                # print("打印故事点总数:", points_total)
    
                # 旭日图所需数据格式
                story_points_list = [
                    {
                        "name": "前端",
                        "children": front_list
                    },
                    {
                        "name": "后端",
                        "children": server_list
                    },
                    {
                        "name": "测试",
                        "children": tester_list
                    }
                ]
    
    
                res = {
                    "code": "200",
                    "points_total": points_total,
                    "story_points_list": story_points_list,
                }
                return res
    
            except Exception as e:
                raise e

    以前端为例,分别打印 front_points、fronter、front_list

    print("打印前端故事点:", front_points)
    print("打印前端工程师:", fronter)
    print("打印前端故事点聚合数据front_list", front_list)

    结果如下:

    打印前端故事点: [1.0, 2.0, 1.0, 1.0, 2.0, 2.0, 0, 0, 0, 1.0, 3.0, 1.0]  每个故事卡的前端故事点
    打印前端工程师: ['张三', '张三', '张三', '张三', '张三', '李四', '未指派', '未指派', '未指派', '李四', '李四', '李四'] 每个故事卡对应的前端工程师
    打印前端故事点聚合数据front_list [{'value': 0.0, 'name': '未指派'}, {'value': 7.0, 'name': '李四'}, {'value': 7.0, 'name': '张三'}]  聚合上面2个列表,得到这样一组聚合数据

    借助pandas处理front_pointsfronter可以得到front_list

    具体用法可以查看之前的一篇博客:质量看板开发实践(三):bug柱状图

    同理可以得到后端工程师测试负责人相关的数据,最后构造为旭日图所需的数据结构

    # 旭日图所需数据格式
      story_points_list = [
          {
              "name": "前端",
              "children": front_list
          },
          {
              "name": "后端",
              "children": server_list
          },
          {
              "name": "测试",
              "children": tester_list
          }
      ]

    前端处理

    前端逻辑比较简单,只要把旭日图相关代码拿过来就好

    <template>
    
    </template>
    
    <script>
    import * as echarts from 'echarts';
    
    export default {
      name: "sun_figure",
      methods: {
        story_sun(datasource, points) {
    
          let chartDom = document.getElementById('story_sun');
          let myChart = echarts.init(chartDom);
          let option;
    
          option = {
            title: {
              text: '故事点汇总',
              top: '5%', // 距离顶部位置
              left: 'center'
            },
            tooltip: {
              trigger: 'item'
            },
            color: ['#FFAE57', '#FF7853', '#EA5151', '#CC3F57', '#9A2555'],
            graphic: {
              type: 'text',
              left: "80%",
              top: '50%',
              style: {
                text: '总数:' + points,
                textAlign: 'center',
                fill: '#333',
                fontSize: 15,
                fontWeight: 700
              }
            },
            series: {
              type: 'sunburst',
              // emphasis: {
              //     focus: 'ancestor'
              // },
              center:['50%', '53%'], //控制左右上下
              data: datasource,
              radius: [0, '60%'], //控制大小
              label: {
                rotate: 'radial'
              }
            }
          };
    
          option && myChart.setOption(option);
    
        }
      }
    }
    </script>
    
    <style scoped>
    
    </style>
  • 相关阅读:
    模板——二分法
    Trie Tree(静态数组写法,好写)
    欧拉路径 基础题 hiho第49周
    Fleury算法求欧拉路径 hiho第50周
    hdu 5266 pog loves szh III 在线lca+线段树区间优化
    hdu 5269 字典树
    hdu 5265 pog loves szh II
    poj 3678 2-sat(强连通)
    lca 在线,离线 poj 1330
    lca 在线算法 zoj 3195
  • 原文地址:https://www.cnblogs.com/hanmk/p/16227245.html
Copyright © 2020-2023  润新知