美文网首页
基于echarts的项目甘特图

基于echarts的项目甘特图

作者: EasyNetCN | 来源:发表于2022-02-13 09:44 被阅读0次
研发资源

如上图所示,本示例是基于viewui,echarts 4的一个简单的研发资源-项目的甘特图,当然可以根据自己需要,实现更复杂的效果。
示例中的源码,用固定数据代替了axios调用服务端接口。

<template>
  <YdLayout>
    <Content
      :style="{
        padding: '0',
        minHeight: windowHeight - 80 + 'px',
        background: '#fff',
      }"
    >
      <Row>
        <Col span="24">
          <div style="padding: 0 15%">
            <div
              id="main"
              :style="{
                width: '100%',
                height: tabHeight + 'px',
                marginTop: padCanvas + 'px',
              }"
            ></div>
          </div>
        </Col>
        <Col span="24" style="padding:20px">
          <Button type="primary" @click="exportData">
            <Icon type="ios-download-outline"></Icon>导出数据
          </Button>
          <br />
          <Table ref="tb" class="ivu-m-8" border :columns="columns" :data="tbData"></Table>
        </Col>
      </Row>
    </Content>
  </YdLayout>
</template>
<script>
import dayjs from "dayjs"
import echarts from "echarts";
import mixinsAutoSize from "../../mixins/auto-size";
import { deepCopy } from "../../utils/assist";
import YdLayout from "../yd-layout";


const stats = () => {
  const data = { "minStartTime": "2022-01-01", "maxEndTime": "2022-03-31", "users": [{ "userId": 1, "userName": "研发1", "projects": [{ "projectId": 1, "projectName": "项目1", "startTime": "2022-01-01", "endTime": "2022-02-26" }, { "projectId": 2, "projectName": "项目2", "startTime": "2022-01-01", "endTime": "2022-03-31" }] }, { "userId": 2, "userName": "研发2", "projects": [{ "projectId": 1, "projectName": "项目1", "startTime": "2022-01-26", "endTime": "2022-02-27" }, { "projectId": 2, "projectName": "项目2", "startTime": "2022-01-29", "endTime": "2022-02-28" }] }], "projects": [{ "projectId": 1, "projectName": "项目1", "startTime": "2022-01-01", "endTime": "2022-02-26" }, { "projectId": 2, "projectName": "项目2", "startTime": "2022-01-01", "endTime": "2022-03-31" }] }

  return new Promise(function (resolve, reject) {
    resolve(data)
  })
}

