code: function calculateBase(groupItem) {
      var extent;
      var baseAxis = groupItem.axis;
      var seriesModels = groupItem.seriesModels;
      var seriesCount = seriesModels.length;
  
      var boxWidthList = groupItem.boxWidthList = [];
      var boxOffsetList = groupItem.boxOffsetList = [];
      var boundList = [];
  
      var bandWidth;
      if (baseAxis.type === 'category') {
          bandWidth = baseAxis.getBandWidth();
      }
      else {
          var maxDataCount = 0;
          each(seriesModels, function (seriesModel) {
              maxDataCount = Math.max(maxDataCount, seriesModel.getData().count());
          });
          extent = baseAxis.getExtent(),
          Math.abs(extent[1] - extent[0]) / maxDataCount;
      }
  
      each(seriesModels, function (seriesModel) {
          var boxWidthBound = seriesModel.get('boxWidth');
          if (!zrUtil.isArray(boxWidthBound)) {
              boxWidthBound = [boxWidthBound, boxWidthBound];
          }
          boundList.push([
              parsePercent(boxWidthBound[0], bandWidth) || 0,
              parsePercent(boxWidthBound[1], bandWidth) || 0
          ]);
      });
  
      var availableWidth = bandWidth * 0.8 - 2;
      var boxGap = availableWidth / seriesCount * 0.3;
      var boxWidth = (availableWidth - boxGap * (seriesCount - 1)) / seriesCount;
      var base = boxWidth / 2 - availableWidth / 2;
  
      each(seriesModels, function (seriesModel, idx) {
          boxOffsetList.push(base);
          base += boxGap + boxWidth;
  
          boxWidthList.push(
              Math.min(Math.max(boxWidth, boundList[idx][0]), boundList[idx][1])
          );
      });
  }
docs: Calculate offset and box width for each series.