echarts:一个复杂的瀑布图制作

本文围绕 ECharts 瀑布图制作展开,分析了几个难点,如让柱子不从 0 开始、左侧 y 轴时间表示、柱子上线条绘制等。介绍了将时间转化为数值、用透明柱子实现效果等方法,还提及了双 y 轴设置、刻度转换、图例添加等图表制作步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

成品展示

在这里插入图片描述

思路介绍

分析一下这个需求,主要有几个难点:

1、如何让柱子不是从0开始

答:echarts 官方 把这种柱子叫瀑布图,实现的原理就是使用一个透明的柱子给他顶起来。我直接搬过来原文。
在这里插入图片描述

2、左侧y轴的时间怎么表示

我本来想到的是 y 轴的 type 设置为 time
在这里插入图片描述
但是做着做着,发现不行,我们做瀑布图要用到 stack,而 stack 不支持 type = time
在这里插入图片描述
那就只能用 type = value 了,也就是要把时间转化为一个数值,比如在上面的图中,最底部是 13:00,我们先以 13:00 为 0,那么 12:00 就是 1,11:00 就是 2,以此类推。

那么由这个问题又引申出两个小问题:
1、y 轴变为数字了,要将其转化为几点几分的这种时间,这个用 formatter 转换一下就行
2、我们现在是以 13:00 为 0 点,现实应该是以所有数据的最大值为 0 点,并且要取整数,比如最大值是13:30,那么 0 点就是 14:00。这个到时候写一个函数进行单独处理。

3、柱子上的线怎么画出来

这个线代表的夜晚醒来的次数和时间,其实原理还是瀑布图的画法,只不过要均匀的分布在睡眠时长里面,需要用一些算法。

n 代表一共几条线(也就是夜醒几次)
第 x 条线的透明柱子 = 睡眠时长的透明柱子高度 + (睡眠时长柱子高度 / n + 1)* x
第 x 条线的柱子 = 夜醒时长,或者给个固定高度

做出两个简单柱子

option = {
  xAxis: {
    type: 'category',
    data: ['周一', '周二', '周三', '周四', '周五', '周六']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    // 黄色柱子
    {
      name: 'bar1',
      type: 'bar',
      stack: 'Total1',
      data: [2900, 1200, 300, 200, 900, 300],
      itemStyle: {
        color: '#fac858',
        barBorderRadius: [8, 8, 0, 0],
      }
    },
    // 紫色柱子
    {
      name: 'bar2',
      type: 'bar',
      stack: 'Total2',
      // stackStrategy: 'negative',
      itemStyle: {
        color: '#8c7dc2',
      },
      data: [2800, 1100, 200, 100, 800, 200]
    },
  ]
};

在这里插入图片描述

下面加上透明柱子

option = {
  xAxis: {
    type: 'category',
    data: ['周一', '周二', '周三', '周四', '周五', '周六']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    // 透明柱子(黄色柱子下面)
    {
      name: 'Placeholder1',
      type: 'bar',
      stack: 'Total1', // 为透明柱子指定不同的 stack
      stackStrategy: 'negative',
      itemStyle: {
        color: 'rgba(0,0,0,0)',
      },
      data: [100, 100, 100, 100, 100, 100]
    },
    // 黄色柱子
    {
      name: 'bar1',
      type: 'bar',
      stack: 'Total1',
      data: [2900, 1200, 300, 200, 900, 300],
      itemStyle: {
        color: '#fac858',
        barBorderRadius: [8, 8, 8, 8],
      }
    },
    // 透明柱子(紫色柱子下面)
    {
      name: 'Placeholder2',
      type: 'bar',
      stack: 'Total2', // 为透明柱子指定不同的 stack
      stackStrategy: 'negative',
      itemStyle: {
        color: 'rgba(0,0,0,0)',
      },
      data: [100, 100, 100, 100, 100, 100]
    },
    // 紫色柱子
    {
      name: 'bar2',
      type: 'bar',
      stack: 'Total2',
      // stackStrategy: 'negative',
      itemStyle: {
        color: '#8c7dc2',
      },
      data: [2800, 1100, 200, 100, 800, 200]
    },
  ]
};

在这里插入图片描述

