diff --git a/src/component/dataRange/ContinuousModel.js b/src/component/dataRange/ContinuousModel.js index e11294e85fff2538cd5d20ca3b47e1b9f329dd71..dd4f628423a12e0e64b0d36b9d6d5491aa7bcbf6 100644 --- a/src/component/dataRange/ContinuousModel.js +++ b/src/component/dataRange/ContinuousModel.js @@ -121,8 +121,14 @@ define(function(require) { */ getValueState: function (value) { var range = this.option.range; - return (range[0] <= value && value <= range[1]) - ? 'inRange' : 'outOfRange'; + var dataExtent = this.getExtent(); + + // When range[0] === dataExtent[0], any value larger than dataExtent[0] maps to 'inRange'. + // range[1] is processed likewise. + return ( + (range[0] <= dataExtent[0] || range[0] <= value) + && (range[1] >= dataExtent[1] || value <= range[1]) + ) ? 'inRange' : 'outOfRange'; } }); diff --git a/src/component/dataRange/ContinuousView.js b/src/component/dataRange/ContinuousView.js index 92064ec3f0753e125bc032225e6308462ba27cd6..91d5d66e2a7002aa4f82fff8db7d180c1017129b 100644 --- a/src/component/dataRange/ContinuousView.js +++ b/src/component/dataRange/ContinuousView.js @@ -58,8 +58,8 @@ define(function(require) { * @protected * @override */ - doRender: function (dataRangeModel, ecModel, api, event) { - if (!event || event.type !== 'dataRangeSelected' || event.from !== this.uid) { + doRender: function (dataRangeModel, ecModel, api, payload) { + if (!payload || payload.type !== 'selectDataRange' || payload.from !== this.uid) { this._buildView(); } else { @@ -84,15 +84,19 @@ define(function(require) { this._renderBar(thisGroup); var dataRangeText = dataRangeModel.get('text'); - dataRangeText && this._renderEndsText(thisGroup, dataRangeText, 0); - dataRangeText && this._renderEndsText(thisGroup, dataRangeText, 1); + this._renderEndsText(thisGroup, dataRangeText, 0); + this._renderEndsText(thisGroup, dataRangeText, 1); + + // Do this for background size calculation. + this._updateView(true); // After updating view, inner shapes is built completely, // and then background can be rendered. - this._updateView(); - this.renderBackground(thisGroup); + // Real update view + this._updateView(); + this.positionGroup(thisGroup); }, @@ -100,7 +104,12 @@ define(function(require) { * @private */ _renderEndsText: function (group, dataRangeText, endsIndex) { - var text = dataRangeText[endsIndex]; + if (!dataRangeText) { + return; + } + + // Compatible with ec2, text[0] map to high value, text[1] map low value. + var text = dataRangeText[1 - endsIndex]; text = text != null ? text + '' : ''; var dataRangeModel = this.dataRangeModel; @@ -164,8 +173,6 @@ define(function(require) { // Handle if (useHandle) { - var handleEndsMax = [0, itemSize[1]]; - shapes.handleGroups = []; shapes.handleThumbs = []; shapes.handleLabels = []; @@ -173,9 +180,6 @@ define(function(require) { this._createHandle(barGroup, 0, itemSize, textSize, orient, itemAlign); this._createHandle(barGroup, 1, itemSize, textSize, orient, itemAlign); - - // Do this for background size calculation. - this._updateHandlePosition(handleEndsMax); } // Indicator @@ -313,14 +317,21 @@ define(function(require) { /** * @private */ - _updateView: function () { + _updateView: function (forSketch) { var dataRangeModel = this.dataRangeModel; var dataExtent = dataRangeModel.getExtent(); var shapes = this._shapes; var dataInterval = this._dataInterval; - var visualInRange = this._createBarVisual(dataInterval, dataExtent); - var visualOutOfRange = this._createBarVisual(dataExtent, dataExtent, 'outOfRange'); + var outOfRangeHandleEnds = [0, dataRangeModel.itemSize[1]]; + var inRangeHandleEnds = forSketch ? outOfRangeHandleEnds : this._handleEnds; + + var visualInRange = this._createBarVisual( + dataInterval, dataExtent, inRangeHandleEnds, 'inRange' + ); + var visualOutOfRange = this._createBarVisual( + dataExtent, dataExtent, outOfRangeHandleEnds, 'outOfRange' + ); shapes.inRange .setStyle('fill', visualInRange.barColor) @@ -347,52 +358,42 @@ define(function(require) { }, this); - this._updateHandlePosition(visualInRange.handleEnds); + this._updateHandlePosition(inRangeHandleEnds); }, /** * @private */ - _createBarVisual: function (dataInterval, dataExtent, forceState) { - var handleEnds = forceState - ? [0, this.dataRangeModel.itemSize[1]] - : this._handleEnds; - - var visuals = [ - this.getControllerVisual(dataInterval[0], forceState), - this.getControllerVisual(dataInterval[1], forceState) - ]; - - var colorStops = []; - var handles = []; - each(dataInterval, function (value, index) { - colorStops.push({offset: index, color: visuals[index].color}); - handles.push(visuals[index].color); - }); + _createBarVisual: function (dataInterval, dataExtent, handleEnds, forceState) { + var colorStops = this.getControllerVisual(dataInterval, forceState, 'color').color; - var barPoints = this._createBarPoints(handleEnds, visuals); + var symbolSizes = [ + this.getControllerVisual(dataInterval[0], forceState, 'symbolSize').symbolSize, + this.getControllerVisual(dataInterval[1], forceState, 'symbolSize').symbolSize + ]; + var barPoints = this._createBarPoints(handleEnds, symbolSizes); return { barColor: new LinearGradient(0, 0, 1, 1, colorStops), barPoints: barPoints, - handlesColor: handles, - handleEnds: handleEnds + handlesColor: [ + colorStops[0].color, + colorStops[colorStops.length - 1].color + ] }; }, /** * @private */ - _createBarPoints: function (handleEnds, visuals) { + _createBarPoints: function (handleEnds, symbolSizes) { var itemSize = this.dataRangeModel.itemSize; - var widths0 = visuals[0].symbolSize; - var widths1 = visuals[1].symbolSize; return [ - [itemSize[0] - widths0, handleEnds[0]], + [itemSize[0] - symbolSizes[0], handleEnds[0]], [itemSize[0], handleEnds[0]], [itemSize[0], handleEnds[1]], - [itemSize[0] - widths1, handleEnds[1]] + [itemSize[0] - symbolSizes[1], handleEnds[1]] ]; }, @@ -428,7 +429,7 @@ define(function(require) { var handleGroup = shapes.handleGroups[handleIndex]; handleGroup.position[1] = handleEnds[handleIndex]; - // Update handle label location + // Update handle label position. var labelPoint = shapes.handleLabelPoints[handleIndex]; var textPoint = modelUtil.applyTransform( [labelPoint.x, labelPoint.y], diff --git a/src/component/dataRange/DataRangeModel.js b/src/component/dataRange/DataRangeModel.js index aea549c42c90ec3c62fa836eb97c4222564469f7..547553df3821cdcf5076ce3732d58f6d72d39970 100644 --- a/src/component/dataRange/DataRangeModel.js +++ b/src/component/dataRange/DataRangeModel.js @@ -74,9 +74,9 @@ define(function(require) { itemWidth: null, // 值域图形宽度 itemHeight: null, // 值域图形高度 precision: 0, // 小数精度,默认为0,无小数点 - color: ['#e0ffff', '#006edd'],//颜色(deprecated,兼容ec2) + color: ['#e0ffff', '#006edd'], //颜色(deprecated,兼容ec2,对应数值由高到低) // formatter: null, - // text:['高','低'], // 文本,默认为数值文本 + text: null, // 文本,如['高', '低'],兼容ec2,text[0]对应高值,text[1]对应低值 textStyle: { color: '#333' // 值域文字颜色 } @@ -320,12 +320,14 @@ define(function(require) { function completeSingle(base) { // Compatible with ec2 dataRange.color. + // The mapping order of dataRange.color is: [high value, ..., low value] + // whereas inRange.color and outOfRange.color is [low value, ..., high value] if (zrUtil.isArray(thisOption.color) // If there has been inRange: {symbol: ...}, adding color is a mistake. // So adding color only when no inRange defined. && !base.inRange ) { - base.inRange = {color: thisOption.color.slice()}; + base.inRange = {color: thisOption.color.slice().reverse()}; } // If using shortcut like: {inRange: 'symbol'}, complete default value. @@ -420,11 +422,7 @@ define(function(require) { * @protected */ resetItemSize: function () { - var api = this.api; - this.itemSize = [ - parsePercent(this.get('itemWidth'), api.getWidth()), - parsePercent(this.get('itemHeight'), api.getHeight()) - ]; + this.itemSize = [+this.get('itemWidth'), +this.get('itemHeight')]; }, /** diff --git a/src/component/dataRange/DataRangeView.js b/src/component/dataRange/DataRangeView.js index 3f1fe52b9cbb603aea40a9c1b06d40be6c645915..f24694b78a1c33fb16d06398f882802391ebec64 100644 --- a/src/component/dataRange/DataRangeView.js +++ b/src/component/dataRange/DataRangeView.js @@ -46,7 +46,7 @@ define(function (require) { /** * @protected */ - render: function (dataRangeModel, ecModel, api, event) { + render: function (dataRangeModel, ecModel, api, payload) { this.dataRangeModel = dataRangeModel; if (dataRangeModel.get('show') === false) { @@ -84,15 +84,29 @@ define(function (require) { /** * @protected + * @param {(number|Array)} targetValue + * @param {string=} forceState Specify state, instead of using getValueState method. + * @param {string=} visualType Specify visual type, defualt all available visualTypes. */ - getControllerVisual: function (representValue, forceState) { + getControllerVisual: function (targetValue, forceState, visualType) { var dataRangeModel = this.dataRangeModel; + var targetIsArray = zrUtil.isArray(targetValue); + + // targetValue is array when caculate gradient color, + // where forceState is required. + if (targetIsArray && (!forceState || visualType !== 'color')) { + throw new Error(targetValue); + } + var mappings = dataRangeModel.controllerVisuals[ - forceState || dataRangeModel.getValueState(representValue) + forceState || dataRangeModel.getValueState(targetValue) ]; + var defaultColor = dataRangeModel.get('contentColor'); var visualObj = { symbol: dataRangeModel.get('itemSymbol'), - color: dataRangeModel.get('contentColor') + color: targetIsArray + ? [{color: defaultColor, offset: 0}, {color: defaultColor, offset: 1}] + : defaultColor }; function getter(key) { @@ -105,10 +119,12 @@ define(function (require) { : (visualObj[key] = value); } - zrUtil.each(mappings, function (visualMapping) { - visualMapping && visualMapping.applyVisual( - representValue, getter, setter - ); + zrUtil.each(mappings, function (visualMapping, type) { + (!visualType || type === visualType) + && visualMapping + && visualMapping.applyVisual( + targetValue, getter, setter + ); }); return visualObj; diff --git a/src/component/dataRange/PiecewiseModel.js b/src/component/dataRange/PiecewiseModel.js index a802dd9b0d332d55f4f41267f88d4ad1d215e30e..37d8c516ec4baf8d8ae4fb65d76e34a8400f1107 100644 --- a/src/component/dataRange/PiecewiseModel.js +++ b/src/component/dataRange/PiecewiseModel.js @@ -19,7 +19,7 @@ define(function(require) { itemWidth: 20, // 值域图形宽度,线性渐变水平布局宽度为该值 * 10 itemHeight: 14, // 值域图形高度,线性渐变垂直布局高度为该值 * 10 itemSymbol: 'roundRect', - splitList: null, + splitList: null, // 值顺序:由高到低 selectedMode: 'multiple', itemGap: 10 // 各个item之间的间隔,单位px,默认为10, // 横向布局时为水平间隔,纵向布局时为纵向间隔 @@ -32,6 +32,7 @@ define(function(require) { this.baseMergeOption(newOption); /** + * Compatible with ec2, value order is [high, ..., low] * [{text: string, interval: Array.}, ...] * * @private diff --git a/src/component/dataRange/PiecewiseView.js b/src/component/dataRange/PiecewiseView.js index 432b7e7aadd94e0d42c04ff9cb5c8d43a40c5f98..e0464c0170c97f76b8bbc097a81a580f64164888 100644 --- a/src/component/dataRange/PiecewiseView.js +++ b/src/component/dataRange/PiecewiseView.js @@ -23,18 +23,19 @@ define(function(require) { var api = this.api; var ecWidth = api.getWidth(); var textGap = dataRangeModel.get('textGap'); - var dataRangeText = dataRangeModel.get('text'); var font = dataRangeModel.textStyleModel.getFont(); - var showLabel = !dataRangeText; - var showEndsText = !showLabel; var itemAlign = this.getItemAlignByOrient('horizontal', ecWidth); var itemSize = dataRangeModel.itemSize; - showEndsText && this._renderEndsText(thisGroup, dataRangeText[0], itemSize); + var viewData = this._getViewData(); + var showLabel = !viewData.endsText; + var showEndsText = !showLabel; + + showEndsText && this._renderEndsText(thisGroup, viewData.endsText[1], itemSize); - zrUtil.each(this._getViewPieceList(), renderItem, this); + zrUtil.each(viewData.pieceList, renderItem, this); - showEndsText && this._renderEndsText(thisGroup, dataRangeText[1], itemSize); + showEndsText && this._renderEndsText(thisGroup, viewData.endsText[0], itemSize); layout.box( dataRangeModel.get('orient'), thisGroup, dataRangeModel.get('itemGap') @@ -91,20 +92,30 @@ define(function(require) { /** * @private + * @return {Object} {peiceList, endsText} value order is [low, ..., high] */ - _getViewPieceList: function () { + _getViewData: function () { var dataRangeModel = this.dataRangeModel; - var list = zrUtil.map(dataRangeModel.getPieceList(), function (piece, index) { + + var pieceList = zrUtil.map(dataRangeModel.getPieceList(), function (piece, index) { return {piece: piece, index: index}; }); + var endsText = dataRangeModel.get('text'); + + // Consider orient and inverse. var orient = dataRangeModel.get('orient'); var inverse = dataRangeModel.get('inverse'); if (orient === 'horizontal' ? inverse : !inverse) { - list.reverse(); + // Value order of pieceList is [high, ..., low] + pieceList.reverse(); + // Value order of endsText is [high, low] + if (endsText) { + endsText = endsText.slice().reverse(); + } } - return list; + return {pieceList: pieceList, endsText: endsText}; }, /** diff --git a/src/component/dataZoom/DataZoomView.js b/src/component/dataZoom/DataZoomView.js index 1f42dfc228cf096840af7eaff96f6e0d15e1122e..135fec6160de94b42f88bec89aa17b5a49ab6192 100644 --- a/src/component/dataZoom/DataZoomView.js +++ b/src/component/dataZoom/DataZoomView.js @@ -86,7 +86,7 @@ define(function (require) { this.api = api; }, - render: function (dataZoomModel, ecModel, api, event) { + render: function (dataZoomModel, ecModel, api, payload) { this.dataZoomModel = dataZoomModel; this.ecModel = ecModel; this._orient = dataZoomModel.get('orient'); @@ -97,7 +97,7 @@ define(function (require) { return; } - if (!event || event.type !== 'dataZoom' || event.from !== this.uid) { + if (!payload || payload.type !== 'dataZoom' || payload.from !== this.uid) { this._buildView(); } diff --git a/src/echarts.js b/src/echarts.js index 39153cc8c44dab92edd5b5c4a0c5299d4b7603d5..06cb1ebafc41873e8aa1b3126e7a531be920b0ca 100644 --- a/src/echarts.js +++ b/src/echarts.js @@ -124,9 +124,7 @@ define(function (require) { var ecModel = this._model; if (!ecModel || notMerge) { - ecModel = new GlobalModel( - option, null, this._theme, this._extensionAPI - ); + ecModel = new GlobalModel(option, null, this._theme); this._model = ecModel; } else { @@ -210,15 +208,15 @@ define(function (require) { /** * @pubilc - * @param {Object} event - * @param {string} [event.type] Event type - * @param {number} [event.from] From uid + * @param {Object} payload + * @param {string} [payload.type] Event type + * @param {number} [payload.from] From uid */ - dispatch: function (event) { - var action = actions[event.type]; + dispatch: function (payload) { + var action = actions[payload.type]; if (action) { - action(event, this._model); - this.updateImmediately(event); + action(payload, this._model); + this.updateImmediately(payload); } }, diff --git a/src/model/Component.js b/src/model/Component.js index 2e2c3f44f1e6f726b372ed565357e52271e511e1..8b9c8519d15d1021ca7f76317c2abb1a74a7ffac 100644 --- a/src/model/Component.js +++ b/src/model/Component.js @@ -47,11 +47,6 @@ define(function(require) { */ uid: null, - /** - * @readOnly - */ - api: null, - init: function () { this.mergeDefaultAndTheme(this.option, this.ecModel); }, @@ -85,11 +80,10 @@ define(function(require) { // Reset ComponentModel.extend, add preConstruct. componentUtil.enableClassExtend( ComponentModel, - function (option, parentModel, ecModel, dependentModels, index, api) { + function (option, parentModel, ecModel, dependentModels) { this.ecModel = ecModel; this.dependentModels = dependentModels; this.uid = componentUtil.getUID('componentModel'); - this.api = api; } ); diff --git a/src/model/Global.js b/src/model/Global.js index 3a949f5354f564da8c60b6dad2468cefc7a03806..7abc4e59acff4d08e54d1e653df15034d7c36f53 100644 --- a/src/model/Global.js +++ b/src/model/Global.js @@ -27,12 +27,11 @@ define(function (require) { constructor: GlobalModel, - init: function (option, parentModel, theme, api) { + init: function (option, parentModel, theme) { theme = theme || {}; this.option = {}; - this.api = api; /** * @type {Array.