export default {
  name: "YdoProjectStats",
  components: { YdLayout },
  mixins: [mixinsAutoSize],
  data() {
    return {
      statsChart: null,
      padCanvas: "30",
      tabHeight: "",
      columns: [{
        title: "人员",
        key: "userName",
        width: 200
      },
      {
        title: "项目",
        key: "projects",
        minWidth: 200
      },
      {
        title: "开始时间",
        key: "startTime",
        width: 100
      }, {
        title: "结束时间",
        key: "endTime",
        width: 100
      }],
      tbData: []
    };
  },
  created() {
    this.tabHeight = this.windowHeight - 200;
    this.init();
  },
  methods: {
    init() {
      this.stats();
    },
    stats() {
      stats()
        .then((response) => {
          console.log(response)
          const minTime = response.minStartTime
          const maxTime = response.maxEndTime
          const projectUsers = response.users.slice(0)
          const projects = response.projects.slice(0)
          const users = projectUsers.map(e => e.userName)

          const serieData = [];

          projects.forEach(project => {
            const endDates = []
            const startDates = []

            projectUsers.forEach(user => {
              const t = user.projects.find(e => e.projectId == project.projectId)

              if (t != undefined) {
                endDates.push(t.endTime)
                startDates.push(t.startTime)
              } else {
                endDates.push("")
                startDates.push("")
              }
            })

            serieData.push(
              {
                name: project.projectName,
                type: "bar",
                stack: project.projectName,
                normal: {
                  borderColor: "#fff",
                  borderWidth: 2
                },
                zlevel: -1,
                data: endDates
              }
            )
            serieData.push(
              {
                name: project.projectName,
                type: "bar",
                stack: project.projectName,
                itemStyle: {
                  normal: {
                    color: "white",
                  }
                },
                zlevel: -1,
                z: 3,
                data: startDates
              }
            )
          })

          let statsChartOption = {
            title: {
              text: "研发资源"
            },
            legend: {
              y: "top",
            },
            grid: {
              containLabel: true
            },
            xAxis: {
              type: "time",
              min: minTime,
              max: maxTime
            },
            yAxis: {
              axisLabel: {
                show: true,
                interval: 0,
                formatter: function (value, index) {
                  var last = ""
                  var max = 5;
                  var len = value.length;
                  var hang = Math.ceil(len / max);
                  if (hang > 1) {
                    for (var i = 0; i < hang; i++) {
                      var start = i * max;
                      var end = start + max;
                      var temp = value.substring(start, end) + "\n";
                      last += temp;
                    }
                    return last;
                  } else {
                    return value;
                  }
                }
              },
              data: users
            },
            tooltip: {
              trigger: "axis",
              axisPointer: {
                type: 'shadow'
              },
              formatter: function (params) {
                var res = "";
                var name = "";
                var start0 = "";
                var start = "";
                var end0 = "";
                var end = "";
                for (var i in params) {
                  var k = i % 2;
                  if (!k) { //奇数
                    name = params[i].seriesName;
                    end0 = params[i].data;

                    if (end0 != null && end0.length > 0) {
                      end = end0
                    }
                  }
                  if (k) { //偶数
                    start0 = params[i].data;

                    if (start0 != null && start0.length > 0) {
                      start = start0
                    }

                    res += name + " : " + start + "~" + end + "</br>";
                  }
                }
                return res;
              }
            },
            series: serieData
          }

          this.statsChart = echarts.init(document.getElementById("main"));
          this.statsChart.setOption(statsChartOption);

          this.renderTable(projectUsers)

        }).catch((error) => this.handleSearchError(error));
    },
    renderTable(data) {
      let tbData = []

      data.forEach(user => {
        let minTime = user.projects[0].startTime;
        let maxTime = user.projects[0].endTime;

        user.projects.forEach(project => {
          if (minTime.length > 0 && project.startTime.length > 0 && dayjs(project.startTime).isBefore(dayjs(minTime))) {
            minTime = project.startTime
          }
          if (maxTime.length > 0 && project.endTime.length > 0 && dayjs(project.endTime).isAfter(dayjs(maxTime))) {
            maxTime = project.endTime
          }
        })

        tbData.push({
          userName: user.userName,
          projects: user.projects.map(e => e.projectName).join(" "),
          startTime: minTime,
          endTime: maxTime
        })
      })

      this.tbData = tbData
    },
    handleSearchError(error) {
      console.log(error);
      this.tbData = [];

      if (
        error.response &&
        error.response.data &&
        error.response.data.message
      ) {
        this.$Notice.warning({ title: error.response.data.message });
      } else {
        this.$Notice.warning({ title: "无法加载数据" });
      }
    },
    exportData() {
      this.$refs.tb.exportCsv({
        filename: 'project-stats'
      })
    }
  },
};
</script>

相关文章

  • 基于echarts的项目甘特图

    如上图所示,本示例是基于viewui,echarts 4的一个简单的研发资源-项目的甘特图,当然可以根据自己需要,...

  • vue项目使用Echarts制作项目工期甘特图

    1,前言 项目迭代过程中,碰上一个需求,要求用甘特图的方式显示项目的工期进度,开完会我赶紧搜索一下甘特图是啥东东,...

  • echarts 甘特图 demo

    回溯项目还可以,不完善还没有进度百分比先保存着 其他平台的一些demohttps://code.hcharts.c...

  • Redmine使用心得

    Redmine介绍 Redmine 是一个开源的, 基于Web的项目管理和缺陷跟踪工具. 它用日历和甘特图辅助项目...

  • Redmine入门

    Redmine简介 Redmine 是一个开源的, 基于Web的项目管理和缺陷跟踪工具. 它用日历和甘特图辅助项目...

  • 甘特图(一)

    如图所示 1.echarts 下载 2.main.js引入 echarts 3.页面代码: 下一篇文章有甘特图添...

  • 项目管理工具Redmine操作手册

    什么是Redmine Redmine是一个开源的、基于web的项目管理和缺陷跟踪工具。它用日历和甘特图辅助项目及进...

  • 设计

    制作项目甘特图,安排项目时间。

  • 【开源项目管理软件】Redmine 安装及使用手册

    Redmine是一个开源的、基于Web的项目管理和缺陷跟踪工具。它用日历和甘特图辅助项目及进度可视化显示。同时它又...

  • 目标设定及时间管理工具

    甘特图:项目时间统计

网友评论

      本文标题:基于echarts的项目甘特图

      本文链接:https://www.haomeiwen.com/subject/mbrflrtx.html