合并两个柱子

stack 改为相同

option = {
  xAxis: {
    type: 'category',
    data: ['周一', '周二', '周三', '周四', '周五', '周六']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    // 透明柱子(黄色柱子下面)
    {
      name: 'Placeholder1',
      type: 'bar',
      stack: 'Total', // 为透明柱子指定不同的 stack
      stackStrategy: 'negative',
      itemStyle: {
        color: 'rgba(0,0,0,0)',
      },
      data: [100, 100, 100, 100, 100, 100]
    },
    // 黄色柱子
    {
      name: 'bar1',
      type: 'bar',
      stack: 'Total',
      data: [2900, 1200, 300, 200, 900, 300],
      itemStyle: {
        color: '#fac858',
        barBorderRadius: [8, 8, 8, 8],
      }
    },
    // 透明柱子(紫色柱子下面)
    {
      name: 'Placeholder2',
      type: 'bar',
      stack: 'Total', // 为透明柱子指定不同的 stack
      stackStrategy: 'negative',
      itemStyle: {
        color: 'rgba(0,0,0,0)',
      },
      data: [100, 100, 100, 100, 100, 100]
    },
    // 紫色柱子
    {
      name: 'bar2',
      type: 'bar',
      stack: 'Total',
      itemStyle: {
        color: '#8c7dc2',
      },
      data: [2800, 1100, 200, 100, 800, 200]
    },
  ]
};

在这里插入图片描述
如果把紫色柱子下面的透明柱子的数字改大一点,就是这样
在这里插入图片描述

y轴左右各一个坐标轴

当我的图表同时有柱状图和折线图时,我想让左侧y轴显示柱状图的数据,右侧y轴显示折线图的数据。

option = {
  xAxis: {
    type: 'category',
    data: ['周一', '周二', '周三', '周四', '周五', '周六']
  },
  yAxis: [
    {
      type: 'value', // 左侧 y 轴配置
    },
    {
      type: 'value', // 右侧 y 轴配置
    },
  ],
  series: [
    // 柱状图系列(放在左侧 y 轴上)
    {
      name: 'bar',
      type: 'bar',
      data: [2900, 1200, 300, 200, 900, 300],
      itemStyle: {
        color: '#fac858',
        barBorderRadius: [15, 15, 0, 0],
      },
      yAxisIndex: 0, // 指定使用左侧 y 轴
    },
    // 折线图系列(放在右侧 y 轴上)
    {
      name: 'line',
      type: 'line',
      data: [2800, 1100, 200, 100, 800, 200],
      itemStyle: {
        color: '#8c7dc2',
      },
      yAxisIndex: 1, // 指定使用右侧 y 轴
    },
  ]
};

在这里插入图片描述

y轴固定间隔刻度

yAxis: {
  type: 'value',
  interval: 100, // 设置刻度的间隔,每隔100一个刻度
}

y轴刻度数值转换

yAxis: {
  type: 'value',
  axisLabel: {
    formatter: function (value) {
      // 在这里进行刻度值的转化
      return value + "h";
    }
  }
}

y轴显示标签

yAxis: {
  type: 'value',
  name: '效率', // 设置 y 轴的名称
  // y 轴的名称的样式
  nameTextStyle: {
    align: 'left'
  }
}

在这里插入图片描述

添加图例

legend: {
  orient: 'horizontal', // 设置图例的方向为水平
  bottom: 10, // 设置图例距离底部的距离
  itemGap: 20, // 设置图例项之间的距离
  // 这里如果不加,默认会把透明柱状图也展示出来,所以筛选一下
  data: ['卧床时长', '睡眠时长', '睡眠效率'], // 图例的名称,与 series 中的 name 对应
}

在这里插入图片描述

对折线图的点样式进行设置

{
  name: '睡眠效率',
  type: 'line',
  data: [20, 30, 100, 80, 20, 19],
  // 点为一个圆圈,如果不设置这个,底下的点的颜色会设置不成功
  symbol: 'circle',
  // 点的大小
  symbolSize: 8,
  lineStyle: {
    color: '#33b981',  // 指定折线的颜色
    width: 2,        // 指定折线的宽度
  },
  itemStyle: {
    color: '#33b981',   // 点的填充颜色
    borderColor: '#fff', // 点的白色边框
    borderWidth: 2,        // 点的边框宽度
  },
  yAxisIndex: 1, // 指定使用右侧 y 轴
}

