function positionElement(el, positionInfo, containerRect, margin, opt) {
  var h = !opt || !opt.hv || opt.hv[0];
  var v = !opt || !opt.hv || opt.hv[1];
  var boundingMode = opt && opt.boundingMode || 'all';

  if (!h && !v) {
    return;
  }

  var rect;

  if (boundingMode === 'raw') {
    rect = el.type === 'group' ? new core_BoundingRect(0, 0, +positionInfo.width || 0, +positionInfo.height || 0) : el.getBoundingRect();
  } else {
    rect = el.getBoundingRect();

    if (el.needLocalTransform()) {
      var transform = el.getLocalTransform(); // Notice: raw rect may be inner object of el,
      // which should not be modified.

      rect = rect.clone();
      rect.applyTransform(transform);
    }
  } // The real width and height can not be specified but calculated by the given el.


  var layoutRect = getLayoutRect(util_defaults({
    width: rect.width,
    height: rect.height
  }, positionInfo), containerRect, margin); // Because 'tranlate' is the last step in transform
  // (see zrender/core/Transformable#getLocalTransform),
  // we can just only modify el.position to get final result.

  var dx = h ? layoutRect.x - rect.x : 0;
  var dy = v ? layoutRect.y - rect.y : 0;

  if (boundingMode === 'raw') {
    el.x = dx;
    el.y = dy;
  } else {
    el.x += dx;
    el.y += dy;
  }

  el.markRedraw();
}
Position a zr element in viewport
 Group position is specified by either
 {left, top}, {right, bottom}
 If all properties exists, right and bottom will be igonred.

Logic:
    1. Scale (against origin point in parent coord)
    2. Rotate (against origin point in parent coord)
    3. Traslate (with el.position by this method)
So this method only fixes the last step 'Traslate', which does not affect
scaling and rotating.

If be called repeatly with the same input el, the same result will be gotten.

@param el Should have `getBoundingRect` method.
@param positionInfo
@param positionInfo.left
@param positionInfo.top
@param positionInfo.right
@param positionInfo.bottom
@param positionInfo.width Only for opt.boundingModel: 'raw'
@param positionInfo.height Only for opt.boundingModel: 'raw'
@param containerRect
@param margin
@param opt
@param opt.hv Only horizontal or only vertical. Default to be [1, 1]
@param opt.boundingMode
       Specify how to calculate boundingRect when locating.
       'all': Position the boundingRect that is transformed and uioned
              both itself and its descendants.
              This mode simplies confine the elements in the bounding
              of their container (e.g., using 'right: 0').
       'raw': Position the boundingRect that is not transformed and only itself.
              This mode is useful when you want a element can overflow its
              container. (Consider a rotated circle needs to be located in a corner.)
              In this mode positionInfo.width/height can only be number.