WXL (wul)
6 天以前 a5cba9ab040f6f97558046885dce3017f9bab7e9
src/views/sfstatistics/percentage/components/ChartDialog.vue
@@ -22,355 +22,366 @@
</template>
<script>
import * as echarts from 'echarts'
import * as echarts from "echarts";
export default {
  name: 'ChartDialog',
  name: "ChartDialog",
  props: {
    visible: {
      type: Boolean,
      default: false
      default: false,
    },
    statisticaltype: {
      type: Number,
      default: 1,
    },
    data: {
      type: Array,
      default: () => []
      default: () => [],
    },
    activeTab: {
      type: String,
      default: 'first'
    }
      default: "first",
    },
  },
  data() {
    return {
      pieChart: null,
      barLineChart: null
    }
      barLineChart: null,
    };
  },
  watch: {
    visible(newVal) {
      if (newVal) {
        this.$nextTick(() => {
          this.initCharts()
        })
          this.initCharts();
        });
      } else {
        this.destroyCharts()
        this.destroyCharts();
      }
    }
    },
  },
  mounted() {
    if (this.visible) {
      this.$nextTick(() => {
        this.initCharts()
      })
        this.initCharts();
      });
    }
  },
  beforeDestroy() {
    this.destroyCharts()
    this.destroyCharts();
  },
  methods: {
    initCharts() {
      this.initPieChart()
      this.initBarLineChart()
      this.initPieChart();
      this.initBarLineChart();
    },
    initPieChart() {
      const pieDom = document.getElementById('pieChart')
      if (!pieDom) return
      const pieDom = document.getElementById("pieChart");
      if (!pieDom) return;
      if (this.pieChart) {
        this.pieChart.dispose()
        this.pieChart.dispose();
      }
      this.pieChart = echarts.init(pieDom)
      this.pieChart = echarts.init(pieDom);
      // 根据当前tab计算饼图数据
      const pieData = this.getPieChartData()
      const pieData = this.getPieChartData();
      const pieOption = {
        title: {
          text: '随访状态分布',
          left: 'center',
          text: "随访状态分布",
          left: "center",
          textStyle: {
            color: '#333',
            fontSize: 16
          }
            color: "#333",
            fontSize: 16,
          },
        },
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b}: {c} ({d}%)'
          trigger: "item",
          formatter: "{a} <br/>{b}: {c} ({d}%)",
        },
        legend: {
          orient: 'vertical',
          left: 'left',
          orient: "vertical",
          left: "left",
          data: pieData.legendData,
          textStyle: {
            color: '#666'
          }
            color: "#666",
          },
        },
        color: ['#FF9D4D', '#36B37E', '#FF5C5C'],
        color: ["#FF9D4D", "#36B37E", "#FF5C5C"],
        series: [
          {
            name: '随访状态',
            type: 'pie',
            radius: ['40%', '70%'],
            name: "随访状态",
            type: "pie",
            radius: ["40%", "70%"],
            avoidLabelOverlap: true,
            itemStyle: {
              borderRadius: 10,
              borderColor: '#fff',
              borderWidth: 2
              borderColor: "#fff",
              borderWidth: 2,
            },
            label: {
              show: true,
              formatter: '{b}: {c} ({d}%)',
              color: '#333'
              formatter: "{b}: {c} ({d}%)",
              color: "#333",
            },
            emphasis: {
              label: {
                show: true,
                fontSize: '18',
                fontWeight: 'bold'
                fontSize: "18",
                fontWeight: "bold",
              },
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
                shadowColor: "rgba(0, 0, 0, 0.5)",
              },
            },
            data: pieData.seriesData
          }
        ]
      }
            data: pieData.seriesData,
          },
        ],
      };
      this.pieChart.setOption(pieOption)
      window.addEventListener('resize', this.resizePieChart)
      this.pieChart.setOption(pieOption);
      window.addEventListener("resize", this.resizePieChart);
    },
    getPieChartData() {
      let legendData = []
      let seriesData = []
      let legendData = [];
      let seriesData = [];
      if (this.activeTab === 'first') {
        legendData = ['待随访', '随访成功', '随访失败']
      if (this.activeTab === "first") {
        legendData = ["待随访", "随访成功", "随访失败"];
        const followUpData = {
          pending: 0,
          success: 0,
          fail: 0
        }
          fail: 0,
        };
        this.data.forEach((item) => {
          followUpData.pending += item.pendingFollowUp || 0
          followUpData.success += item.followUpSuccess || 0
          followUpData.fail += item.followUpFail || 0
        })
          followUpData.pending += item.pendingFollowUp || 0;
          followUpData.success += item.followUpSuccess || 0;
          followUpData.fail += item.followUpFail || 0;
        });
        seriesData = [
          { value: followUpData.pending, name: '待随访' },
          { value: followUpData.success, name: '随访成功' },
          { value: followUpData.fail, name: '随访失败' }
        ]
      } else if (this.activeTab === 'second') {
        legendData = ['待随访(再次)', '随访成功(再次)', '随访失败(再次)']
          { value: followUpData.pending, name: "待随访" },
          { value: followUpData.success, name: "随访成功" },
          { value: followUpData.fail, name: "随访失败" },
        ];
      } else if (this.activeTab === "second") {
        legendData = ["待随访(再次)", "随访成功(再次)", "随访失败(再次)"];
        const followUpData = {
          pending: 0,
          success: 0,
          fail: 0
        }
          fail: 0,
        };
        this.data.forEach((item) => {
          followUpData.pending += item.pendingFollowUpAgain || 0
          followUpData.success += item.followUpSuccessAgain || 0
          followUpData.fail += item.followUpFailAgain || 0
        })
          followUpData.pending += item.pendingFollowUpAgain || 0;
          followUpData.success += item.followUpSuccessAgain || 0;
          followUpData.fail += item.followUpFailAgain || 0;
        });
        seriesData = [
          { value: followUpData.pending, name: '待随访(再次)' },
          { value: followUpData.success, name: '随访成功(再次)' },
          { value: followUpData.fail, name: '随访失败(再次)' }
        ]
      } else if (this.activeTab === 'continued') {
        legendData = ['护理完成', '护理进行中', '护理未开始']
          { value: followUpData.pending, name: "待随访(再次)" },
          { value: followUpData.success, name: "随访成功(再次)" },
          { value: followUpData.fail, name: "随访失败(再次)" },
        ];
      } else if (this.activeTab === "continued") {
        legendData = ["护理完成", "护理进行中", "护理未开始"];
        const careData = {
          completed: 0,
          inProgress: 0,
          notStarted: 0
        }
          notStarted: 0,
        };
        this.data.forEach((item) => {
          careData.completed += item.careCompleted || 0
          careData.inProgress += item.careInProgress || 0
          careData.notStarted += item.careNotStarted || 0
        })
          careData.completed += item.careCompleted || 0;
          careData.inProgress += item.careInProgress || 0;
          careData.notStarted += item.careNotStarted || 0;
        });
        seriesData = [
          { value: careData.completed, name: '护理完成' },
          { value: careData.inProgress, name: '护理进行中' },
          { value: careData.notStarted, name: '护理未开始' }
        ]
          { value: careData.completed, name: "护理完成" },
          { value: careData.inProgress, name: "护理进行中" },
          { value: careData.notStarted, name: "护理未开始" },
        ];
      }
      return { legendData, seriesData }
      return { legendData, seriesData };
    },
    initBarLineChart() {
      const barDom = document.getElementById('barLineChart')
      if (!barDom) return
      const barDom = document.getElementById("barLineChart");
      if (!barDom) return;
      if (this.barLineChart) {
        this.barLineChart.dispose()
        this.barLineChart.dispose();
      }
      this.barLineChart = echarts.init(barDom)
      this.barLineChart = echarts.init(barDom);
      // 准备数据
      const chartData = this.getBarLineChartData()
      const chartData = this.getBarLineChartData();
      const option = {
        title: {
          text: `${chartData.title}趋势`,
          left: 'center',
          left: "center",
          textStyle: {
            color: '#333',
            fontSize: 16
          }
            color: "#333",
            fontSize: 16,
          },
        },
        tooltip: {
          trigger: 'axis',
          trigger: "axis",
          axisPointer: {
            type: 'cross',
            type: "cross",
            crossStyle: {
              color: '#999'
            }
          }
              color: "#999",
            },
          },
        },
        legend: {
          data: chartData.legendData,
          top: 'bottom',
          top: "bottom",
          textStyle: {
            color: '#666'
          }
            color: "#666",
          },
        },
        color: chartData.colors,
        xAxis: {
          type: 'category',
          type: "category",
          data: chartData.categories,
          axisLabel: {
            interval: 0,
            rotate: 30,
            color: '#666'
            color: "#666",
          },
          axisLine: {
            lineStyle: {
              color: '#ddd'
            }
          }
              color: "#ddd",
            },
          },
        },
        yAxis: [
          {
            type: 'value',
            type: "value",
            name: chartData.yAxisName1,
            min: 0,
            axisLabel: {
              color: '#666'
              color: "#666",
            },
            axisLine: {
              lineStyle: {
                color: '#ddd'
              }
                color: "#ddd",
              },
            },
            splitLine: {
              lineStyle: {
                color: '#f0f0f0'
              }
            }
                color: "#f0f0f0",
              },
            },
          },
          {
            type: 'value',
            name: '百分比(%)',
            type: "value",
            name: "百分比(%)",
            min: 0,
            max: 100,
            axisLabel: {
              color: '#666',
              formatter: '{value}%'
              color: "#666",
              formatter: "{value}%",
            },
            axisLine: {
              lineStyle: {
                color: '#ddd'
              }
                color: "#ddd",
              },
            },
            splitLine: {
              show: false
            }
          }
              show: false,
            },
          },
        ],
        series: chartData.series,
        grid: {
          top: '15%',
          left: '3%',
          right: '4%',
          bottom: '15%',
          containLabel: true
        }
      }
          top: "15%",
          left: "3%",
          right: "4%",
          bottom: "15%",
          containLabel: true,
        },
      };
      this.barLineChart.setOption(option)
      window.addEventListener('resize', this.resizeBarLineChart)
      this.barLineChart.setOption(option);
      window.addEventListener("resize", this.resizeBarLineChart);
    },
    getBarLineChartData() {
      const categories = this.data.map(
        (item) => item.leavehospitaldistrictname || item.deptname
      )
      let categories
      if (this.statisticaltype == 2) {
         categories = this.data.map(
          (item) => item.deptname || item.leavehospitaldistrictname
        );
      } else {
         categories = this.data.map(
          (item) => item.leavehospitaldistrictname || item.deptname
        );
      }
      let title = '科室/病区'
      let yAxisName1 = '人次'
      let legendData = []
      let colors = []
      let series = []
      let title = "科室/病区";
      let yAxisName1 = "人次";
      let legendData = [];
      let colors = [];
      let series = [];
      if (this.activeTab === 'first') {
        title = '首次随访'
        yAxisName1 = '人次'
        legendData = ['出院人次', '应随访人次', '随访率(%)', '及时率(%)']
        colors = ['#5470C6', '#91CC75', '#EE6666', '#9A60B4']
      if (this.activeTab === "first") {
        title = "首次随访";
        yAxisName1 = "人次";
        legendData = ["出院人次", "应随访人次", "随访率(%)", "及时率(%)"];
        colors = ["#5470C6", "#91CC75", "#EE6666", "#9A60B4"];
        const dischargeData = this.data.map((item) => item.dischargeCount || 0)
        const followUpData = this.data.map((item) => item.followUpNeeded || 0)
        const dischargeData = this.data.map((item) => item.dischargeCount || 0);
        const followUpData = this.data.map((item) => item.followUpNeeded || 0);
        const followUpRateData = this.data.map((item) => {
          if (!item.followUpRate) return 0
          const rateStr = String(item.followUpRate).replace('%', '')
          return parseFloat(rateStr) || 0
        })
          if (!item.followUpRate) return 0;
          const rateStr = String(item.followUpRate).replace("%", "");
          return parseFloat(rateStr) || 0;
        });
        const timelyRateData = this.data.map((item) =>
          item.rate ? (Number(item.rate) * 100).toFixed(2) : 0
        )
        );
        series = [
          {
            name: '出院人次',
            type: 'bar',
            barWidth: '25%',
            name: "出院人次",
            type: "bar",
            barWidth: "25%",
            data: dischargeData,
            itemStyle: {
              borderRadius: [4, 4, 0, 0]
            }
              borderRadius: [4, 4, 0, 0],
            },
          },
          {
            name: '应随访人次',
            type: 'bar',
            barWidth: '25%',
            name: "应随访人次",
            type: "bar",
            barWidth: "25%",
            data: followUpData,
            itemStyle: {
              borderRadius: [4, 4, 0, 0]
            }
              borderRadius: [4, 4, 0, 0],
            },
          },
          {
            name: '随访率(%)',
            type: 'line',
            name: "随访率(%)",
            type: "line",
            yAxisIndex: 1,
            data: followUpRateData,
            symbolSize: 8,
            lineStyle: {
              width: 3
              width: 3,
            },
            markLine: {
              silent: true,
@@ -378,22 +389,22 @@
                {
                  yAxis: 80,
                  lineStyle: {
                    color: '#EE6666',
                    type: 'dashed'
                  }
                }
              ]
            }
                    color: "#EE6666",
                    type: "dashed",
                  },
                },
              ],
            },
          },
          {
            name: '及时率(%)',
            type: 'line',
            name: "及时率(%)",
            type: "line",
            yAxisIndex: 1,
            data: timelyRateData,
            symbolSize: 8,
            lineStyle: {
              width: 3,
              type: 'dotted'
              type: "dotted",
            },
            markLine: {
              silent: true,
@@ -401,55 +412,55 @@
                {
                  yAxis: 90,
                  lineStyle: {
                    color: '#9A60B4',
                    type: 'dashed'
                  }
                }
              ]
            }
          }
        ]
      } else if (this.activeTab === 'second') {
        title = '再次随访'
        yAxisName1 = '人次'
        legendData = ['出院人次', '应随访人次', '随访率(%)']
        colors = ['#5470C6', '#91CC75', '#EE6666']
                    color: "#9A60B4",
                    type: "dashed",
                  },
                },
              ],
            },
          },
        ];
      } else if (this.activeTab === "second") {
        title = "再次随访";
        yAxisName1 = "人次";
        legendData = ["出院人次", "应随访人次", "随访率(%)"];
        colors = ["#5470C6", "#91CC75", "#EE6666"];
        const dischargeData = this.data.map((item) => item.dischargeCount || 0)
        const followUpData = this.data.map((item) => item.followUpNeeded || 0)
        const dischargeData = this.data.map((item) => item.dischargeCount || 0);
        const followUpData = this.data.map((item) => item.followUpNeeded || 0);
        const followUpRateAgainData = this.data.map((item) => {
          if (!item.followUpRateAgain) return 0
          const rateStr = String(item.followUpRateAgain).replace('%', '')
          return parseFloat(rateStr) || 0
        })
          if (!item.followUpRateAgain) return 0;
          const rateStr = String(item.followUpRateAgain).replace("%", "");
          return parseFloat(rateStr) || 0;
        });
        series = [
          {
            name: '出院人次',
            type: 'bar',
            barWidth: '25%',
            name: "出院人次",
            type: "bar",
            barWidth: "25%",
            data: dischargeData,
            itemStyle: {
              borderRadius: [4, 4, 0, 0]
            }
              borderRadius: [4, 4, 0, 0],
            },
          },
          {
            name: '应随访人次',
            type: 'bar',
            barWidth: '25%',
            name: "应随访人次",
            type: "bar",
            barWidth: "25%",
            data: followUpData,
            itemStyle: {
              borderRadius: [4, 4, 0, 0]
            }
              borderRadius: [4, 4, 0, 0],
            },
          },
          {
            name: '随访率(%)',
            type: 'line',
            name: "随访率(%)",
            type: "line",
            yAxisIndex: 1,
            data: followUpRateAgainData,
            symbolSize: 8,
            lineStyle: {
              width: 3
              width: 3,
            },
            markLine: {
              silent: true,
@@ -457,55 +468,59 @@
                {
                  yAxis: 80,
                  lineStyle: {
                    color: '#EE6666',
                    type: 'dashed'
                  }
                }
              ]
            }
          }
        ]
      } else if (this.activeTab === 'continued') {
        title = '延续护理'
        yAxisName1 = '人次'
        legendData = ['延续护理人次', '护理完成', '完成率(%)']
        colors = ['#5470C6', '#91CC75', '#EE6666']
                    color: "#EE6666",
                    type: "dashed",
                  },
                },
              ],
            },
          },
        ];
      } else if (this.activeTab === "continued") {
        title = "延续护理";
        yAxisName1 = "人次";
        legendData = ["延续护理人次", "护理完成", "完成率(%)"];
        colors = ["#5470C6", "#91CC75", "#EE6666"];
        const continuedCareData = this.data.map((item) => item.continuedCareCount || 0)
        const careCompletedData = this.data.map((item) => item.careCompleted || 0)
        const continuedCareData = this.data.map(
          (item) => item.continuedCareCount || 0
        );
        const careCompletedData = this.data.map(
          (item) => item.careCompleted || 0
        );
        const completionRateData = this.data.map((item) => {
          if (!item.completionRate) return 0
          const rateStr = String(item.completionRate).replace('%', '')
          return parseFloat(rateStr) || 0
        })
          if (!item.completionRate) return 0;
          const rateStr = String(item.completionRate).replace("%", "");
          return parseFloat(rateStr) || 0;
        });
        series = [
          {
            name: '延续护理人次',
            type: 'bar',
            barWidth: '25%',
            name: "延续护理人次",
            type: "bar",
            barWidth: "25%",
            data: continuedCareData,
            itemStyle: {
              borderRadius: [4, 4, 0, 0]
            }
              borderRadius: [4, 4, 0, 0],
            },
          },
          {
            name: '护理完成',
            type: 'bar',
            barWidth: '25%',
            name: "护理完成",
            type: "bar",
            barWidth: "25%",
            data: careCompletedData,
            itemStyle: {
              borderRadius: [4, 4, 0, 0]
            }
              borderRadius: [4, 4, 0, 0],
            },
          },
          {
            name: '完成率(%)',
            type: 'line',
            name: "完成率(%)",
            type: "line",
            yAxisIndex: 1,
            data: completionRateData,
            symbolSize: 8,
            lineStyle: {
              width: 3
              width: 3,
            },
            markLine: {
              silent: true,
@@ -513,14 +528,14 @@
                {
                  yAxis: 85,
                  lineStyle: {
                    color: '#EE6666',
                    type: 'dashed'
                  }
                }
              ]
            }
          }
        ]
                    color: "#EE6666",
                    type: "dashed",
                  },
                },
              ],
            },
          },
        ];
      }
      return {
@@ -529,41 +544,41 @@
        categories,
        legendData,
        colors,
        series
      }
        series,
      };
    },
    resizePieChart() {
      if (this.pieChart) {
        this.pieChart.resize()
        this.pieChart.resize();
      }
    },
    resizeBarLineChart() {
      if (this.barLineChart) {
        this.barLineChart.resize()
        this.barLineChart.resize();
      }
    },
    destroyCharts() {
      if (this.pieChart) {
        this.pieChart.dispose()
        this.pieChart = null
        this.pieChart.dispose();
        this.pieChart = null;
      }
      if (this.barLineChart) {
        this.barLineChart.dispose()
        this.barLineChart = null
        this.barLineChart.dispose();
        this.barLineChart = null;
      }
      window.removeEventListener('resize', this.resizePieChart)
      window.removeEventListener('resize', this.resizeBarLineChart)
      window.removeEventListener("resize", this.resizePieChart);
      window.removeEventListener("resize", this.resizeBarLineChart);
    },
    handleClose() {
      this.destroyCharts()
      this.$emit('close')
    }
  }
}
      this.destroyCharts();
      this.$emit("close");
    },
  },
};
</script>
<style lang="scss" scoped>