在这里插入图片描述

显示点上的数字并对数字做转换

{
  name: '睡眠效率',
  type: 'line',
  data: [20, 30, 100, 80, 20, 19],
  // 显示点上的数字
  label: {
    show: true,
    position: 'top',
    formatter: function (params) {
      // 在这里对数字进行转换
      return params.value + '%';
    },
  },
},

修改点击后的弹出框

tooltip: {
  textStyle: {
    fontSize: 14,    // 修改文字大小等其他样式
  },
  formatter: function (params) {
    console.log(params)
    // 在这里对 Tooltip 中的数字进行转换
    var result = `<span style="color: ${params.color};">${params.seriesName}&nbsp;&nbsp;${params.data}</span><br>`
    return result;
  },
}

在这里插入图片描述

完整

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>ECharts</title>
  <head>
    <meta charset="utf-8" />
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
  </head>
  <style>
  </style>
</head>

<body>
  <div class="test">
    <div id="main" style="width: 600px;height:600px;"></div>
  </div>
</body>
<script>
// import * as echarts from 'echarts';
var echarts = window.echarts
console.log('测试-', echarts)
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);

const polylineColor = '#e74c3c'
const bigBarColor = '#bdc3c7'
const smallBarColor = '#3498db'
const lineColor = '#bdc3c7'

/* eslint-disable @typescript-eslint/restrict-plus-operands */
/* eslint-disable no-plusplus */
/* eslint-disable radix */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable max-len */
// @ts-nocheck
// 两个时间相差几个小时
function calculateHours(startTime, endTime) {
  if (!startTime) return 0;
  if (!endTime) return 0;
  // 将时间字符串转换为 Date 对象
  const startDate = new Date(startTime);
  const endDate = new Date(endTime);

  // 计算时间差(毫秒)
  const timeDifference = endDate - startDate;

  // 将毫秒转换为分钟并取绝对值
  const minutesDifference = Math.abs(timeDifference / (1000 * 60));

  return minutesDifference / 60;
}

// 分钟转小时
function convertMinutesToHours(minutes) {
  if (typeof minutes !== 'number' || minutes < 0) {
    return 'Invalid input';
  }

  const hours = Math.floor(minutes / 60);
  const remainingMinutes = Math.floor(minutes % 60);

  return {
    hours,
    remainingMinutes,
  };
}

// 生成长度为n的二维空数组
function generateEmptyArray(n) {
  return Array.from({ length: n }, () => []);
}

// 时间减去n个小时后的时间
function subtractHours(dateTimeStr, hoursToSubtract) {
  // 辅助函数:在数字前补零,确保总是两位数
  function padZero(number) {
    return number.toString().padStart(2, '0');
  }
  // 解析日期时间字符串为 Date 对象
  const dateTimeParts = dateTimeStr.split(' ');
  const dateParts = dateTimeParts[0].split('-');
  const timeParts = dateTimeParts[1].split(':');
  const dateObj = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2], timeParts[0], timeParts[1]));

  // 减去指定的小时数
  dateObj.setUTCHours(dateObj.getUTCHours() - hoursToSubtract);

  // 格式化修改后的 Date 对象为字符串
  const formattedDate = `${dateObj.getUTCFullYear()}-${
    padZero(dateObj.getUTCMonth() + 1)}-${
    padZero(dateObj.getUTCDate())} ${
    padZero(dateObj.getUTCHours())}:${
    padZero(dateObj.getUTCMinutes())}`;

  // 返回结果
  return formattedDate;
}

// 获取数组最大值
function findMaxWakeNum(arr) {
  if (arr.length === 0) {
    return null; // 如果数组为空,返回null或其他你认为合适的默认值
  }

  const maxNumObject = arr.reduce((max, current) => ((current.nightWakeTimes > max.nightWakeTimes) ? current : max));

  return maxNumObject.nightWakeTimes;
}

