1

先上效果图:
image.png

一般我们看到的柱状图,形态是这样的:
image.png
那相比于原始形态的柱状图,大致有以下变化:
1.柱状发生堆叠
2.柱状信息内容及鼠标悬浮框内容,增加了百分比的信息

这样修改的话可以让信息比对更加明显,视觉效果也更优

首先先来定义我们的数据源,每个人数据肯定不同,这里可以参考我的数据格式,对代码进行一定的修改,以便复用

{
        stack: { 名称: ["高", "较高", "一般", "差"] },
        columns: ["名称", "高", "较高", "一般", "差"],
        ifpercent: true,
        rows: [
          { 名称: "出勤率", 高: 276, 较高: 162, 一般: 28, 差: 1 },
          { 名称: "作业完成情况", 高: 6, 较高: 21, 一般: 172, 差: 268 },
          { 名称: "学习精力投入", 高: 220, 较高: 188, 一般: 59, 差: 0 },
          { 名称: "课外活动参与", 高: 218, 较高: 186, 一般: 62, 差: 1 }
        ]
      }

查阅官方文档我们可以发现,只要在chartSettings属性中设置 stack 字段,即可实现堆叠

所以我这里在数据源中自定义了一个 stack 字段以传入,stack 对象的定义格式为:
stack:{xxx:["x","y","z"......]}
数组中的几个属性即为你要选择堆叠的指标名称

设置完了 stack 我们可以获得以下效果:
image.png

接下来我们修改柱状图上显示的文字内容
我先按照我的数据格式,算出每一组的总分

this.chartData.rows.map((item, index) => {
        total = 0;
        this.chartData.columns.map((colitem, colindex) => {
          if (colindex != 0) {
            total += item[colitem];
          }
        });
        item.total = total;
      });

这里因为每个人数据格式不同,大家可以参照我的方法进行一定的修改
然后修改 chartsettings 属性中的 label 属性

 var that = this;
      this.chartSettings.label.normal.formatter = function(value, index) {
        var componentIndex = value.componentIndex;
        var totalcount = that.chartData.rows[componentIndex].total;
        return (
          ((value.data / totalcount).toFixed(4) * 100).toString().slice(0, 5) +
          "%"
        );
      };

我们把 formatter 方法中的 value 属性打印下来分析一下

image.png
componentIndex:表示每个堆叠后的柱状组的下标,对应图上内容即可以分成四个组
image.png
data:该指标的维度值

根据可知信息,即可拼接成比例形式的字符串内容,这里我们把数值保留两位小数

接下来我们再对鼠标悬浮内容进行自定义
我们对 options 对象进行修改

 options.tooltip = {
        trigger: "axis",
        axisPointer: {
          // 坐标轴指示器,坐标轴触发有效
          type: "shadow" // 默认为直线,可选为:'line' | 'shadow'
        },
        //数据格式
        formatter: function(params) {
          let dataFunction = function(params) {
            var componentIndex = params.componentIndex;
            var totalcount = that.chartData.rows[componentIndex].total;
            return (
              ((params.value / totalcount).toFixed(4) * 100)
                .toString()
                .slice(0, 5) + "%"
            );
          };
          String.prototype.splice = function(start, newStr) {
            return this.slice(0, start) + newStr + this.slice(start);
          };
         
          var str = "";

          params.map((item, index) => {
            str = that.chartData.ifpercent
              ? str.splice(
                  0,
                  item.marker +
                    item.seriesName +
                    " : " +
                    item.value +
                    " (" +
                    dataFunction(item) +
                    ") " +
                    "<br/>"
                )
              : str.splice(
                  0,
                  item.marker + item.seriesName + " : " + item.value
                );
          });
          str = str.splice(0, params[0].name + "<br/>");
          return str;
        }
      };

代码看不懂没关系,我们可以先来分析 params 参数的内容
image.png
params 一共有四个对象,分别对应的就是堆叠后的四个系列柱状
marker表示的是前面的小圆点
seriesName表示的是柱子的名字
value表示的是柱子的值

起初我采用的是按顺序拼接字符串

str+= item.marker +item.seriesName + " : " + item.value + " (" + dataFunction(item) + ") " +"<br/>"

但发现显示的顺序与柱状上下的堆叠顺序想法
于是重写了 splice 方法,使之可以向自己想插入的位置插入相应的字符串

 String.prototype.splice = function(start, newStr) {
            return this.slice(0, start) + newStr + this.slice(start);
          };

这样一来我们的功能就全部实现了
image.png


无锡肖奈
186 声望7 粉丝

十八线野生程序猿 前端开发