123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- <template>
- <div style="width: 100%; height: 500px">
- <!-- 条件渲染日期范围选择器 -->
- <el-date-picker
- v-if="isDateType(chartData.data[0]?.xData)"
- <!--
- 只有xData是日期时才显示
- --
- >
- v-model="dateRange" type="daterange" align="right" unlink-panels
- range-separator="至" start-placeholder="开始日期"
- end-placeholder="结束日期" @change="onDateRangeChange" size="mini"
- style="margin: 20px 0 0 0" ></el-date-picker
- >
- <!-- boxLineCharts -->
- <div
- v-loading="loading"
- :id="`plotDivBox-${index}`"
- style="width: 100%; height: 450px"
- >
- <el-empty v-if="isError" description="请求失败"></el-empty>
- </div>
- </div>
- </template>
- <script>
- import Plotly from "plotly.js-dist";
- import axios from "axios";
- import { myMixin } from "@/mixins/chartRequestMixin";
- export default {
- mixins: [myMixin],
- props: {
- fileAddr: {
- default: "",
- type: String,
- },
- index: {
- type: String,
- },
- },
- data() {
- return {
- chartData: {},
- dateRange: [], // 用于存储选中的日期范围
- loading: false,
- isError: false,
- };
- },
- mounted() {
- console.log(this.fileAddr, "fileAddr 连接");
- this.getData();
- },
- methods: {
- async getData() {
- if (this.fileAddr !== "") {
- try {
- this.loading = true;
- this.cancelToken = axios.CancelToken.source();
- const resultChartsData = await axios.get(this.fileAddr, {
- cancelToken: this.cancelToken.token,
- });
- this.chartData = resultChartsData.data;
- this.drawBoxPlot();
- this.loading = false;
- this.isError = false;
- } catch (error) {
- this.loading = false;
- this.isError = true;
- }
- }
- },
- // 处理日期范围变化
- onDateRangeChange() {
- this.drawBoxPlot(); // 日期变化时重新绘制图表
- },
- // 判断时间戳是否在选择的日期范围内
- isInDateRange(timestamp) {
- const [startDate, endDate] = this.dateRange;
- if (!startDate || !endDate) return true;
- const date = new Date(timestamp);
- return date >= new Date(startDate) && date <= new Date(endDate);
- },
- // 判断xData是否为日期格式
- isDateType(xData) {
- // 假设第一个元素如果是日期字符串或Date对象则为日期类型
- const firstTimestamp = xData[0];
- return !isNaN(Date.parse(firstTimestamp)); // 判断是否是有效日期
- },
- // 过滤数据
- filterData(group) {
- const filteredXData = [];
- const filteredYData = [];
- const filteredMedians = group.medians ? { x: [], y: [] } : null;
- // 如果是日期类型数据,则进行日期过滤
- if (this.isDateType(group.xData)) {
- group.xData.forEach((timestamp, index) => {
- if (this.isInDateRange(timestamp)) {
- filteredXData.push(timestamp);
- filteredYData.push(group.yData[index]);
- // 处理中位值数据,确保索引一致
- if (filteredMedians && this.isInDateRange(group.medians.x[index])) {
- filteredMedians.x.push(group.medians.x[index]);
- filteredMedians.y.push(group.medians.y[index]);
- }
- }
- });
- } else {
- // 如果不是日期类型,直接将数据添加到数组
- filteredXData.push(...group.xData);
- filteredYData.push(...group.yData);
- if (group.medians) {
- filteredMedians.x.push(...group.medians.x);
- filteredMedians.y.push(...group.medians.y);
- }
- }
- return {
- ...group,
- xData: filteredXData,
- yData: filteredYData,
- medians: filteredMedians,
- };
- },
- // 绘制箱线图
- drawBoxPlot() {
- const chartData = this.chartData.data[0];
- // 过滤数据
- const filteredData = this.filterData(chartData);
- // 构建箱线图
- console.log(filteredData, "filteredData");
- const trace = {
- x: filteredData.xData,
- y: filteredData.yData,
- type: "box",
- marker: {
- color: "lightgray",
- },
- boxpoints: false, // 不显示散点
- boxmean: false, // 不显示均值
- name: filteredData.title,
- };
- let trace2 = {}; // 初始化trace2为一个空对象
- // 如果有中位值并且中位值的x轴数据不为空,则显示中位点
- if (filteredData.medians && filteredData.medians.x.length > 0) {
- trace2 = {
- x: filteredData.medians.x,
- y: filteredData.medians.y,
- mode: "markers",
- marker: {
- color: "#406DAB",
- size: 3,
- },
- name: `${filteredData.title} - 中位点`,
- type: "scatter",
- };
- }
- console.log(filteredData, "filteredData");
- // 布局设置
- const layout = {
- title: filteredData.title,
- xaxis: {
- title: this.chartData.xaixs,
- // 如果xData不是日期格式,则不配置type: "date"
- title: this.chartData.xaixs,
- // tickvals: filteredData.xData, // 设置tickvals为原始的xData
- // ticktext: filteredData.xData, // 设置ticktext为原始的xData(避免被转换成数字)
- // tickformat: this.isDateType(filteredData.xData)
- // ? "%Y-%m-%d"
- // : undefined,
- tickmode: "array", // 精确控制刻度
- },
- yaxis: { title: this.chartData.yaixs },
- showlegend: true,
- };
- // 使用 v-if 防止重新渲染
- if (this.chartData.data && this.chartData.data.length > 0) {
- Plotly.newPlot(`plotDivBox-${this.index}`, [trace, trace2], layout);
- }
- // Plotly.newPlot(`plotDivBox-${this.index}`, [trace, trace2], layout);
- },
- },
- };
- </script>
- <style scoped>
- /* 可根据需要自定义样式 */
- </style>
|