// 获取数组最大值,如:10:00
function findMaxLeaveBedDate(arr) {
  // '2024-01-01 10:00' -> 10
  const changeNum = (str) => {
    if (!str) return 0;
    return parseInt(str.slice(11, 13));
  };
  if (!arr) {
    return null; // 如果数组为空,返回null或其他你认为合适的默认值
  }
  if (arr.length === 0) {
    return null; // 如果数组为空,返回null或其他你认为合适的默认值
  }

  const maxNumObject = arr.reduce((max, current) => ((changeNum(current.outOfBedDateTime) > changeNum(max.outOfBedDateTime)) ? current : max));

  if (!maxNumObject.outOfBedDateTime) return '10:00';

  const time = maxNumObject.outOfBedDateTime.slice(11, 16);
  const timeArr = time.split(':');
  let str = '';
  let tenthPlaceNum = '';
  const num = parseInt(timeArr[0]) + 1;
  if (num >= 10) {
    tenthPlaceNum = num;
  } else {
    tenthPlaceNum = `0${num}`;
  }
  if (timeArr[1] !== '00') {
    str = `${tenthPlaceNum}:00`;
  } else {
    str = time;
  }
  return str;
}

// 数组转换
// [
//   [1, 2],
//   [3, 4],
//   [5, 6],
//   [7, 8],
// ];
// [
//   [1, 3, 5, 7],
//   [2, 4, 6, 8],
// ];
function transposeArray(arr) {
  if (arr.length === 0) {
    return []; // 如果数组为空,返回空数组或其他你认为合适的默认值
  }

  const numRows = arr.length;
  const numCols = arr[0].length;

  // 初始化新的二维数组
  const transposedArray = Array.from({ length: numCols }, () => Array(numRows).fill(0));

  // 转置数组
  for (let i = 0; i < numRows; i++) {
    for (let j = 0; j < numCols; j++) {
      transposedArray[j][i] = arr[i][j];
    }
  }

  return transposedArray;
}

// '2024-01-01' -> 周一
function convertToWeekday(dateString) {
  const daysOfWeek = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];

  // 将日期字符串转换为Date对象
  const date = new Date(dateString);

  // 获取星期几的索引(0表示星期天,1表示星期一,以此类推)
  const dayOfWeekIndex = date.getDay();

  // 获取对应的星期几字符串
  const weekdayString = daysOfWeek[dayOfWeekIndex];

  return weekdayString;
}

// 夜间醒来次数的最大值
const handleSourceData = (sourceData, newTime) => {
  console.log('测试-sourceData', sourceData);
  // 我需要的数据
  const allDataObj = {
    xData: [],
    bedData: [],
    bedOpData: [],
    sleepData: [],
    sleepOpData: [],
    lineDataTemp: generateEmptyArray(sourceData.statisticsVoList.length),
    lineOpDataTemp: generateEmptyArray(sourceData.statisticsVoList.length),
    lineData: generateEmptyArray(sourceData.statisticsVoList.length),
    lineOpData: generateEmptyArray(sourceData.statisticsVoList.length),
    polylineData: [],
  };
  const maxNum = findMaxWakeNum(sourceData.statisticsVoList);
  sourceData.statisticsVoList.forEach((item, index) => {
    // eslint-disable-next-line no-param-reassign
    item.date = item.date.slice(0, 10);
    allDataObj.xData.push(convertToWeekday(item.date));
    // 1、黄色卧床透明柱子的数据
    const bedOpData = calculateHours(item.outOfBedDateTime, `${item.date} ${newTime}`);
    // 2、紫色睡眠透明柱子的数据
    const sleepOpData = calculateHours(item.wakeDateTime, `${item.date} ${newTime}`);
    // 3、黄色卧床柱子的数据
    const bedData = calculateHours(item.inBedDateTime, item.outOfBedDateTime);
    // 4、紫色睡眠柱子的数据
    const sleepData = calculateHours(item.asleepDateTime, item.wakeDateTime);
    // 5、柱子上的线,有个公式
    // const lineOpData = sleepOpData + (sleepData/(item.nightWakeTimes))*1
    // const lineData = 0.2
    allDataObj.bedData.push(bedData);
    allDataObj.bedOpData.push(bedOpData);
    allDataObj.sleepData.push(sleepData);
    allDataObj.sleepOpData.push(sleepOpData);
    if (item.nightWakeTimes) {
      for (let i = 0; i < item.nightWakeTimes; i++) {
        // 第n个线的oPdata
        const lineOpData = sleepOpData + (sleepData / (item.nightWakeTimes + 1)) * (i + 1);
        // 第n个线的data
        const lineData = item.nightWakeTotalMinutes / 60 / item.nightWakeTimes;
        allDataObj.lineDataTemp[index].push(lineData);
        allDataObj.lineOpDataTemp[index].push(lineOpData);
      }
    } else {
      for (let i = 0; i < maxNum; i++) {
        allDataObj.lineDataTemp[index].push(0);
        allDataObj.lineOpDataTemp[index].push(0);
      }
    }
    allDataObj.lineData = transposeArray(allDataObj.lineDataTemp);
    allDataObj.lineOpData = transposeArray(allDataObj.lineOpDataTemp);
    // 6、折线图
    allDataObj.polylineData.push(item.sleepEfficiency);
  });
  return allDataObj;
};

