咱们先看看对比图,下图是echarts统计图放入数据不做处理的结果(只看蓝色柱子即可),可以看到柱状图不管数据时正数还是负数,都是以y=0为图形的起点
下图是我想要实现的效果,相当于是以y轴最小值为起点渲染柱子:
话不多说,直接上解决方案:
方案1:如果echarts版本是4.0.0以下(没记错的话),那么实现就很简单了
如果不知道使用的是什么版本的eacharts,可以打印console.log(echarts.version);看看是什么版本的,高于4.0版本的很有可能也是无法达到这个效果的
在xAxis内添加属性axisLine.onZero = false即可,代码如下:
xAxis: {
data: ['衬衫11111111111111111', '羊毛衫', '雪纺衫', '裤子', '高跟鞋'],
axisLine: {
onZero: false, //轴线是否在0刻度轴上
},
},
使用了axisLine.onZero = false但是达不到效果的话,可以直接引用以下版本看看能否实现,若能达到效果,八成是echarts版本问题了
<script crossorigin="anonymous" integrity="sha384-mYHbpb8SNpRR9uL7PfZoWk1rI3/VXsAkIC5Sy7+Aa7a79JKqZ19qg4OcgvgsCx36"
src="https://lib.baomitu.com/echarts/4.0.0/echarts.min.js"></script>
(ps:之前翻看了echarts GitHub上的问题记录, 5.5.0版本以后可以使用barSeries.startValue设置起始值,但是貌似目前这个版本还未发布,具体问题自行参考:https://github.com/apache/echarts/pull/17078)
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:500px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
let xData = ['衬衫11111111111111111', '羊毛衫', '雪纺衫', '裤子', '高跟鞋']
let data1 = [20, 8, -18, -26, -37] //bar1数据
let data2 = [] //bar2数据
// 计算y轴最小值(根据自己实际情况而定)-------------------------
let yMin = Math.ceil(Math.min(...data1))
if (yMin < 0) {
let numConvert = yMin;
numConvert = yMin * -1
let str = numConvert.toString().length;
let arr = [1, 10, 100, 1000, 10000]
let digit; //位数
let num = 1
if (str === 1) {
// 个位
digit = parseInt(yMin % 10);
if (digit < 0) {
num = -1
}
yMin = num * 10
} else {
digit = parseInt((yMin % arr[str]) / arr[str - 1]);
if (digit < 0) {
num = -1
}
yMin = (digit + num) * arr[str - 1]
}
//--------------------------------------------------
//bar2值设置
data1.forEach(item => {
if (item > 0) {
data2.push(yMin)
} else {
data2.push(item + yMin)
}
})
} else {
data2 = [0, 0, 0, 0, 0] //我这是柱状图固定只显示5个柱子,实际情况自行改逻辑
}
var option = {
tooltip: {
show: true,
trigger: 'axis',
formatter: function (par) {
return `${par[0].name}光功率:${par[0].value}`
}
},
xAxis: {
data: xData,
axisLabel: {
// 文字省略
formatter: function (value) {
// console.log('999--', value);
if (value.length > 3) {
return `${value.slice(0, 3)}...`
}
return value
}
},
axisLine: {
onZero: false, //轴线是否在0刻度轴上
},
},
yAxis: {
splitLine: { show: false },
min: yMin < 0 ? yMin : 0, //y最小值
},
series: [
{
name: '销量',
type: 'bar',
stack: 'one', //设置堆叠图
data: data1.map(item => {
return {
value: item,
label: {
formatter: '{c}' + 'db',
show: item > 0 ? true : false, //bar1数据大于0顶部显示提示文字
position: 'top',
textStyle: {
color: 'blue'
},
},
itemStyle: {
// 边框
borderColor: item > 0 ?"blue":"rgba(240, 240, 240,0)",
}
}
}),
barWidth: '50px', // 柱子宽度
itemStyle: {
normal: {
//bar1颜色控制,小于0,颜色与背景色相同,否则为蓝色
color: function (param) {
let color = "blue"
if (param.value < 0) {
color = "rgba(240, 240, 240,0)"
}
return color
},
}
},
//设置柱状图背景
showBackground: true,
backgroundStyle: {
color: 'rgba(180, 180, 180, 0.2)'
},
},
{
name: 'bar2',
type: 'bar',
stack: 'one',
itemStyle: {
normal: {
color: "blue",
borderColor: "blue", //边框
}
},
barWidth: '50px', // 柱子宽度
data: data2.map((item, index) => {
return {
value: item,
label: {
formatter: data1[index] + 'db',
//bar1当前数据小于0,bar2顶部显示提示文字,否则不显示
show: data1[index] < 0 ? true : false,
position: 'top',
textStyle: {
color: 'blue'
},
},
}
}),
},
]
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
完结~~~(方法不一定很好,仅供参考)