最近遇到一个图表需要展示任务的计划时间和实际时间
常用echarts的大佬知道这是一个xy轴刻度对应两条柱子的图;
但是由于多个任务(刻度)开始的时间不一致可能不在0开始(多任务柱子开始位置)
需要展示两条柱子
let option = {
...
series:[
{
name: '计划时间',
type: 'bar',
data:[...]
},
{
name: '实际时间',
type: 'bar',
data:[...]
}
]
...
}
如上的option加上数据渲染出的如图
处理开始日期(值)不一样问题
开始日期不一样的(多个任务;任务一10月1日-10月10日;任务二10月2日开始)两个任务的开始位置是不一样的
我想到是用堆叠柱状图把开始日期空白的部分隐藏掉
let option = {
...
series:[
//用于开始位置空白的柱子要注意堆叠图的数组位置在前渲染时在前
{
name: '计划时间0',
type: 'bar',
stack: 'total1', //堆叠属性;计划时间的这里用的total1
data:[...],
label: {
show: false
},
itemStyle: { //隐藏柱子
opacity: 0,
},
},
{
name: '计划时间',
type: 'bar',
stack: 'total1',
data:[...]
},
//用于开始位置空白的柱子
{
name: '实际时间0',
type: 'bar',
stack: 'total2', //堆叠属性;实际时间的这里用的total2
data:[...],
label: {
show: false
},
itemStyle: { //隐藏柱子
opacity: 0,
},
}
{
name: '实际时间',
type: 'bar',
stack: 'total2', //堆叠属性;实际时间的这里用的total2
data:[...]
}
]
...
}
加上数据渲染可以看到效果如下
处理轴label显示
由于这个图的需求就是展示日期;后期数据可以使用时间戳;
通过时间戳在x或者y轴自定义渲染刻度
数据格式我这里是这样的
let date_timestr = +new Date();
//为什么有这个;这个作用于xy轴的自定义显示;
//因为echarts是从0开始的如果设置最小值为数据内的最小值;
//就会发现自定义x轴显示日期跨度非常之大不合理
// 这个变量在我们自定义是拼接格式化就好;
// 这个值是所有数据中最小的日期的时间戳
// 数据部分没有前面的年月 相当于只有任务的开始的天和结束的天;小时等等应该都可以吧
// 计划时间
let opacity_Data = [ //隐藏部分的;开始时间的 (几天几小时)
1000 * 60 * 60 * 24 * 2,
1000 * 60 * 60 * 24 * 4,
1000 * 60 * 60 * 24 * 2,
1000 * 60 * 60 * 24 * 10,
]
let high_Data = [ //高亮部分的;结束时间的
1000 * 60 * 60 * 24 * 5,
1000 * 60 * 60 * 24 * 10,
1000 * 60 * 60 * 24 * 100,
1000 * 60 * 60 * 24 * 50,
]
// 实际时间的
let opacity_Data2 = [
1000 * 60 * 60 * 24 * 2,
1000 * 60 * 60 * 24 * 4,
1000 * 60 * 60 * 24 * 2,
1000 * 60 * 60 * 24 * 10,
]
let high_Data2 = [
1000 * 60 * 60 * 24 * 10,
1000 * 60 * 60 * 24 * 7,
1000 * 60 * 60 * 24 * 10,
1000 * 60 * 60 * 24 * 55,
]
xAxis: {
type: 'value',
minInterval: 1000 * 60 * 60 * 24, //最小轴线分割 一天的的值 如果是小时自行修改
// 此处可
// 最大的用于限制x多刻度线的一刻度值 这里8天一刻度;其它的都可以多了如果要细致到小时等等自行修改
// 如果数据是天的且想要精确到一天甚至更小推荐添加滚动条
maxInterval: 1000 * 60 * 60 * 24 * 8, //最大轴线分割 一天的的值 如果是小时自行修改
axisLabel: {
fontSize: 12,
fontWeight: 600,
color: '#888',
formatter: function (val, index) {
let date_ = new Date(val + date_timestr);
let label_ = `${date_.getFullYear()}/${date_.getMonth() + 1}/${date_.getDate()}`;
return label_;
},
// maxInterval 的设置刻度较多旋转显示
rotate: 20
},
splitLine: {
show: true,
lineStyle: {
color: '#eee',
},
},
axisLine: {
show: false
}
},
完整代码
let date_timestr = +new Date(); //任务开始的最小值我这里就用的目前时间
date_timestr = +new Date('2022/10/19');
let opacity_Data = [ //隐藏部分的;开始时间的 (几天几小时)
1000 * 60 * 60 * 24 * 2,
1000 * 60 * 60 * 24 * 4,
1000 * 60 * 60 * 24 * 2,
1000 * 60 * 60 * 24 * 10,
]
let high_Data = [ //高亮部分的;结束时间的
1000 * 60 * 60 * 24 * 5,
1000 * 60 * 60 * 24 * 10,
1000 * 60 * 60 * 24 * 100,
1000 * 60 * 60 * 24 * 50,
]
let opacity_Data2 = [
1000 * 60 * 60 * 24 * 2,
1000 * 60 * 60 * 24 * 4,
1000 * 60 * 60 * 24 * 2,
1000 * 60 * 60 * 24 * 10,
]
let high_Data2 = [
1000 * 60 * 60 * 24 * 10,
1000 * 60 * 60 * 24 * 7,
1000 * 60 * 60 * 24 * 10,
1000 * 60 * 60 * 24 * 55,
]
const formatterTime = (d) => {
let d_ = new Date(d);
return `${d_.getFullYear()}/${d_.getMonth() + 1}/${d_.getDate()} ${d_.getHours()}:${d_.getMinutes()}:${d_.getSeconds()}`
}
let option = {
grid: {
containLabel: true,
right: '10%',
left: '5%',
bottom: '6%',
top: '10%',
},
legend: {
top: "5%",
data: ['计划时间', '实际时间'],
selectedMode: false, //这里禁止点击;需要的自己写事件使用filter动态setOption
textStyle: {
fontSize: 12,
fontWeight: 600
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
// Use axis to trigger tooltip
type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
},
formatter: function (ToolFormatterParam) {
let labels = `<div>
<b>${ToolFormatterParam[0].name}</b>
</div>`;
ToolFormatterParam.map((item) => {
let isSeriesNameZero = item.seriesName.includes('0');
if (!isSeriesNameZero) {
let startTime = ToolFormatterParam.filter((item2) => {
if (item2.seriesName.includes((item.seriesName + '0'))) {
return item2
}
})[0].value + date_timestr;
let endTime = null;
endTime = date_timestr + item.value;
let label_item = `<div>${item.seriesName}:${formatterTime(startTime)} 至 ${formatterTime(endTime)}</div>`
labels += label_item
}
})
return labels;
}
},
xAxis: {
type: 'value',
minInterval: 1000 * 60 * 60 * 24, //最小轴线分割 一天的的值 如果是小时自行修改
// 此处可
// 最大的用于限制x多刻度线的一刻度值 这里8天一刻度;其它的都可以多了如果要细致到小时等等自行修改
// 如果数据是天的且想要精确到一天甚至更小推荐添加滚动条
maxInterval: 1000 * 60 * 60 * 24 * 8, //最大轴线分割 一天的的值 如果是小时自行修改
axisLabel: {
fontSize: 12,
fontWeight: 600,
color: '#888',
formatter: function (val, index) {
let date_ = new Date(val + date_timestr);
let label_ = `${date_.getFullYear()}/${date_.getMonth() + 1}/${date_.getDate()}`;
return label_;
},
// maxInterval 的设置刻度较多旋转显示
rotate: 20
},
splitLine: {
show: true,
lineStyle: {
color: '#eee',
},
},
axisLine: {
show: false
}
},
yAxis: {
type: 'category',
inverse: true,
data: ['收购痛讯', '亿个小目标', '下一个小目标', '周游世界'],
axisLabel: {
color: '#333',
fontSize: 12,
fontWeight: 600
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
// k = 0,1 隐藏的;k=1,2高亮的
color: [
'#fff',
{
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: '#4297FE', // 0% 处的颜色
},
{
offset: 1,
color: '#007BFF', // 0% 处的颜色
},
],
global: false, // 缺省为 false
},
'#fff',
{
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: '#5198FF', // 0% 处的颜色
},
{
offset: 1,
color: '#8BF8FE', // 0% 处的颜色
},
],
global: false, // 缺省为 false
}
],
series: [
{
//开始空白(隐藏部分需要在后面加0)tooltip formatter内有判断需要修改注意
name: '计划时间0',
type: 'bar',
stack: 'total',
label: {
show: false
},
itemStyle: {
opacity: 0,
},
emphasis: {
focus: 'series'
},
barWidth: 24,
barGap: '10%',
data: opacity_Data
},
{
name: '计划时间',
type: 'bar',
stack: 'total',
label: {
show: false
},
emphasis: {
focus: 'series'
},
barWidth: 24,
barGap: '10%',
itemStyle: {
borderRadius: [6, 20, 20, 6]
},
data: high_Data
},
{
name: '实际时间0',
type: 'bar',
stack: 'total2',
label: {
show: false,
},
itemStyle: {
opacity: 0
},
barWidth: 24,
emphasis: {
focus: 'series'
},
barGap: '10%',
data: opacity_Data2
},
{
name: '实际时间',
type: 'bar',
stack: 'total2',
label: {
show: false
},
emphasis: {
focus: 'series'
},
barWidth: 24,
barGap: '10%',
itemStyle: {
borderRadius: [6, 20, 20, 6]
},
data: high_Data2
},
],
};
最终效果如图
echarts也是有xAxis,yAxis type:"time"的配置可以支持日期;
因为使用版本是v5.4.1的原因堆叠没有展示正确
同样代码3.x版本是这样的可以正常展示堆叠的