// 半夜醒来
const getNightWakeOption = (data, opData) => {
  let options = [];
  options = [
    // 透明柱子(黑色柱子下面)
    {
      name: 'Placeholder2',
      type: 'bar',
      stack: 'Total', // 为透明柱子指定不同的 stack
      stackStrategy: 'negative',
      itemStyle: {
        color: 'rgba(0,0,0,0)',
      },
      data: opData,
      yAxisIndex: 0, // 指定使用左侧 y 轴
      z: 0,
    },
    // 黑色柱子
    {
      name: '半夜醒来',
      type: 'bar',
      stack: 'Total',
      // stackStrategy: 'negative',
      itemStyle: {
        color: lineColor,
      },
      // 条的高度
      data,
      yAxisIndex: 0, // 指定使用左侧 y 轴
      z: 1,
    },
  ];
  return options;
};

// 半夜醒来(获取多条)
const getNightWakeOptionAll = (data, opData) => {
  let arr = [];
  data.forEach((item, index) => {
    const arrTemp = getNightWakeOption(data[index], opData[index]);
    arr = [...arr, ...arrTemp];
  });
  return arr;
};

// 卧床时长
const getBedTimeOption = (data, opData) => {
  let options = [];
  options = [
    // 透明柱子(黄色柱子下面)
    {
      name: 'Placeholder1',
      type: 'bar',
      stack: 'Total', // 为透明柱子指定不同的 stack
      // stackStrategy: 'negative',
      itemStyle: {
        color: 'rgba(0,0,0,0)',
      },
      data: opData,
      yAxisIndex: 0, // 指定使用左侧 y 轴
      z: 0,
    },
    // 黄色柱子
    {
      name: '卧床时长',
      type: 'bar',
      stack: 'Total',
      data,
      itemStyle: {
        color: bigBarColor,
        barBorderRadius: [8, 8, 8, 8],
      },
      yAxisIndex: 0, // 指定使用左侧 y 轴
      z: 1,
      tooltip: {
        show: true,
        textStyle: {
          color: bigBarColor,
        },
      },
    },
  ];
  return options;
};

// 睡眠时长
const getSleepTimeOption = (data, opData) => {
  let options = [];
  options = [
    // 透明柱子(紫色柱子下面)
    {
      name: 'Placeholder2',
      type: 'bar',
      stack: 'Total', // 为透明柱子指定不同的 stack
      stackStrategy: 'negative',
      itemStyle: {
        color: 'rgba(0,0,0,0)',
      },
      data: opData,
      yAxisIndex: 0, // 指定使用左侧 y 轴
      z: 0,
    },
    // 紫色柱子
    {
      name: '睡眠时长',
      type: 'bar',
      stack: 'Total',
      // stackStrategy: 'negative',
      itemStyle: {
        color: smallBarColor,
      },
      data,
      yAxisIndex: 0, // 指定使用左侧 y 轴
      z: 1,
      tooltip: {
        show: true,
        textStyle: {
          color: smallBarColor,
        },
      },
    },
  ];
  return options;
};

