【Echarts】OMG!情人节那天,柱状图(bar)和时间轴(timeline)在一起了

假如提供了一份示例数据:

let data = {
	2011: 264,
	2012: 352,
	2013: 256,
	2014: 368,
	2015: 189,
	2016: 98,
	2017: 643,
	2018: 259,
	2019: 365,
	2020: 521,
};

我们通过Echarts提供的柱状图、时间轴组件简单地把数据展示出来:

let xData = [];
let yData = [];
for (let key in data) {
  xData.push(key);
  yData.push(data[key]);
}
let chartEl = document.getElementById("timeline");
let chart = echarts.init(chartEl);
let option = {
  timeline: {
    data: xData,
    axisType: "category",
    show: true,
    autoPlay: true,
    playInterval: 2000,
    bottom: 20,
    symbol: "emptyCircle",
    symbolSize: 5,
    color: "#0088cc",
    checkpointStyle: {
      symbolSize: 8,
      color: "#0088cc",
      borderColor: "rgba(0,136,204,0.5)"
    },
    controlStyle: {
      emphasis: {
        color: "#176FCC",
        borderColor: "#176FCC"
      }
    },
    label: {
      normal: {
        show: true
      }
    }
  },
  options: [
    {
      tooltip: {
        trigger: "axis"
      },
      grid: {
        y: 30,
        y2: 100,
      },
      xAxis: {
        type: 'category',
        data: xData
      },
      yAxis: {
        type: 'value'
      },
      series: [{
        type: "bar",
        barWidth: 30,
        color: '#298EF8'
      }]
    }
  ]
};
for (var j = 0; j < xData.length; j++) {
  option.options.push({
    series: [
      {
        data: yData
      }
    ]
  });
}
chart.setOption(option);

就可以看到 图1 这个结果:
在这里插入图片描述

BUT,柱状图和时间轴的刻度 “严重错位”,实在是看着难受,所以有强迫症的我决定改造改造。
首先,我们需要明白一个思路,想要让两个部分的刻度完全吻合,就必须保证两点:
1、保证柱状图的第一根柱子中心和时间轴的第一个刻度在同一个位置;
2、保证柱状图的最后一根柱子中心和时间轴的最后一个刻度在同一个位置。
简单来说,这不就是列两个等式,解这两个等式就可以了吗?!

设echarts容器的宽度为W,柱子个数为n,柱状图左边距为bl,右边距为br,时间轴左边距为tl,右边距为tr,最左端到第一个刻度的距离为x,最右端到最后一个刻度的距离为y(如图2
在这里插入图片描述
根据上面的两个保证,我们就可以列出如下两个等式

bl+(W-bl-br)/n/2 = tl+x
br+(W-bl-br)/n/2 = tr+y

不要被两个等式中这么多未知数吓到,可以简单思考一下,这两个等式中,有哪些值是可以取到,哪些值其实是固定值。
很显然,W、n可以取到,x、y是固定值,这样就只剩下了未知数bl、br、tl、tr。只要我们随意设置两个固定值,那么就可以求出另两个未知数。

由于柱状图左侧或者右侧会有内容,所以我们这里固定bl、br,这样上面的等式就可以改写为:

tl = bl+(W-bl-br)/n/2 - x
tr = br+(W-bl-br)/n/2 - y

修改代码:

let xData = [];
let yData = [];
for (let key in data) {
  xData.push(key);
  yData.push(data[key]);
}
let chartEl = document.getElementById("timeline");
let chartElWidth = chartEl.offsetWidth;
let chart = echarts.init(chartEl);
let barLeft = 100; // 修改内容
let barRight = 80; // 修改内容
let timelineLeft = barLeft + ((chartElWidth - barLeft - barRight) / xData.length / 2) - 74; // 修改内容
let timelineRight = barRight + (chartElWidth - barLeft - barRight) / xData.length / 2 - 40; // 修改内容
let option = {
  timeline: {
    data: xData,
    axisType: "category",
    show: true,
    autoPlay: true,
    playInterval: 2000,
    bottom: 20,
    left: timelineLeft, // 修改内容
    right: timelineRight, // 修改内容
    symbol: "emptyCircle",
    symbolSize: 5,
    color: "#0088cc",
    checkpointStyle: {
      symbolSize: 8,
      color: "#0088cc",
      borderColor: "rgba(0,136,204,0.5)"
    },
    controlStyle: {
      emphasis: {
        color: "#176FCC",
        borderColor: "#176FCC"
      }
    },
    label: {
      normal: {
        show: true
      }
    }
  },
  options: [
    {
      tooltip: {
        trigger: "axis"
      },
      grid: {
        y: 30,
        y2: 100,
        left: barLeft, // 修改内容
        right: barRight // 修改内容
      },
      xAxis: {
        type: 'category',
        data: xData
      },
      yAxis: {
        type: 'value'
      },
      series: [{
        type: "bar",
        barWidth: 30,
        color: '#298EF8'
      }]
    }
  ]
};
for (var j = 0; j < xData.length; j++) {
  option.options.push({
    series: [
      {
        data: yData
      }
    ]
  });
}
chart.setOption(option);

就会得到如下效果
在这里插入图片描述
PS:
实践中会发现,时间轴的最左端和最右端并不是肉眼可见的最左端和最右端,改造 图2 应该是如下 图4 这样
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值