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 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.
    positionInfo = getLayoutRect(
        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 elPos = el.position;
    var dx = h ? positionInfo.x - rect.x : 0;
    var dy = v ? positionInfo.y - rect.y : 0;

    el.attr('position', boundingMode === 'raw' ? [dx, dy] : [elPos[0] + dx, elPos[1] + dy]);
}
Consider Case:
When defulat option has {left: 0, width: 100}, and we set {right: 0}
through setOption or media query, using normal zrUtil.merge will cause
{right: 0} does not take effect.

@example
ComponentModel.extend({
    init: function () {
        ...
        var inputPositionParams = layout.getLayoutParams(option);
        this.mergeOption(inputPositionParams);
    },
    mergeOption: function (newOption) {
        newOption && zrUtil.merge(thisOption, newOption, true);
        layout.mergeLayoutParam(thisOption, newOption);
    }
});

@param {Object} targetOption
@param {Object} newOption
@param {Object|string} [opt]
@param {boolean|Array.<boolean>} [opt.ignoreSize=false] Used for the components
 that width (or height) should not be calculated by left and right (or top and bottom).