// 睡眠效率
const getSleepEfficiencyOption = (data) => {
  let options = [];
  options = [
    {
      name: '睡眠效率',
      type: 'line',
      data,
      symbol: 'circle',
      symbolSize: 8,
      lineStyle: {
        color: polylineColor, // 指定折线的颜色
        width: 2, // 指定折线的宽度
      },
      itemStyle: {
        color: polylineColor,
        borderColor: '#fff', // 白色边框
        borderWidth: 2, // 边框宽度
      },
      // 显示点上的数字
      label: {
        show: true,
        position: 'top',
        formatter(params) {
          // 在这里对数字进行转换
          return `${params.value}%`;
        },
        // color: '#333',
      },
      yAxisIndex: 1, // 指定使用右侧 y 轴
      tooltip: {
        show: true,
        textStyle: {
          color: polylineColor,
        },
      },
    },
  ];
  return options;
};

// 获取最终的图表配置
const getChartOptions = (allDataObj, newTime, thisWeekData) => {
  const option = {
    xAxis: {
      type: 'category',
      data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
      axisLabel: {
        textStyle: {
          color: '#999', // 设置文字颜色
        },
      },
      axisTick: {
        show: false, // 设置不显示刻度点
      },
    },
    yAxis: [
      {
        type: 'value', // 左侧 y 轴配置
        interval: 2, // 设置刻度的间隔
        axisLabel: {
          textStyle: {
            color: '#999', // 设置文字颜色
          },
          formatter(value) {
            // 在这里进行刻度值的转化,第一个值其实可以是任何一天的10点,因为在图表y轴逻辑上不关心是哪一天的10:00
            const data = subtractHours(`2024-02-02 ${newTime}`, value).slice(11);
            return data;
            // return value;
          },
        },
        // min: 0, // 设置最小值为0
        max: thisWeekData.sleepMinutesAverage ? null : 10, // 设置最大值为100
        name: '时间', // 设置 y 轴的名称
        // nameGap: 20, // 设置 y 轴名称的偏移量
        nameTextStyle: {
          align: 'right',
        },
      },
      {
        type: 'value', // 右侧 y 轴配置
        name: '效率', // 设置 y 轴的名称
        nameTextStyle: {
          align: 'left',
        },
        splitLine: {
          show: false, // 右侧 Y 轴不显示横线
        },
        min: 0, // 设置最小值为0
        max: 100, // 设置最大值为100
        interval: 20, // 设置刻度间隔为20
        axisTick: {
          show: false,
          inside: false,
          length: 5,
        },
        axisLine: {
          show: false, // 不显示轴线
        },
        axisLabel: {
          textStyle: {
            color: '#999', // 设置文字颜色
          },
        },
      },
    ],
    grid: {
      show: false,
      left: 50,
      top: 50,
    },
    legend: {
      orient: 'horizontal', // 设置图例的方向为水平
      bottom: 10, // 设置图例距离底部的距离
      itemGap: 20, // 设置图例项之间的距离
      data: ['卧床时长', '睡眠时长', '睡眠效率'], // 图例的名称,与 series 中的 name 对应
      // itemWidth: 12, // 设置图例项的宽度为10
      // itemHeight: 12, // 设置图例项的高度为10,即正方形
    },
    tooltip: {
      show: false,
      formatter(params) {
        let result = '';
        const { seriesName, seriesType, data } = params;
        if (seriesType === 'line') {
          result = `${seriesName} ${data}%`;
        }
        if (seriesType === 'bar') {
          const { hours, remainingMinutes } = convertMinutesToHours(data * 60);
          // 在这里对 Tooltip 中的数字进行转换
          result = `${seriesName} ${hours}h${remainingMinutes}m`;
          // result = `<view style="color: ${color};">${seriesName}&nbsp;&nbsp;${data}</view><br>`;
        }
        return result;
      },
      // textStyle: {
      //   color: '#8c7dc2',
      // },
    },
    series: [
      // 卧床时长
      ...getBedTimeOption(allDataObj.bedData, allDataObj.bedOpData),
      // 睡眠时长
      ...getSleepTimeOption(allDataObj.sleepData, allDataObj.sleepOpData),
      // 半夜醒来
      ...getNightWakeOptionAll(allDataObj.lineData, allDataObj.lineOpData),
      // // 睡眠效率折线图
      ...getSleepEfficiencyOption(allDataObj.polylineData),
    ],
  };
  return option;
};

const getResultChartOptions = (thisWeekData) => {
  // // 获取我要的周数据
  // const thisWeekData = getThisWeekData(sourceData);
  // 坐标上的10:00最新时间
  const newTime = findMaxLeaveBedDate(thisWeekData.statisticsVoList);
  // 处理得到我要的数据
  const allDataObjTemp = handleSourceData(thisWeekData, newTime);
  console.log('测试-处理得到我要的数据', allDataObjTemp);
  // 获取图表的配置
  const chartOptions = getChartOptions(allDataObjTemp, newTime, thisWeekData);
  return chartOptions;
};

// 原始数据
const sourceData = [
  {
    // 周开始时间
    startDateTime: '2024-01-29',
    // 周结束时间
    endDateTime: '2024-02-04',
    // 平均睡眠时长
    sleepMinutesAverage: 2323,
    // 平均入睡时长
    asleepMinutesAverage: 1000,
    // 平均卧床时长
    inBedMinutesAverage: 2000,
    // 平均睡眠效率
    sleepEfficiencyAverage: 20,
    statisticsVoList: [
      {
        // 卧床开始时间
        inBedDateTime: '2024-01-28 22:00',
        // 卧床结束时间
        outOfBedDateTime: '2024-01-29 12:30',
        // 睡眠开始时间
        asleepDateTime: '2024-01-28 23:00',
        // 睡眠结束时间
        wakeDateTime: '2024-01-29 09:00',
        // 夜间起来次数
        nightWakeTimes: 3,
        // 夜间起来总时长
        nightWakeTotalMinutes: 20,
        // 睡眠效率
        sleepEfficiency: 80,
        // 日期
        date: '2024-01-29',
        // 睡眠时长
        sleepMinutes: 368
      },
      {
        // 卧床开始时间
        inBedDateTime: '2024-01-29 21:00',
        // 卧床结束时间
        outOfBedDateTime: '2024-01-30 09:00',
        // 睡眠开始时间
        asleepDateTime: '2024-01-30 00:00',
        // 睡眠结束时间
        wakeDateTime: '2024-01-30 06:00',
        // 夜间起来次数
        nightWakeTimes: 2,
        // 夜间起来总时长
        nightWakeTotalMinutes: 20,
        // 睡眠效率
        sleepEfficiency: 60,
        // 日期
        date: '2024-01-30',
        // 睡眠时长
        sleepMinutes: 368
      },
      {
        // 卧床开始时间
        inBedDateTime: '2024-01-30 20:00',
        // 卧床结束时间
        outOfBedDateTime: '2024-01-31 08:00',
        // 睡眠开始时间
        asleepDateTime: '2024-01-31 00:00',
        // 睡眠结束时间
        wakeDateTime: '2024-01-31 06:00',
        // 夜间起来次数
        nightWakeTimes: 0,
        // 夜间起来总时长
        nightWakeTotalMinutes: 20,
        // 睡眠效率
        sleepEfficiency: 70,
        // 日期
        date: '2024-01-31',
        // 睡眠时长
        sleepMinutes: 368
      },
      {
        // 卧床开始时间
        inBedDateTime: '2024-01-31 20:00',
        // 卧床结束时间
        outOfBedDateTime: '2024-02-01 09:00',
        // 睡眠开始时间
        asleepDateTime: '2024-01-31 23:00',
        // 睡眠结束时间
        wakeDateTime: '2024-02-01 06:00',
        // 夜间起来次数
        nightWakeTimes: 2,
        // 夜间起来总时长
        nightWakeTotalMinutes: 20,
        // 睡眠效率
        sleepEfficiency: 90,
        // 日期
        date: '2024-02-01',
        // 睡眠时长
        sleepMinutes: 368
      },
    ]
  }
]

const chartOptions = getResultChartOptions(sourceData[0])
chartOptions && myChart.setOption(chartOptions)
console.log('测试-chartOptions', chartOptions)
</script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lvan的前端笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值