提交 e24dba70 编写于 作者: P pah100

udpate datazoom, list, action

上级 da4fed1f
...@@ -5,7 +5,7 @@ define(function(require) { ...@@ -5,7 +5,7 @@ define(function(require) {
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
var echartsAPIList = [ var echartsAPIList = [
'getZr', 'update', 'getCoordinateSystem', 'getWidth', 'getHeight' 'getZr', 'getCoordinateSystem', 'getWidth', 'getHeight', 'dispatch'
]; ];
function ExtensionAPI(echarts) { function ExtensionAPI(echarts) {
......
...@@ -19,7 +19,7 @@ define(function (require) { ...@@ -19,7 +19,7 @@ define(function (require) {
var data = seriesModel.getData(); var data = seriesModel.getData();
data.diff(this._data) data.diff(this._data)
.add(function (dataItem, idx) { .add(function (dataItem, dataIndex) {
// 空数据 // 空数据
if (dataItem.getValue() == null) { if (dataItem.getValue() == null) {
return; return;
...@@ -48,7 +48,7 @@ define(function (require) { ...@@ -48,7 +48,7 @@ define(function (require) {
// Animation // Animation
rect.animateTo({ rect.animateTo({
shape: layout shape: layout
}, 1000, 300 * dataItem.dataIndex / data.elements.length, 'cubicOut'); }, 1000, 300 * dataIndex / data.count(), 'cubicOut');
}) })
.update(function (newData, oldData) { .update(function (newData, oldData) {
var el = oldData.__el; var el = oldData.__el;
......
...@@ -66,11 +66,13 @@ define(function(require) { ...@@ -66,11 +66,13 @@ define(function(require) {
this._polyline = polyline; this._polyline = polyline;
} }
else { else {
this._polyline.animateShape() // this._polyline.animateShape()
.when(500, { // .when(500, {
points: points // points: points
}) // })
.start('cubicOut'); // .start('cubicOut');
this._polyline.shape.points = points;
this._polyline.dirty(true);
} }
this._data = data; this._data = data;
......
...@@ -5,6 +5,7 @@ define(function (require) { ...@@ -5,6 +5,7 @@ define(function (require) {
ecModel.eachSeriesByType('line', function (lineSeries) { ecModel.eachSeriesByType('line', function (lineSeries) {
var data = lineSeries.getData(); var data = lineSeries.getData();
var coords = lineSeries.coordinateSystem.dataToCoords(data); var coords = lineSeries.coordinateSystem.dataToCoords(data);
data.each(function (dataItem, idx) { data.each(function (dataItem, idx) {
var coord = coords[idx]; var coord = coords[idx];
var value = dataItem.getValue(); var value = dataItem.getValue();
......
...@@ -92,9 +92,7 @@ define(function(require) { ...@@ -92,9 +92,7 @@ define(function(require) {
p1[0] = p2[0] = this._axisLinePosition; p1[0] = p2[0] = this._axisLinePosition;
} }
api.subPixelOptimizeLine(p1, p2, lineWidth); this.group.add(new api.Line(api.subPixelOptimizeLine({
this.group.add(new api.Line({
shape: { shape: {
x1: p1[0], x1: p1[0],
y1: p1[1], y1: p1[1],
...@@ -106,7 +104,7 @@ define(function(require) { ...@@ -106,7 +104,7 @@ define(function(require) {
}, lineStyleModel.getLineStyle()), }, lineStyleModel.getLineStyle()),
z: axisModel.get('z'), z: axisModel.get('z'),
silent: true silent: true
})); })));
}, },
/** /**
...@@ -144,7 +142,7 @@ define(function(require) { ...@@ -144,7 +142,7 @@ define(function(require) {
|| i % (tickInterval + 1) || i % (tickInterval + 1)
) )
) { ) {
continue continue;
} }
var tickCoord = ticksCoords[i]; var tickCoord = ticksCoords[i];
...@@ -173,16 +171,18 @@ define(function(require) { ...@@ -173,16 +171,18 @@ define(function(require) {
var p1 = [x, y]; var p1 = [x, y];
var p2 = [x + offX, y + offY]; var p2 = [x + offX, y + offY];
api.subPixelOptimizeLine(p1, p2, tickLineWidth);
// Tick line // Tick line
tickLines.push(new api.Line({ tickLines.push(new api.Line(api.subPixelOptimizeLine({
shape: { shape: {
x1: p1[0], x1: p1[0],
y1: p1[1], y1: p1[1],
x2: p2[0], x2: p2[0],
y2: p2[1] y2: p2[1]
},
style: {
lineWidth: tickLineWidth
} }
})); })));
} }
var tickEl = api.mergePath(tickLines, { var tickEl = api.mergePath(tickLines, {
style: lineStyleModel.getLineStyle(), style: lineStyleModel.getLineStyle(),
...@@ -218,7 +218,7 @@ define(function(require) { ...@@ -218,7 +218,7 @@ define(function(require) {
var labels; var labels;
if (axis.scale.type === 'ordinal') { if (axis.scale.type === 'ordinal') {
labels = zrUtil.map(ticks, zrUtil.bind(axis.scale.getItem, axis.scale)); labels = zrUtil.map(ticks, axis.scale.getItem, axis.scale);
} }
else { else {
labels = ticks.slice(); labels = ticks.slice();
...@@ -229,8 +229,8 @@ define(function(require) { ...@@ -229,8 +229,8 @@ define(function(require) {
for (var i = 0; i < ticks.length; i++) { for (var i = 0; i < ticks.length; i++) {
// Default is false // Default is false
showList[i] = false; showList[i] = false;
needsCheckTextSpace = false; needsCheckTextSpace = false;
var tick = ticks[i];
// Only ordinal scale support label interval // Only ordinal scale support label interval
if (axis.scale.type === 'ordinal') { if (axis.scale.type === 'ordinal') {
...@@ -239,14 +239,14 @@ define(function(require) { ...@@ -239,14 +239,14 @@ define(function(require) {
} }
if (isLabelIntervalFunction if (isLabelIntervalFunction
&& !labelInterval(tick, axis.scale.getItem(tick)) && !labelInterval(tick, axis.scale.getItem(tick))
|| tick % (labelInterval + 1)) { || tick % (labelInterval + 1)
) {
continue; continue;
} }
} }
var x; var x;
var y; var y;
var tick = ticks[i];
var tickCoord = axis.dataToCoord(tick); var tickCoord = axis.dataToCoord(tick);
var labelTextAlign = 'center'; var labelTextAlign = 'center';
var labelTextBaseline = 'middle'; var labelTextBaseline = 'middle';
...@@ -353,18 +353,20 @@ define(function(require) { ...@@ -353,18 +353,20 @@ define(function(require) {
p2[0] = gridRect.x + gridRect.width; p2[0] = gridRect.x + gridRect.width;
p2[1] = tickCoord; p2[1] = tickCoord;
} }
api.subPixelOptimizeLine(p1, p2, lineWidth);
var colorIndex = (lineCount++) % lineColors.length; var colorIndex = (lineCount++) % lineColors.length;
splitLines[colorIndex] = splitLines[colorIndex] || []; splitLines[colorIndex] = splitLines[colorIndex] || [];
splitLines[colorIndex].push(new api.Line({ splitLines[colorIndex].push(new api.Line(api.subPixelOptimizeLine({
shape: { shape: {
x1: p1[0], x1: p1[0],
y1: p1[1], y1: p1[1],
x2: p2[0], x2: p2[0],
y2: p2[1] y2: p2[1]
},
style: {
lineWidth: lineWidth
} }
})); })));
} }
// Simple optimization // Simple optimization
......
...@@ -6,5 +6,6 @@ define(function (require) { ...@@ -6,5 +6,6 @@ define(function (require) {
require('./dataZoom/DataZoomModel'); require('./dataZoom/DataZoomModel');
require('./dataZoom/DataZoomView'); require('./dataZoom/DataZoomView');
require('./dataZoom/dataZoomProcessor'); require('./dataZoom/dataZoomProcessor');
require('./dataZoom/dataZoomAction');
}); });
\ No newline at end of file
define(function (require) {
var zrUtil = require('zrender/core/util');
var helper = require('./helper');
var retrieveValue = helper.retrieveValue;
var linearMap = require('../../util/number').linearMap;
var round = Math.round;
// Constants
var DEFAULT_LOCATION_EDGE_GAP = 2;
var DEFAULT_FILLER_SIZE = 30;
function DataZoomLayout(dataZoomModel, ecModel, api) {
/**
* @readOnly
*/
this.dataZoomModel = dataZoomModel;
/**
* @readOnly
*/
this.ecModel = ecModel;
/**
* @readOnly
*/
this.api = api;
/**
* @private
*/
this._orient = dataZoomModel.get('orient');
/**
* @readOnly
* @type {Object}
*/
this.layout = {
viewRange: {
// handle1 may less than handle2,
// so we dont naming them as 'start', 'end'
handle1: null,
handle2: null
},
/**
* {
* x: {number},
* y: {number},
* width: {number},
* height: {number}
* }
* @type {Object}
*/
location: {},
filler: {
shape: {}
},
startHandle: {
shape: {}
},
endHandle: {
shape: {}
},
startFrame: {
shape: {}
},
endFrame: {
shape: {}
}
};
}
DataZoomLayout.prototype = {
constructor: DataZoomLayout,
/**
* @public
*/
reset: function () {
this._initLocation();
this._initViewRange();
this.update();
},
/**
* @public
* @param {Object} dataZoomModel
* @param {Object} operation If empty, just re-calculate layout.
* @param {string} [operation.rangeArgs] ['start'] or ['end'] or ['start', 'end']
* @param {number} [operation.dx]
* @param {number} [operation.dy]
*/
update: function (operation) {
operation && this._updateViewRange(operation);
this._orient === 'horizontal'
? this._updateWidgetsLayoutHorizontally()
: this._updateWidgetsLayoutVertically();
},
/**
* @public
* @return {Object} {start, end}
*/
normalizeToRange: function () {
var viewRange = this.layout.viewRange;
var viewExtend = [0, this._getViewTotalLength()];
var percentExtent = [0, 100];
var range = {
start: linearMap(viewRange.handle1, viewExtend, percentExtent, true),
end: linearMap(viewRange.handle2, viewExtend, percentExtent, true)
};
// Auto exchange
if (range.start > range.end) {
range.start = [range.end, range.end = range.start][0];
}
return range;
},
/**
* @private
*/
_initLocation: function () {
var dataZoomModel = this.dataZoomModel;
var x;
var y;
var width;
var height;
// If some of x/y/width/height are not specified, auto-adapt according to target grid.
var gridRect = this._findGridRectForLocating();
if (this._orient === 'horizontal') { // Horizontal layout
width = retrieveValue(dataZoomModel.get('width'), gridRect.width);
height = retrieveValue(dataZoomModel.get('height'), DEFAULT_FILLER_SIZE);
x = retrieveValue(dataZoomModel.get('x'), gridRect.x);
y = retrieveValue(
dataZoomModel.get('y'),
(this.api.getHeight() - height - DEFAULT_LOCATION_EDGE_GAP)
);
}
else { // Vertical layout
width = retrieveValue(dataZoomModel.get('width'), DEFAULT_FILLER_SIZE);
height = retrieveValue(dataZoomModel.get('height'), gridRect.height);
x = retrieveValue(dataZoomModel.get('x'), DEFAULT_LOCATION_EDGE_GAP);
y = retrieveValue(dataZoomModel.get('y'), gridRect.y);
}
this.layout.location = {
x: x, y: y, width: width, height: height
};
},
/**
* @private
*/
_findGridRectForLocating: function () {
// Find the grid coresponding to the first axis referred by dataZoom.
var axisModel;
var dataZoomModel = this.dataZoomModel;
var ecModel = this.ecModel;
helper.eachAxisDim(function (dimNames) {
var axisIndices = dataZoomModel.get(dimNames.axisIndex);
if (!axisModel && axisIndices.length) {
axisModel = ecModel.getComponent(dimNames.axis, axisIndices[0]);
}
});
return ecModel
.getComponent('grid', axisModel.get('gridIndex'))
.coordinateSystem
.getRect();
},
/**
* @private
*/
_initViewRange: function () {
// Based on layout.location.
var range = this.dataZoomModel.getRange();
var viewExtend = [0, this._getViewTotalLength()];
var percentExtent = [0, 100];
this.layout.viewRange = {
handle1: round(linearMap(range.start, percentExtent, viewExtend, true)),
handle2: round(linearMap(range.end, percentExtent, viewExtend, true))
};
},
/**
* @private
* @param {Object} dataZoomModel
* @param {Object} operation
* @param {string} [operation.rangeArgs] ['handle1'] or ['handle2'] or ['handle1', 'handle2']
* @param {number} [operation.dx]
* @param {number} [operation.dy]
*/
_updateViewRange: function (operation) {
var delta = retrieveValue(
this._orient === 'horizontal' ? operation.dx : operation.dy,
0
);
var standardValue = delta > 0 ? Number.MIN_VALUE : Number.MAX_VALUE;
var methods = ['min', 'max'];
var methodIndex = delta > 0 ? 1 : 0;
var edgeValue = delta > 0 ? this._getViewTotalLength() : 0;
zrUtil.each(operation.rangeArgs, function (rangeArg) {
var value = this.layout.viewRange[rangeArg];
standardValue = Math[methods[methodIndex]](standardValue, value);
}, this);
var standardValueResult = Math[methods[1 - methodIndex]](standardValue + delta, edgeValue);
delta = standardValueResult - standardValue;
zrUtil.each(operation.rangeArgs, function (rangeArg) {
this.layout.viewRange[rangeArg] += delta;
}, this);
},
/**
* @private
*/
_getViewTotalLength: function () {
var location = this.layout.location;
return this._orient === 'horizontal' ? location.width : location.height;
},
/**
* @private
*/
_updateWidgetsLayoutHorizontally: function () {
// Based on layout.viewRange and this.layout.location.
var dataZoomModel = this.dataZoomModel;
var layout = this.layout;
var location = layout.location;
var handleSize = dataZoomModel.get('handleSize');
var viewRange = layout.viewRange;
var viewRangeStart = Math.min(viewRange.handle1, viewRange.handle2);
var viewRangeEnd = Math.max(viewRange.handle1, viewRange.handle2);
var fillerStyle = layout.filler.shape = {
x: location.x + viewRangeStart + handleSize,
y: location.y,
width: viewRangeEnd - viewRangeStart - handleSize * 2,
height: location.height
};
var handleBase = {
shape: {
y: location.y,
width: handleSize,
height: location.height
}
};
var handles = [
zrUtil.merge(
{
shape: {x: fillerStyle.x - handleSize}
},
handleBase
),
zrUtil.merge(
{
shape: {x: fillerStyle.x + fillerStyle.width}
},
handleBase
)
];
var handle1Index = viewRange.handle1 > viewRange.handle2 ? 1 : 0;
layout.handle1 = handles[handle1Index];
layout.handle2 = handles[1 - handle1Index];
var startHandleShape = handles[0].shape;
var endHandleShape = handles[1].shape;
layout.startFrame = {
shape: {
x: location.x,
y: location.y,
width: startHandleShape.x - location.x,
height: location.height
}
};
layout.endFrame = {
shape: {
x: endHandleShape.x + endHandleShape.width,
y: location.y,
width: location.x + location.width
- (endHandleShape.x + endHandleShape.width),
height: location.height
}
};
},
/**
* @private
*/
_updateWidgetsLayoutVertically: function () {
// Based on layout.viewRange and this.layout.location.
var dataZoomModel = this.dataZoomModel;
var layout = this.layout;
var location = layout.location;
var handleSize = dataZoomModel.get('handleSize');
var viewRange = layout.viewRange;
var viewRangeStart = Math.min(viewRange.handle1, viewRange.handle2);
var viewRangeEnd = Math.max(viewRange.handle1, viewRange.handle2);
var fillerStyle = layout.filler.shape = {
x: location.x,
y: location.y + viewRangeStart + handleSize,
width: location.width,
height: viewRangeEnd - viewRangeStart - handleSize * 2
};
var handleBase = {
shape: {
x: location.x,
width: location.width,
height: handleSize
}
};
var handles = [
zrUtil.merge(
{
shape: {y: fillerStyle.y - handleSize}
},
handleBase
),
layout.endHandle = zrUtil.merge(
{
shape: {y: fillerStyle.y + fillerStyle.height}
},
handleBase
)
];
var handle1Index = viewRange.handle1 > viewRange.handle2 ? 1 : 0;
layout.handle1 = handles[handle1Index];
layout.handle2 = handles[1 - handle1Index];
var startHandleShape = handles[0].shape;
var endHandleShape = handles[1].shape;
layout.startFrame = {
shape: {
x: location.x,
y: location.y,
width: location.width,
height: startHandleShape.y - location.y
}
};
layout.endFrame = {
shape: {
x: location.x,
y: endHandleShape.y + endHandleShape.height,
width: location.width,
height: location.y + location.height
- (endHandleShape.y + endHandleShape.height)
}
};
}
};
return DataZoomLayout;
});
\ No newline at end of file
...@@ -14,12 +14,43 @@ define(function(require) { ...@@ -14,12 +14,43 @@ define(function(require) {
dependencies: ['xAxis', 'yAxis', 'series'], dependencies: ['xAxis', 'yAxis', 'series'],
/**
* @protected
*/
defaultOption: {
zlevel: 0, // 一级层叠
z: 4, // 二级层叠
show: false,
orient: 'horizontal', // 布局方式,默认为水平布局,可选为:
// 'horizontal' ¦ 'vertical'
// x: {number}, // 水平安放位置,默认为根据grid参数适配,可选为:
// {number}(x坐标,单位px)
// y: {number}, // 垂直安放位置,默认为根据grid参数适配,可选为:
// {number}(y坐标,单位px)
// width: {number}, // 指定宽度,横向布局时默认为根据grid参数适配
// height: {number}, // 指定高度,纵向布局时默认为根据grid参数适配
backgroundColor: 'rgba(0,0,0,0)', // 背景颜色
dataBackgroundColor: '#eee', // 数据背景颜色
fillerColor: 'rgba(144,197,237,0.2)', // 填充颜色
handleColor: 'rgba(70,130,180,0.8)', // 手柄颜色
handleSize: 10,
showDetail: true,
// xAxisIndex: [], // 默认控制所有横向类目
// yAxisIndex: [], // 默认控制所有横向类目
start: 0, // 默认为0
end: 100, // 默认为全部 100%
start2: 0, // 默认为0
end2: 100, // 默认为全部 100%
realtime: true
// zoomLock: false // 是否锁定选择区域大小
},
/** /**
* @override * @override
*/ */
init: function (option, parentModel, ecModel) { init: function (option, parentModel, ecModel) {
this.mergeDefaultAndTheme(option, ecModel); this.mergeDefaultAndTheme(option, ecModel);
this.mergeOption(); this.mergeOption({});
}, },
/** /**
...@@ -48,12 +79,12 @@ define(function(require) { ...@@ -48,12 +79,12 @@ define(function(require) {
var thisOption = this.option; var thisOption = this.option;
var noAxisDefined = true; var noAxisDefined = true;
helper.eachAxisDim(function (names) { helper.eachAxisDim(function (dimNames) {
// Overlap these arrays but not merge. // Overlap these arrays but not merge.
var axisIndices = helper.toArray(helper.retrieveValue( var axisIndices = helper.toArray(helper.retrieveValue(
newOption[names.axisIndex], thisOption[names.axisIndex], [] newOption[dimNames.axisIndex], thisOption[dimNames.axisIndex], []
)); ));
var axisModels = this.dependentModels[names.axis]; var axisModels = this.dependentModels[dimNames.axis];
// If not specified, set default. // If not specified, set default.
if (axisModels.length && !axisIndices.length) { if (axisModels.length && !axisIndices.length) {
...@@ -63,7 +94,7 @@ define(function(require) { ...@@ -63,7 +94,7 @@ define(function(require) {
} }
} }
} }
thisOption[names.axisIndex] = axisIndices; thisOption[dimNames.axisIndex] = axisIndices;
if (axisIndices.length) { if (axisIndices.length) {
noAxisDefined = false; noAxisDefined = false;
...@@ -80,9 +111,9 @@ define(function(require) { ...@@ -80,9 +111,9 @@ define(function(require) {
// both xAxis and yAxis which type is 'value'. // both xAxis and yAxis which type is 'value'.
this.ecModel.eachSeries(function (seriesModel) { this.ecModel.eachSeries(function (seriesModel) {
if (this._isSeriesHasAllAxesTypeOf(seriesModel, 'value')) { if (this._isSeriesHasAllAxesTypeOf(seriesModel, 'value')) {
helper.eachAxisDim(function (names) { helper.eachAxisDim(function (dimNames) {
var axisIndices = thisOption[names.axisIndex]; var axisIndices = thisOption[dimNames.axisIndex];
var axisIndex = seriesModel.get(names.axisIndex); var axisIndex = seriesModel.get(dimNames.axisIndex);
if (zrUtil.indexOf(axisIndices, axisIndex) < 0) { if (zrUtil.indexOf(axisIndices, axisIndex) < 0) {
axisIndices.push(axisIndex); axisIndices.push(axisIndex);
} }
...@@ -98,9 +129,9 @@ define(function(require) { ...@@ -98,9 +129,9 @@ define(function(require) {
// 例如series.type === scatter时。 // 例如series.type === scatter时。
var is = true; var is = true;
helper.eachAxisDim(function (names) { helper.eachAxisDim(function (dimNames) {
var seriesAxisIndex = seriesModel.get(names.axisIndex); var seriesAxisIndex = seriesModel.get(dimNames.axisIndex);
var axisModel = this.dependentModels[names.axis][seriesAxisIndex]; var axisModel = this.dependentModels[dimNames.axis][seriesAxisIndex];
if (!axisModel || axisModel.get('type') !== axisType) { if (!axisModel || axisModel.get('type') !== axisType) {
is = false; is = false;
...@@ -122,9 +153,9 @@ define(function(require) { ...@@ -122,9 +153,9 @@ define(function(require) {
// When only xAxisIndex or only yAxisIndex is specified, start/end controls them. // When only xAxisIndex or only yAxisIndex is specified, start/end controls them.
// targetDim === false means that both xAxisIndex and yAxisIndex are specified. // targetDim === false means that both xAxisIndex and yAxisIndex are specified.
var targetDim; var targetDim;
helper.eachAxisDim(function (names) { helper.eachAxisDim(function (dimNames) {
if (thisOption[names.axisIndex].length) { if (thisOption[dimNames.axisIndex].length) {
targetDim = targetDim !== false ? false : names.dim; targetDim = targetDim !== false ? false : dimNames.dim;
} }
}); });
...@@ -136,7 +167,7 @@ define(function(require) { ...@@ -136,7 +167,7 @@ define(function(require) {
targetDim2 = targetDim === 'x' ? 'y' : 'x'; targetDim2 = targetDim === 'x' ? 'y' : 'x';
} }
var optAttrs = []; var optAttrs = {};
optAttrs[targetDim] = {start: 'start', end: 'end'}; optAttrs[targetDim] = {start: 'start', end: 'end'};
targetDim2 && (optAttrs[targetDim2] = {start: 'start2', end: 'end2'}); targetDim2 && (optAttrs[targetDim2] = {start: 'start2', end: 'end2'});
...@@ -156,13 +187,45 @@ define(function(require) { ...@@ -156,13 +187,45 @@ define(function(require) {
}); });
thisOption[dimItem.start] = startValue; thisOption[dimItem.start] = startValue;
thisOption[dimItem.end] = endValue; thisOption[dimItem.end] = endValue;
}); }, this);
if (!targetDim2) { if (!targetDim2) {
thisOption.start2 = thisOption.end2 = null; thisOption.start2 = thisOption.end2 = null;
} }
}, },
/**
* @public
* @param {Function} callback param: axisModel, dimNames, axisIndex, dataZoomModel, ecModel
*/
eachTargetAxis: function (callback, context) {
var ecModel = this.ecModel;
helper.eachAxisDim(function (dimNames) {
zrUtil.each(
this.get(dimNames.axisIndex),
function (axisIndex) {
callback.call(context, dimNames, axisIndex, this, ecModel);
},
this
);
}, this);
},
/**
* @public
* @param {string} dimName 'x', 'y', 'z'
* @param {number} axisIndex
*/
getTargetSeriesModels: function (dimName, axisIndex) {
var seriesModels = [];
this.ecModel.eachSeries(function (seriesModel) {
if (axisIndex === seriesModel.get(dimName + 'AxisIndex')) {
seriesModels.push(seriesModel);
}
});
return seriesModels;
},
/** /**
* @public * @public
* @param {Object} param * @param {Object} param
...@@ -193,37 +256,6 @@ define(function(require) { ...@@ -193,37 +256,6 @@ define(function(require) {
star2: thisOption.star2, star2: thisOption.star2,
end2: thisOption.end2 end2: thisOption.end2
}; };
},
/**
* @protected
*/
defaultOption: {
zlevel: 0, // 一级层叠
z: 4, // 二级层叠
show: false,
orient: 'horizontal', // 布局方式,默认为水平布局,可选为:
// 'horizontal' ¦ 'vertical'
// x: {number}, // 水平安放位置,默认为根据grid参数适配,可选为:
// {number}(x坐标,单位px)
// y: {number}, // 垂直安放位置,默认为根据grid参数适配,可选为:
// {number}(y坐标,单位px)
// width: {number}, // 指定宽度,横向布局时默认为根据grid参数适配
// height: {number}, // 指定高度,纵向布局时默认为根据grid参数适配
backgroundColor: 'rgba(0,0,0,0)', // 背景颜色
dataBackgroundColor: '#eee', // 数据背景颜色
fillerColor: 'rgba(144,197,237,0.2)', // 填充颜色
handleColor: 'rgba(70,130,180,0.8)', // 手柄颜色
handleSize: 8,
showDetail: true,
// xAxisIndex: [], // 默认控制所有横向类目
// yAxisIndex: [], // 默认控制所有横向类目
start: 0, // 默认为0
end: 100, // 默认为全部 100%
start2: 0, // 默认为0
end2: 100, // 默认为全部 100%
realtime: true
// zoomLock: false // 是否锁定选择区域大小
} }
}); });
......
...@@ -2,19 +2,35 @@ define(function (require) { ...@@ -2,19 +2,35 @@ define(function (require) {
var echarts = require('../../echarts'); var echarts = require('../../echarts');
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
var helper = require('./helper'); var DataZoomLayout = require('./DataZoomLayout');
var retrieveValue = helper.retrieveValue; var graphic = require('../../util/graphic');
// Constants // Constants
var DEFAULT_LOCATION_EDGE_GAP = 2; var DEFAULT_FRAME_BORDER_WIDTH = 1;
var DEFAULT_FILLER_SIZE = 30; var DEFAULT_HANDLE_INNER_COLOR = '#fff';
return echarts.extendComponentView({ return echarts.extendComponentView({
type: 'dataZoom', type: 'dataZoom',
init: function (echarts) { init: function (echarts) {
this._location; /**
* @private
* @type {Object}
*/
this._updatableShapes = {};
/**
* @private
* @type {module:echarts/component/dataZoom/DataZoomLayout}
*/
this._layout;
/**
* @private
* @type {string}
*/
this._orient;
}, },
render: function (dataZoomModel, ecModel, api, event) { render: function (dataZoomModel, ecModel, api, event) {
...@@ -22,9 +38,10 @@ define(function (require) { ...@@ -22,9 +38,10 @@ define(function (require) {
// 需要区别用户事件在本component上触发的render和其他render。 // 需要区别用户事件在本component上触发的render和其他render。
// 后者不重新构造shape。否则难于实现拖拽。 // 后者不重新构造shape。否则难于实现拖拽。
this._dataZoomModel = dataZoomModel; this.dataZoomModel = dataZoomModel;
this._ecModel = ecModel; this.ecModel = ecModel;
this._api = api; this.api = api;
this._orient = dataZoomModel.get('orient'); this._orient = dataZoomModel.get('orient');
if (!event || event.type !== 'dataZoom' || event.from !== this.uid) { if (!event || event.type !== 'dataZoom' || event.from !== this.uid) {
...@@ -35,288 +52,198 @@ define(function (require) { ...@@ -35,288 +52,198 @@ define(function (require) {
} }
// Layout // Layout
this._updateLocation(); this._layout = new DataZoomLayout(dataZoomModel, ecModel, api);
this._updateSliderRange({init: true}); this._layout.reset();
this._updateWidgetSize();
// Render // Render
this._renderBackground(); this._renderBackground();
this._renderDataShadow(); this._renderDataShadow();
this._renderFrame();
this._renderFiller();
this._renderHandle();
} }
}, },
/**
* 根据选项计算实体的位置坐标
*/
_updateLocation: function () {
var dataZoomModel = this._dataZoomModel;
var x;
var y;
var width;
var height;
// If some of x/y/width/height are not specified, auto-adapt according to target grid.
var gridRect = this._findGridRectForLocating();
if (this._orient === 'horizontal') { // Horizontal layout
width = retrieveValue(dataZoomModel.get('width'), gridRect.width);
height = retrieveValue(dataZoomModel.get('height'), DEFAULT_FILLER_SIZE);
x = retrieveValue(dataZoomModel.get('x'), gridRect.x);
y = retrieveValue(
dataZoomModel.get('y'), (api.getHeight() - height - DEFAULT_LOCATION_EDGE_GAP)
);
}
else { // Vertical layout
width = retrieveValue(dataZoomModel.get('width'), DEFAULT_FILLER_SIZE);
height = retrieveValue(dataZoomModel.get('height'), gridRect.height);
x = retrieveValue(dataZoomModel.get('x'), DEFAULT_LOCATION_EDGE_GAP);
y = retrieveValue(dataZoomModel.get('y'), gridRect.y);
}
this._location = {
x: x, y: y, width: width, height: height
};
},
/**
* @private
* @param {Object} dataZoomModel
* @param {Object} operation
* @param {boolean} [operation.init]
* @param {string} [operation.rangeArg] 'start' or 'end'
* @param {number} [operation.dx]
* @param {number} [operation.dy]
*/
_updateSliderRange: function (operation) {
// Based on this._location.
if (operation.init) {
var dataZoomModel = this._dataZoomModel;
var range = dataZoomModel.getRange();
var sliderTotalLength = this._getSliderTotalLength();
this._sliderRange = {
start: Math.round(range.start * 100 / sliderTotalLength),
end: Math.round(range.end * 100 / sliderTotalLength)
};
}
if (operation.rangeArg) {
this._sliderRange[operation.rangeArg] += this._getSliderDelta(operation);
}
},
_getSliderTotalLength: function () {
var location = this._location;
return this._orient === 'horizontal' ? location.width : location.height;
},
_getSliderDelta: function (operation) {
return retrieveValue(
this._orient === 'horizontal' ? operation.dx : operation.dy,
0
);
},
_normalizeToRange: function () {
var sliderTotalLength = this._getSliderTotalLength();
var sliderRange = this._sliderRange;
return {
start: sliderRange.start / sliderTotalLength * 100,
end: sliderRange.end / sliderTotalLength * 100
};
},
_updateWidgetSize: function () {
// Based on this._sliderRange and this._location.
var dataZoomModel = this._dataZoomModel;
var sliderRange = this._sliderRange;
var location = this._location;
var handleSize = dataZoomModel.get('handleSize');
var widgetSize = this._widgetSize = {};
if (dataZoomModel.get('orient') === 'horizontal') {
widgetSize.filler = {
x: location.x + sliderRange.start + handleSize,
y: location.y,
width: sliderRange.end - sliderRange.start - handleSize * 2,
height: location.height
};
}
else { // 'vertical'
widgetSize.filler = {
x: location.x,
y: location.y + sliderRange.start + handleSize,
width: location.width,
height: sliderRange.end - sliderRange.start - handleSize * 2
};
}
},
_findGridRectForLocating: function () {
// Find the grid coresponding to the first axis referred by dataZoom.
var axisModel;
var dataZoomModel = this._dataZoomModel;
var ecModel = this._ecModel;
helper.eachAxisDim(function (dimNames) {
var axisIndices = dataZoomModel.get(dimNames.axisIndex);
if (!axisModel && axisIndices.length) {
axisModel = ecModel.get(dimNames.axis)[axisIndices[0]];
}
});
return ecModel.getComponent('grid', axisModel.get('gridIndex')).getRect();
},
_renderBackground : function () { _renderBackground : function () {
var dataZoomModel = this._dataZoomModel; var dataZoomModel = this.dataZoomModel;
var location = this._location; var location = this._layout.layout.location;
this.group.push(new api.Rect({ this.group.add(new this.api.Rect({
// FIXME // FIXME
// zlevel: this.getZlevelBase(), // zlevel: this.getZlevelBase(),
// z: this.getZBase(), // z: this.getZBase(),
hoverable:false, hoverable:false,
style: { shape: {
x: location.x, x: location.x,
y: location.y, y: location.y,
width: location.width, width: location.width,
height: location.height, height: location.height
color: dataZoomModel.get('backgroundColor') },
style: {
fill: dataZoomModel.get('backgroundColor')
} }
})); }));
}, },
_renderFrame: function () {
var updatableShapes = this._updatableShapes;
var layout = this._layout.layout;
var baseFrame = {
// FIXME
// zlevel: this.getZlevelBase(),
// z: this.getZBase(),
hoverable: false,
style: {
stroke: this.dataZoomModel.get('handleColor'),
lineWidth: DEFAULT_FRAME_BORDER_WIDTH,
fill: 'rgba(0,0,0,0)'
}
};
this.group
.add(updatableShapes.startFrame = new this.api.Rect(zrUtil.mergeAll(
{},
baseFrame,
layout.startFrame
)))
.add(updatableShapes.endFrame = new this.api.Rect(zrUtil.mergeAll(
{},
baseFrame,
layout.endFrame
)));
},
_renderDataShadow: function () { _renderDataShadow: function () {
// Data shadow // Data shadow
// TODO // TODO
}, },
_renderFiller: function () { _renderFiller: function () {
var dataZoomModel = this._dataZoomModel; this.group.add(
var orient = dataZoomModel.get('orient'); this._updatableShapes.filler = new this.api.Rect(zrUtil.merge(
this._fillerShape = new api.Rect({
// FIXME
// zlevel: this.getZlevelBase(),
// z: this.getZBase(),
draggable: true,
ondrift: zrUtil.bind(this._onDrift, this, 'both'),
ondragend: zrUtil.bind(this._onDragEnd, this),
style: zrUtil.merge(
{ {
color: dataZoomModel.get('fillerColor'), // FIXME
text: orient === 'horizontal' ? ':::' : '::', // zlevel: this.getZlevelBase(),
textPosition : 'inside' // z: this.getZBase(),
draggable: this._orient,
drift: zrUtil.bind(this._onDrift, this, this._getUpdateArgs()),
ondragend: zrUtil.bind(this._onDragEnd, this),
style: {
fill: this.dataZoomModel.get('fillerColor'),
text: this._orient === 'horizontal' ? ':::' : '::',
textPosition : 'inside'
}
// FIXME
// highlightStyle: {
// brushType: 'fill',
// color: 'rgba(0,0,0,0)'
// }
}, },
this._widgetSize this._layout.layout.filler
), ))
highlightStyle: { );
brushType: 'fill',
color: 'rgba(0,0,0,0)'
}
});
this.group.push(this._fillerShape);
}, },
_renderHandle : function () { _renderHandle: function () {
var detail = this.zoomOption.showDetail ? this._getDetail() : {start: '',end: ''}; var dataZoomModel = this.dataZoomModel;
this._startShape = { var layout = this._layout.layout;
zlevel: this.getZlevelBase(), var updatableShapes = this._updatableShapes;
z: this.getZBase(), // FIXME
draggable : true, // var detailInfo = this.zoomOption.showDetail ? this._getDetail() : {start: '',end: ''};
style : {
iconType: 'rectangle', var baseHandle = {
x: this._location.x, // FIXME
y: this._location.y, // zlevel: this.getZlevelBase(),
width: this._handleSize, // z: this.getZBase(),
height: this._handleSize, draggable: this._orient,
color: this.zoomOption.handleColor, style: {
fill: dataZoomModel.get('handleColor'),
textColor: DEFAULT_HANDLE_INNER_COLOR,
text: '=', text: '=',
textPosition: 'inside' textPosition: 'inside'
}, }
highlightStyle: { // FIXME
text: detail.start, // highlightStyle: {
brushType: 'fill', // text: detail.start,
textPosition: 'left' // brushType: 'fill',
}, // textPosition: 'left'
ondrift: this._ondrift, // },
ondragend: this._ondragend
}; };
if (this.zoomOption.orient === 'horizontal') { this.group
this._startShape.style.height = this._location.height; .add(updatableShapes.handle1 = new this.api.Rect(zrUtil.mergeAll(
this._endShape = zrUtil.clone(this._startShape); {
drift: zrUtil.bind(this._onDrift, this, this._getUpdateArgs('handle1')),
ondragend: zrUtil.bind(this._onDragEnd, this)
},
baseHandle,
layout.handle1
)))
.add(updatableShapes.handle2 = new this.api.Rect(zrUtil.mergeAll(
{
drift: zrUtil.bind(this._onDrift, this, this._getUpdateArgs('handle2')),
ondragend: zrUtil.bind(this._onDragEnd, this)
},
baseHandle,
layout.handle2
)));
},
this._startShape.style.x = this._fillerShae.style.x - this._handleSize, _updateView: function () {
this._endShape.style.x = this._fillerShae.style.x + this._fillerShae.style.width; // Only shape can be modified.
this._endShape.highlightStyle.text = detail.end; // So only update shape for convenience and performance.
this._endShape.highlightStyle.textPosition = 'right'; zrUtil.each(this._updatableShapes, function (shape, name) {
shape.attr('shape', subPixelOptimize(this._layout.layout[name].shape, name));
}, this);
function subPixelOptimize(shape, name) {
var subPixelOptimizeLineWidth = {
startFrame: DEFAULT_FRAME_BORDER_WIDTH,
endFrame: DEFAULT_FRAME_BORDER_WIDTH
};
if (subPixelOptimizeLineWidth.hasOwnProperty(name)) {
shape = graphic.subPixelOptimizeRect({
shape: shape,
style: {lineWidth: subPixelOptimizeLineWidth[name]}
}).shape;
}
return shape;
} }
else { },
this._startShape.style.width = this._location.width;
this._endShape = zrUtil.clone(this._startShape);
this._startShape.style.y = this._fillerShae.style.y + this._fillerShae.style.height;
this._startShape.highlightStyle.textPosition = 'bottom';
this._endShape.style.y = this._fillerShae.style.y - this._handleSize; _getUpdateArgs: function (arg) {
this._endShape.highlightStyle.text = detail.end; return (!arg || this.dataZoomModel.get('zoomLock'))
this._endShape.highlightStyle.textPosition = 'top'; ? ['handle1', 'handle2']
} : [arg];
this._startShape = new IconShape(this._startShape);
this._endShape = new IconShape(this._endShape);
this.shapeList.push(this._startShape);
this.shapeList.push(this._endShape);
}, },
_onDrift : function (rangeArg, dx, dy) { _onDrift: function (rangeArgs, dx, dy) {
var dataZoomModel = this._dataZoomModel; var dataZoomModel = this.dataZoomModel;
if (rangeArg === 'both' || dataZoomModel.get('zoomLock')) { this._layout.update({rangeArgs: rangeArgs, dx: dx, dy: dy});
this._updateSliderRange({rangeArg: 'start', dx: dx, dy: dy});
this._updateSliderRange({rangeArg: 'end', dx: dx, dy: dy});
}
else { // rangeArg === 'start' or 'end'
this._updateSliderRange({rangeArg: rangeArg, dx: dx, dy: dy});
}
// FIXME this._updateView();
// refresh shape location
// FIXME
if (dataZoomModel.get('realtime')) { if (dataZoomModel.get('realtime')) {
// this._syncData(); // FIXME
} // if (this.zoomOption.showDetail) {
// }
// FIXME
if (this.zoomOption.showDetail) { this.api.dispatch({
// var detail = this._getDetail(); type: 'dataZoom',
// this._startShape.style.text = this._startShape.highlightStyle.text = detail.start; from: this.uid,
// this._endShape.style.text = this._endShape.highlightStyle.text = detail.end; dataZoomRange: this._layout.normalizeToRange(),
// this._startShape.style.textPosition = this._startShape.highlightStyle.textPosition; dataZoomModel: this.dataZoomModel
// this._endShape.style.textPosition = this._endShape.highlightStyle.textPosition; });
} }
this._api.dispatch({
type: 'dataZoom',
from: this.uid,
param: this._normalizeToRange(),
targetModel: this._dataZoomModel
});
// FIXME
return true; return true;
}, },
_onDragEnd : function () { _onDragEnd : function () {
// FIXME
// if (this.zoomOption.showDetail) { // if (this.zoomOption.showDetail) {
// this._startShape.style.text = this._endShape.style.text = '=';
// this._startShape.style.textPosition = this._endShape.style.textPosition = 'inside';
// this.zr.modShape(this._startShape.id);
// this.zr.modShape(this._endShape.id);
// this.zr.refreshNextFrame();
// } // }
// this.isDragend = true; }
},
}); });
}); });
\ No newline at end of file
...@@ -9,24 +9,23 @@ define(function(require) { ...@@ -9,24 +9,23 @@ define(function(require) {
var helper = require('./helper'); var helper = require('./helper');
echarts.registerAction('dataZoom', function (event, ecModel) { echarts.registerAction('dataZoom', function (event, ecModel) {
var sourceDataZoomModel = event.targetModel; var linkSet = helper.findLinkSet(
ecModel.eachComponent('dataZoom', zrUtil.curry(processSingleDataZoom, event, ecModel)); zrUtil.bind(ecModel.eachComponent, ecModel, 'dataZoom'),
}); function (model, dimNames) {
return model.get(dimNames.axisIndex);
},
event.dataZoomModel
);
function processSingleDataZoom(event, ecModel, dataZoomModel) { var dataZoomRange = event.dataZoomRange;
helper.eachAxisDim(function (dimNames) { zrUtil.each(linkSet.models, function (dataZoomModel) {
zrUtil.each( dataZoomModel.setRange({
dataZoomModel.get(dimNames.axisIndex), start: dataZoomRange.start,
zrUtil.curry(processSingleAxis, ecModel, dataZoomModel, dimNames) end: dataZoomRange.end,
); start2: dataZoomRange.start2,
end2: dataZoomRange.end2
});
}); });
} });
function processSingleAxis(ecModel, dataZoomModel, dimNames, axisIndex) {
}
function isSharingAxis(dataZoomModel0, dataZoomModel1) {
}
}); });
\ No newline at end of file
...@@ -4,11 +4,13 @@ ...@@ -4,11 +4,13 @@
define(function (require) { define(function (require) {
var echarts = require('../../echarts'); var echarts = require('../../echarts');
var helper = require('./helper');
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
var linearMap = require('../../util/number').linearMap;
echarts.registerProcessor(function (ecModel) { echarts.registerProcessor(function (ecModel) {
ecModel.eachComponent('dataZoom', zrUtil.curry(processSingleDataZoom, ecModel)); ecModel.eachComponent('dataZoom', function (dataZoomModel) {
dataZoomModel.eachTargetAxis(processSingleAxis);
});
}); });
// FIXME // FIXME
...@@ -23,66 +25,54 @@ define(function (require) { ...@@ -23,66 +25,54 @@ define(function (require) {
// TODO // TODO
// undo redo // undo redo
function processSingleDataZoom(ecModel, dataZoomModel) { function processSingleAxis(dimNames, axisIndex, dataZoomModel, ecModel) {
helper.eachAxisDim(function (dimNames) {
zrUtil.each(
dataZoomModel.get(dimNames.axisIndex),
zrUtil.curry(processSingleAxis, ecModel, dataZoomModel, dimNames)
);
});
}
function processSingleAxis(ecModel, dataZoomModel, dimNames, axisIndex) { // Process axis data
// TODO
// backup axis data
var axisModel = ecModel.getComponent(dimNames.axis, axisIndex); var axisModel = ecModel.getComponent(dimNames.axis, axisIndex);
var axisData = axisModel.get('data'); var percentExtent = [0, 100];
if (axisData) { var dataZoomStart = axisModel.get('dataZoomStart');
var dataLength = axisData.length; var dataZoomEnd = axisModel.get('dataZoomEnd');
var start = Math.floor(axisModel.get('dataZoomStart') / 100 * dataLength);
var end = Math.ceil(axisModel.get('dataZoomEnd') / 100 * dataLength);
var axisData = axisModel.getData();
if (axisData) {
var axisDataExtent = [0, axisData.length];
var axisStart = Math.floor(linearMap(dataZoomStart, percentExtent, axisDataExtent, true));
var axisEnd = Math.ceil(linearMap(dataZoomEnd, percentExtent, axisDataExtent, true));
// Only category axis has property 'data's. // Only category axis has property 'data's.
axisData = axisData.slice(start, end); // FIXME
// setter?
axisData = axisModel.option.data = axisData.slice(axisStart, axisEnd);
}
var seriesModels = getTargetSeriesModelsByAxis( // Process series data
ecModel, dataZoomModel, axisIndex, dimNames var seriesModels = dataZoomModel.getTargetSeriesModels(dimNames.dim, axisIndex);
); zrUtil.each(seriesModels, function (seriesModel) {
zrUtil.each(seriesModels, function (seriesModel) {
// FIXME
// data的backup
// FIXME // FIXME
// 如何filter, // 如何filter,
// 是根据data自己存的信息(如dimension)来判断(这比较直接,但是现在list里存的信息没清楚), // 是根据data自己存的信息(如dimension)来判断(这比较直接,但是现在list里存的信息没清楚),
// 还是根据axis type来判断(比较枚举不太好) // 还是根据axis type来判断(比较枚举不太好)
// var axisType = axisModel.get('type'); // var axisType = axisModel.get('type');
// FIXME // FIXME
// 这里仅仅处理了list类型 // 这里仅仅处理了list类型
var seriesData = seriesModel.getData(); var seriesData = seriesModel.getData();
seriesModel.setData( if (seriesData) {
seriesData['filter' + dimNames.dim.toUpperCase()](function (value) {
return value >= start && value <= end;
})
);
// FIXME var seriesDataExtent = [0, seriesData.count()];
// 对于数值轴,还要考虑log等情况. var seriesStart = Math.floor(linearMap(dataZoomStart, percentExtent, seriesDataExtent, true));
// FIXME var seriesEnd = Math.ceil(linearMap(dataZoomEnd, percentExtent, seriesDataExtent, true));
// 对于时间河流图,还要考虑是否须整块移除。 seriesData.filterSelf(function (entry) {
}); var value = entry['get' + dimNames.dim.toUpperCase()]();
} return value >= seriesStart && value <= seriesEnd;
} });
function getTargetSeriesModelsByAxis(ecModel, dataZoomModel, axisIndex, dimNames) {
var seriesModels = [];
ecModel.eachSeries(function (seriesModel) {
if (axisIndex === seriesModel.get(dimNames.axisIndex)) {
seriesModels.push(seriesModel);
} }
// FIXME
// 对于数值轴,还要考虑log等情况.
// FIXME
// 对于时间河流图,还要考虑是否须整块移除。
}); });
return seriesModels;
} }
}); });
...@@ -11,14 +11,14 @@ define(function(require) { ...@@ -11,14 +11,14 @@ define(function(require) {
// FIXME // FIXME
// 公用? // 公用?
helper.eachAxisDim = function (callback, scope) { helper.eachAxisDim = function (callback, context) {
zrUtil.each(AXIS_DIMS, function (axisDim) { zrUtil.each(AXIS_DIMS, function (axisDim) {
var names = { var names = {
axisIndex: axisDim + 'AxisIndex', axisIndex: axisDim + 'AxisIndex',
axis: axisDim + 'Axis', axis: axisDim + 'Axis',
dim: axisDim dim: axisDim
}; };
callback.call(scope, names); callback.call(context, names);
}); });
}; };
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
define(function (require) { define(function (require) {
require('./legend/LegendModel'); require('./legend/LegendModel');
require('./legend/legendAction');
require('./legend/LegendView'); require('./legend/LegendView');
var echarts = require('../echarts'); var echarts = require('../echarts');
......
...@@ -68,9 +68,13 @@ define(function (require) { ...@@ -68,9 +68,13 @@ define(function (require) {
group.add(text); group.add(text);
legendSymbol.on('click', function () { legendSymbol.on('click', function () {
legendModel.toggleSelected(seriesName); api.dispatch({
api.update(); type: 'legendSelected',
}); from: this.uid,
legendModel: legendModel,
seriesName: seriesName
});
}, this);
}, this); }, this);
var groupRect = group.getBoundingRect(); var groupRect = group.getBoundingRect();
...@@ -80,9 +84,9 @@ define(function (require) { ...@@ -80,9 +84,9 @@ define(function (require) {
_createSymbol: function (seriesModel, x, y, width, height, api) { _createSymbol: function (seriesModel, x, y, width, height, api) {
// Using rect symbol defaultly // Using rect symbol defaultly
var legendSymbolType = seriesModel.getVisual('legendSymbol') var legendSymbolType = seriesModel && seriesModel.getVisual('legendSymbol')
|| 'roundRect'; || 'roundRect';
var symbolType = seriesModel.getVisual('symbol'); var symbolType = seriesModel && seriesModel.getVisual('symbol');
var legendSymbolShape = symbolCreator.createSymbol(legendSymbolType, x, y, width, height); var legendSymbolShape = symbolCreator.createSymbol(legendSymbolType, x, y, width, height);
......
/**
* @file Legend action
*/
define(function(require) {
var echarts = require('../../echarts');
echarts.registerAction('legendSelected', function (event, ecModel) {
event.legendModel.toggleSelected(event.seriesName);
});
});
\ No newline at end of file
...@@ -84,7 +84,6 @@ define(function (require) { ...@@ -84,7 +84,6 @@ define(function (require) {
if (data == null || data === '-') { if (data == null || data === '-') {
return NaN; return NaN;
} }
data = this.scale.normalize(data); data = this.scale.normalize(data);
var extent = this.getExtent(); var extent = this.getExtent();
......
...@@ -2,6 +2,7 @@ define(function(require) { ...@@ -2,6 +2,7 @@ define(function(require) {
'use strict'; 'use strict';
var ComponentModel = require('../../model/Component');
var defaultOption = require('../axisDefault'); var defaultOption = require('../axisDefault');
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
...@@ -13,7 +14,8 @@ define(function(require) { ...@@ -13,7 +14,8 @@ define(function(require) {
zrUtil.merge(axisOption, defaultOption[axisType]); zrUtil.merge(axisOption, defaultOption[axisType]);
} }
var AxisModel = require('../../model/Component').extend({ var AxisModel = ComponentModel.extend({
type: 'cartesian2dAxis', type: 'cartesian2dAxis',
/** /**
...@@ -21,6 +23,32 @@ define(function(require) { ...@@ -21,6 +23,32 @@ define(function(require) {
*/ */
axis: null, axis: null,
/**
* @override
*/
init: function () {
ComponentModel.prototype.init.call(this);
var data = this.getData();
if (data) {
// FIXME
// clone?
/**
* @type {Array}
* @private
*/
this._dataBeforeProcessing = data.slice();
}
},
/**
* @public
* @return {Array=} data Can be null
*/
getData: function () {
return this.get('data');
},
/** /**
* @public * @public
* @param {number} start 0-100, null means remain current value. * @param {number} start 0-100, null means remain current value.
...@@ -30,6 +58,17 @@ define(function(require) { ...@@ -30,6 +58,17 @@ define(function(require) {
var option = this.option; var option = this.option;
start != null && (option.dataZoomStart = start); start != null && (option.dataZoomStart = start);
end != null && (option.dataZoomEnd = end); end != null && (option.dataZoomEnd = end);
},
/**
* @override
*/
restoreData: function () {
// FIXME
// clone?
if (this._dataBeforeProcessing) {
this.option.data = this._dataBeforeProcessing.slice();
}
} }
}); });
...@@ -42,6 +81,8 @@ define(function(require) { ...@@ -42,6 +81,8 @@ define(function(require) {
type: 'xAxis', type: 'xAxis',
init: function (axisOption, parentModel, ecModel) { init: function (axisOption, parentModel, ecModel) {
AxisModel.prototype.init.call(this);
axisOption.type = axisOption.type || 'category'; axisOption.type = axisOption.type || 'category';
axisOption.position = axisOption.position || 'bottom'; axisOption.position = axisOption.position || 'bottom';
...@@ -58,6 +99,8 @@ define(function(require) { ...@@ -58,6 +99,8 @@ define(function(require) {
type: 'yAxis', type: 'yAxis',
init: function (axisOption, parentModel, ecModel) { init: function (axisOption, parentModel, ecModel) {
AxisModel.prototype.init.call(this);
axisOption.type = axisOption.type || 'value'; axisOption.type = axisOption.type || 'value';
axisOption.position = axisOption.position || 'left'; axisOption.position = axisOption.position || 'left';
......
...@@ -26,10 +26,10 @@ define(function(require, factory) { ...@@ -26,10 +26,10 @@ define(function(require, factory) {
var axisType = axisModel.get('type'); var axisType = axisModel.get('type');
if (axisType) { if (axisType) {
return axisType === 'category' return axisType === 'category'
? new OrdinalScale(axisModel.get('data')) ? new OrdinalScale(axisModel.getData())
: new IntervalScale(); : new IntervalScale();
} }
}; }
/** /**
* Check if the axis is used in the specified grid * Check if the axis is used in the specified grid
...@@ -232,7 +232,7 @@ define(function(require, factory) { ...@@ -232,7 +232,7 @@ define(function(require, factory) {
this._axesList.push(axisY); this._axesList.push(axisY);
this._axesMap['y' + idx] = axisY; this._axesMap['y' + idx] = axisY;
xAxesMap[idx] = axisY; yAxesMap[idx] = axisY;
yAxesCount++; yAxesCount++;
}, this); }, this);
...@@ -253,18 +253,6 @@ define(function(require, factory) { ...@@ -253,18 +253,6 @@ define(function(require, factory) {
cartesian.addAxis(xAxis); cartesian.addAxis(xAxis);
cartesian.addAxis(yAxis); cartesian.addAxis(yAxis);
});
});
ecModel.eachComponent('xAxis', function (xAxisModel, i) {
ecModel.eachComponent('yAxis', function (yAxisModel, j) {
var key = 'x' + i + 'y' + j;
var cartesian = new Cartesian2D(key);
this._coordsMap[key] = cartesian;
this._coordsList.push(cartesian);
cartesian.addAxis(xAxisModel.axis);
cartesian.addAxis(yAxisModel.axis);
}, this); }, this);
}, this); }, this);
...@@ -319,7 +307,7 @@ define(function(require, factory) { ...@@ -319,7 +307,7 @@ define(function(require, factory) {
else { else {
data.eachValue(function (value) { data.eachValue(function (value) {
if (value != null) { if (value != null) {
axisData[categoryAxis.dim == 'y' ? 'x' : 'y'].push(value); axisData[categoryAxis.dim === 'y' ? 'x' : 'y'].push(value);
} }
}); });
} }
...@@ -371,7 +359,7 @@ define(function(require, factory) { ...@@ -371,7 +359,7 @@ define(function(require, factory) {
}); });
return grids; return grids;
} };
require('../../CoordinateSystem').register('grid', Grid); require('../../CoordinateSystem').register('grid', Grid);
......
...@@ -40,12 +40,14 @@ define(function(require) { ...@@ -40,12 +40,14 @@ define(function(require) {
var oldDataMap = {}; var oldDataMap = {};
var newDataMap = {}; var newDataMap = {};
var newDataIndexMap = {};
var i; var i;
for (i = 0; i < oldArr.length; i++) { for (i = 0; i < oldArr.length; i++) {
oldDataMap[oldArr[i].name] = oldArr[i]; oldDataMap[oldArr[i].name] = oldArr[i];
} }
for (i = 0; i < newArr.length; i++) { for (i = 0; i < newArr.length; i++) {
newDataMap[newArr[i].name] = newArr[i]; newDataMap[newArr[i].name] = newArr[i];
newDataIndexMap[newArr[i].name] = i;
} }
for (i = 0; i < oldArr.length; i++) { for (i = 0; i < oldArr.length; i++) {
...@@ -61,8 +63,8 @@ define(function(require) { ...@@ -61,8 +63,8 @@ define(function(require) {
for (i = 0; i < newArr.length; i++) { for (i = 0; i < newArr.length; i++) {
var newData = newArr[i]; var newData = newArr[i];
if (! oldDataMap[newData.name]) { if (!oldDataMap[newData.name]) {
this._add && this._add(newData); this._add && this._add(newData, newDataIndexMap[newData.name]);
} }
} }
} }
......
...@@ -25,9 +25,11 @@ define(function(require) { ...@@ -25,9 +25,11 @@ define(function(require) {
array[i] = eachAxis(item, depth); array[i] = eachAxis(item, depth);
} }
} }
} };
} }
var dimensions = ['x', 'y', 'z', 'value', 'radius', 'angle']
var dimensions = ['x', 'y', 'z', 'value', 'radius', 'angle'];
/** /**
* @name echarts/data/List~Entry * @name echarts/data/List~Entry
* @extends {module:echarts/model/Model} * @extends {module:echarts/model/Model}
...@@ -78,7 +80,7 @@ define(function(require) { ...@@ -78,7 +80,7 @@ define(function(require) {
*/ */
valueIndex: 1, valueIndex: 1,
init: function (option, parentModel, dataIndex, independentVar, dependentVar) { init: function (option, parentModel, rawDataIndex, independentVar, dependentVar) {
/** /**
* @type {string} * @type {string}
...@@ -87,12 +89,27 @@ define(function(require) { ...@@ -87,12 +89,27 @@ define(function(require) {
*/ */
this.name = option.name || ''; this.name = option.name || '';
/**
* this.option **MUST NOT** be modified in List!
* Different lists might share this option instance.
*
* @readOnly
* @type {*}
*/
this.option = option; this.option = option;
var value = option.value == null ? option : option.value; var value = option.value == null ? option : option.value;
if (typeof value === 'number') { if (typeof value === 'number') {
value = [dataIndex, value]; value = [rawDataIndex, value];
/**
* If dataIndex is persistent in entry, it should be udpated when modifying list.
* So use this.dataIndexIndex to mark that.
*
* @readOnly
* @type {number}
*/
this.dataIndexIndex = 0;
} }
if (independentVar) { if (independentVar) {
...@@ -105,6 +122,10 @@ define(function(require) { ...@@ -105,6 +122,10 @@ define(function(require) {
} }
/** /**
* All of the content **MUST NOT** be modified,
* (because they are the same instance with option.value)
* except this._value[this.dataIndexIndex].
*
* @type {Array.<number>} * @type {Array.<number>}
* @memeberOf module:echarts/data/List~Entry * @memeberOf module:echarts/data/List~Entry
* @private * @private
...@@ -112,10 +133,11 @@ define(function(require) { ...@@ -112,10 +133,11 @@ define(function(require) {
this._value = value; this._value = value;
/** /**
* @private * Data index before modifying list (filterSelf).
*
* @readOnly * @readOnly
*/ */
this.dataIndex = dataIndex; this.rawDataIndex = rawDataIndex;
}, },
/** /**
...@@ -129,10 +151,11 @@ define(function(require) { ...@@ -129,10 +151,11 @@ define(function(require) {
}, },
clone: function () { clone: function () {
var entry = new Entry( var entry = new Entry(this.option, this.parentModel);
this.option, this.parentModel, this.dataIndex
);
entry.name = this.name; entry.name = this.name;
entry.dataIndexIndex = this.dataIndexIndex;
entry._value = entry.dataIndexIndex != null
? this._value.slice() : this._value;
for (var i = 0; i < dimensions.length; i++) { for (var i = 0; i < dimensions.length; i++) {
var key = dimensions[i] + 'Index'; var key = dimensions[i] + 'Index';
...@@ -150,16 +173,20 @@ define(function(require) { ...@@ -150,16 +173,20 @@ define(function(require) {
if (index >= 0) { if (index >= 0) {
return this._value[index]; return this._value[index];
} }
} };
Entry.prototype['set' + capitalized] = function (val) { Entry.prototype['set' + capitalized] = function (val) {
var index = this[indexKey]; var index = this[indexKey];
if (index >= 0) { if (index >= 0) {
this._value[indexKey] = val; this._value[indexKey] = val;
} }
} };
}); });
function List() { function List() {
/**
* @readOnly
* @type {Array}
*/
this.elements = []; this.elements = [];
} }
...@@ -169,9 +196,12 @@ define(function(require) { ...@@ -169,9 +196,12 @@ define(function(require) {
type: 'list', type: 'list',
count: function () {
return this.elements.length;
},
each: function (cb, context) { each: function (cb, context) {
context = context || this; zrUtil.each(this.elements, cb, context || this);
zrUtil.each(this.elements, cb, context);
}, },
/** /**
...@@ -180,16 +210,34 @@ define(function(require) { ...@@ -180,16 +210,34 @@ define(function(require) {
*/ */
map: function (cb, context) { map: function (cb, context) {
var ret = []; var ret = [];
context = context || this;
this.each(function (item, idx) { this.each(function (item, idx) {
ret.push(cb && cb.call(context || this, item)); ret.push(cb && cb.call(context, item));
}, context); }, context);
return ret; return ret;
}, },
filter: function (cb, context) { filterSelf: function (cb, context) {
var list = new List(); this.elements = zrUtil.filter(this.elements, cb, context || this);
context = context || this;
list.elements = zrUtil.filter(this.elements, cb, context); var dataIndexDirty = false;
this.elements = zrUtil.filter(this.elements, function (entry) {
var result = cb.apply(this, arguments);
if (result && entry.dataIndexIndex != null) {
dataIndexDirty = true;
}
return result;
}, context || this);
dataIndexDirty && this.refreshDataIndex();
},
refreshDataIndex: function () {
this.each(function (entry, dataIndex) {
if (entry.dataIndexIndex != null) {
entry._value[entry.dataIndexIndex] = dataIndex;
}
}, this);
}, },
/** /**
...@@ -227,8 +275,6 @@ define(function(require) { ...@@ -227,8 +275,6 @@ define(function(require) {
for (var i = 0; i < elements.length; i++) { for (var i = 0; i < elements.length; i++) {
list.elements.push(elements[i].clone()); list.elements.push(elements[i].clone());
} }
list.depth = this.depth;
list.properties = this.properties;
return list; return list;
} }
}; };
...@@ -247,18 +293,6 @@ define(function(require) { ...@@ -247,18 +293,6 @@ define(function(require) {
}, context); }, context);
return ret; return ret;
}; };
List.prototype['filter' + name] = function (cb, context) {
var newList = this.clone();
var elements = []
newList.each(function (item) {
if (cb.call(context || newList, item['get' + name]())) {
elements.push(item);
}
}, context);
newList.elements = elements;
return newList;
};
}); });
List.fromArray = function (data, seriesModel, ecModel) { List.fromArray = function (data, seriesModel, ecModel) {
...@@ -295,7 +329,7 @@ define(function(require) { ...@@ -295,7 +329,7 @@ define(function(require) {
else if (coordinateSystem === 'polar') { else if (coordinateSystem === 'polar') {
function axisFinder(axisModel) { function axisFinder(axisModel) {
return axisModel.get('polarIndex') === polarIndex; return axisModel.get('polarIndex') === polarIndex;
}; }
var polarIndex = seriesModel.get('polarIndex') || 0; var polarIndex = seriesModel.get('polarIndex') || 0;
var angleAxisModel = ecModel.findComponent('angleAxis', axisFinder); var angleAxisModel = ecModel.findComponent('angleAxis', axisFinder);
var radiusAxisModel = ecModel.findComponent('radiusAxis', axisFinder); var radiusAxisModel = ecModel.findComponent('radiusAxis', axisFinder);
......
...@@ -154,22 +154,26 @@ define(function (require) { ...@@ -154,22 +154,26 @@ define(function (require) {
this._needsUpdate = true; this._needsUpdate = true;
}, },
updateImmediately: function () { updateImmediately: function (event) {
// console.time('update'); // console.time('update');
var ecModel = this._model; var ecModel = this._model;
ecModel.restoreData(); ecModel.restoreData();
// TODO
// Save total ecModel here for undo/redo (after restoring data and before processing data).
// Undo (restoration of total ecModel) can be carried out in 'action' or outside API call.
this._processData(ecModel); this._processData(ecModel);
this._coordinateSystem.update(ecModel, this._extensionAPI); this._coordinateSystem.update(ecModel, this._extensionAPI);
this._doVisualCoding(ecModel); this._doVisualCoding(ecModel);
this._doLayout(ecModel); this._doLayout(ecModel, event);
this._doRender(ecModel); this._doRender(ecModel, event);
this._needsUpdate = false; this._needsUpdate = false;
...@@ -190,6 +194,20 @@ define(function (require) { ...@@ -190,6 +194,20 @@ define(function (require) {
this.updateImmediately(); this.updateImmediately();
}, },
/**
* @pubilc
* @param {Object} event
* @param {string} [event.type] Event type
* @param {number} [event.from] From uid
*/
dispatch: function (event) {
var action = actions[event.type];
if (action) {
action(event, this._model);
this.updateImmediately(event);
}
},
_prepareCharts: function (ecModel) { _prepareCharts: function (ecModel) {
var chartsList = this._chartsList; var chartsList = this._chartsList;
...@@ -299,12 +317,12 @@ define(function (require) { ...@@ -299,12 +317,12 @@ define(function (require) {
* @param {module:echarts/model/Global} ecModel * @param {module:echarts/model/Global} ecModel
* @private * @private
*/ */
_doLayout: function (ecModel) { _doLayout: function (ecModel, event) {
zrUtil.each(this._layouts, function (layout) { zrUtil.each(this._layouts, function (layout) {
layout(ecModel); layout(ecModel, event);
}); });
zrUtil.each(layoutFuncs, function (layout) { zrUtil.each(layoutFuncs, function (layout) {
layout(ecModel); layout(ecModel, event);
}); });
}, },
...@@ -323,23 +341,25 @@ define(function (require) { ...@@ -323,23 +341,25 @@ define(function (require) {
/** /**
* Render each chart and component * Render each chart and component
*/ */
_doRender: function (ecModel) { _doRender: function (ecModel, event) {
var api = this._extensionAPI; var api = this._extensionAPI;
// Render all components // Render all components
zrUtil.each(this._componentsList, function (component) { zrUtil.each(this._componentsList, function (component) {
component.render(component.__model, ecModel, api); component.render(component.__model, ecModel, api, event);
}, this); }, this);
// Remove groups of charts
zrUtil.each(this._chartsList, function (chart) { zrUtil.each(this._chartsList, function (chart) {
chart.__keepAlive = false; chart.__keepAlive = false;
}, this); }, this);
// Render all charts // Render all charts
ecModel.eachSeries(function (seriesModel, idx) { ecModel.eachSeries(function (seriesModel, idx) {
var id = getSeriesId(seriesModel.option, idx); var id = getSeriesId(seriesModel.option, idx);
var chart = this._chartsMap[id]; var chart = this._chartsMap[id];
chart.__keepAlive = true; chart.__keepAlive = true;
chart.render(seriesModel, ecModel, api); chart.render(seriesModel, ecModel, api, event);
}, this); }, this);
// Remove groups of charts // Remove groups of charts
zrUtil.each(this._chartsList, function (chart) { zrUtil.each(this._chartsList, function (chart) {
if (!chart.__keepAlive) { if (!chart.__keepAlive) {
...@@ -363,6 +383,8 @@ define(function (require) { ...@@ -363,6 +383,8 @@ define(function (require) {
var dataProcessorFuncs = []; var dataProcessorFuncs = [];
var actions = [];
var layoutClasses = []; var layoutClasses = [];
var layoutFuncs = []; var layoutFuncs = [];
...@@ -387,6 +409,15 @@ define(function (require) { ...@@ -387,6 +409,15 @@ define(function (require) {
} }
}, },
/**
* @param {Function}
*/
registerAction: function (actionName, action) {
if (!actions[actionName]) {
actions[actionName] = action;
}
},
/** /**
* @param {string} type * @param {string} type
* @param {*} CoordinateSystem * @param {*} CoordinateSystem
...@@ -429,6 +460,13 @@ define(function (require) { ...@@ -429,6 +460,13 @@ define(function (require) {
return ComponentModel.extend(opts); return ComponentModel.extend(opts);
}, },
/**
* @param {Object} opts
*/
extendSeriesModel: function (opts) {
return SeriesModel.extend(opts);
},
/** /**
* @param {Object} opts * @param {Object} opts
*/ */
......
...@@ -77,6 +77,7 @@ define(function (require) { ...@@ -77,6 +77,7 @@ define(function (require) {
max = Math.max(data[i], max); max = Math.max(data[i], max);
min = Math.min(data[i], min); min = Math.min(data[i], min);
} }
this.setExtent(min, max); this.setExtent(min, max);
}, },
......
...@@ -4,7 +4,7 @@ define(function(require) { ...@@ -4,7 +4,7 @@ define(function(require) {
var pathTool = require('zrender/tool/path'); var pathTool = require('zrender/tool/path');
var matrix = require('zrender/core/matrix'); var matrix = require('zrender/core/matrix');
var round = Math.round;
var Path = require('zrender/graphic/Path'); var Path = require('zrender/graphic/Path');
var graphic = { var graphic = {
...@@ -77,27 +77,81 @@ define(function(require) { ...@@ -77,27 +77,81 @@ define(function(require) {
}, },
/** /**
* @param {Array.<number>} p1 * Sub pixel optimize line for canvas
* @param {Array.<number>} p2 *
* @param {number} lineWidth * @param {Object} param
* @param {Object} [param.shape]
* @param {number} [param.shape.x1]
* @param {number} [param.shape.y1]
* @param {number} [param.shape.x2]
* @param {number} [param.shape.y2]
* @param {Object} [param.style]
* @param {number} [param.style.lineWidth]
* @return {Object} Modified param
*/ */
subPixelOptimizeLine: function (p1, p2, lineWidth) { subPixelOptimizeLine: function (param) {
var round = Math.round; var subPixelOptimize = graphic.subPixelOptimize;
// Sub pixel optimize var shape = param.shape;
var offset = lineWidth % 2 / 2; var lineWidth = param.style.lineWidth;
var x1 = round(p1[0]);
var y1 = round(p1[1]); if (round(shape.x1 * 2) === round(shape.x2 * 2)) {
var x2 = round(p2[0]); shape.x1 = shape.x2 = subPixelOptimize(shape.x1, lineWidth, true);
var y2 = round(p2[1]);
if (x1 === x2) {
x1 += offset;
x2 += offset;
} }
if (y1 === y2) { if (round(shape.y1 * 2) === round(shape.y2 * 2)) {
y1 += offset; shape.y1 = shape.y2 = subPixelOptimize(shape.y1, lineWidth, true);
y2 += offset;
} }
return param;
},
/**
* Sub pixel optimize rect for canvas
*
* @param {Object} param
* @param {Object} [param.shape]
* @param {number} [param.shape.x]
* @param {number} [param.shape.y]
* @param {number} [param.shape.width]
* @param {number} [param.shape.height]
* @param {Object} [param.style]
* @param {number} [param.style.lineWidth]
* @return {Object} Modified param
*/
subPixelOptimizeRect: function (param) {
var subPixelOptimize = graphic.subPixelOptimize;
var shape = param.shape;
var lineWidth = param.style.lineWidth;
var originX = shape.x;
var originY = shape.y;
var originWidth = shape.width;
var originHeight = shape.height;
shape.x = subPixelOptimize(shape.x, lineWidth, true);
shape.y = subPixelOptimize(shape.y, lineWidth, true);
shape.width = Math.max(
subPixelOptimize(originX + originWidth, lineWidth, false) - shape.x,
originWidth === 0 ? 0 : 1
);
shape.height = Math.max(
subPixelOptimize(originY + originHeight, lineWidth, false) - shape.y,
originHeight === 0 ? 0 : 1
);
return param;
},
/**
* Sub pixel optimize for canvas
*
* @param {number} position Coordinate, such as x, y
* @param {number} lineWidth Should be nonnegative integer.
* @param {boolean=} positiveOrNegative Default false (negative).
* @return {number} Optimized position.
*/
subPixelOptimize: function (position, lineWidth, positiveOrNegative) {
// Assure that (position + lineWidth / 2) is near integer edge,
// otherwise line will be fuzzy in canvas.
var doubledPosition = round(position * 2);
return (doubledPosition + round(lineWidth)) % 2 === 0
? doubledPosition / 2
: (doubledPosition + (positiveOrNegative ? 1 : -1)) / 2;
} }
}; };
......
<html>
<head>
<meta charset="utf-8">
<script src="esl.js"></script>
<script src="config.js"></script>
</head>
<body>
<style>
html, body, #main {
width: 100%;
height: 100%;
}
</style>
<div id="main"></div>
<script>
require([
'echarts',
'echarts/chart/line',
'echarts/component/legend',
'echarts/component/grid',
'echarts/component/axis',
'echarts/component/dataZoom'
], function (echarts) {
var chart = echarts.init(document.getElementById('main'), null, {
renderer: 'canvas'
});
var xAxisData = [];
var data1 = [];
var data2 = [];
var data3 = [];
for (var i = 0; i < 20; i++) {
xAxisData.push('类目' + i);
data1.push(Math.random() * 5);
data2.push(Math.random());
data3.push(Math.random());
}
chart.setOption({
legend: {
data: ['line', 'line2', 'line3']
},
xAxis: {
// data: ['类目1', '类目2', '类目3', '类目4', '类目5',]
data: xAxisData
},
yAxis: {
// scale: true
},
series: [
{
name: 'line',
type: 'line',
data: data1
},
// {
// name: 'line2',
// type: 'line',
// data: data2
// },
// {
// name: 'line3',
// type: 'line',
// data: data3
// }
],
dataZoom: {
show: true
}
});
})
</script>
</body>
</html>
\ No newline at end of file
document.write('<script src="ut/core/utHelper.js"><\/script>'); document.write('<script src="ut/core/utHelper.js"><\/script>');
// Specs ... // Specs ...
document.write('<script src="ut/spec/util/graphic.js"><\/script>');
document.write('<script src="ut/spec/model/Component.js"><\/script>'); document.write('<script src="ut/spec/model/Component.js"><\/script>');
document.write('<script src="ut/spec/dataZoom/helper.js"><\/script>'); document.write('<script src="ut/spec/dataZoom/helper.js"><\/script>');
describe('util/graphic', function() {
var utHelper = window.utHelper;
var graphic;
beforeAll(function (done) { // jshint ignore:line
utHelper.resetPackageLoader(function () {
window.require(['echarts/util/graphic'], function (g) {
graphic = g;
done();
});
});
});
describe('subPixelOptimize', function () {
it('subPixelOptimize_base', function (done) {
expect(graphic.subPixelOptimize(5, 1)).toEqual(4.5);
expect(graphic.subPixelOptimize(5, 2)).toEqual(5);
expect(graphic.subPixelOptimize(5, 43)).toEqual(4.5);
expect(graphic.subPixelOptimize(7.5, 1)).toEqual(7.5);
expect(graphic.subPixelOptimize(7.5, 2)).toEqual(7);
expect(graphic.subPixelOptimize(14, 1, true)).toEqual(14.5);
expect(graphic.subPixelOptimize(14, 2, true)).toEqual(14);
expect(graphic.subPixelOptimize(-11, 1)).toEqual(-11.5);
expect(graphic.subPixelOptimize(-11, 2)).toEqual(-11);
expect(graphic.subPixelOptimize(0, 2)).toEqual(0);
expect(graphic.subPixelOptimize(0, 1)).toEqual(-0.5);
expect(graphic.subPixelOptimize(5, 0)).toEqual(5);
done();
});
it('subPixelOptimize_line', function (done) {
function doSubPixelOptimizeLine(x, y, width, height, lineWidth) {
return graphic.subPixelOptimizeLine(makeParam(x, y, width, height, lineWidth));
}
function makeParam(x1, y1, x2, y2, lineWidth) {
return {
shape: {x1: x1, y1: y1, x2: x2, y2: y2},
style: {lineWidth: lineWidth}
};
}
expect(doSubPixelOptimizeLine(5, 11, 3, 7, 1)).toEqual(makeParam(5, 11, 3, 7, 1));
expect(doSubPixelOptimizeLine(5, 11, 5, 7, 1)).toEqual(makeParam(5.5, 11, 5.5, 7, 1));
expect(doSubPixelOptimizeLine(5, 11, 5, 7, 2)).toEqual(makeParam(5, 11, 5, 7, 2));
expect(doSubPixelOptimizeLine(5, 11, 15, 11, 1)).toEqual(makeParam(5, 11.5, 15, 11.5, 1));
expect(doSubPixelOptimizeLine(5, 11, 15, 11, 2)).toEqual(makeParam(5, 11, 15, 11, 2));
expect(doSubPixelOptimizeLine(5, 11, 15, 11, 3)).toEqual(makeParam(5, 11.5, 15, 11.5, 3));
expect(doSubPixelOptimizeLine(5, 11, 15, 11.5, 3)).toEqual(makeParam(5, 11, 15, 11.5, 3));
expect(doSubPixelOptimizeLine(5, 11.5, 15, 11.5, 3)).toEqual(makeParam(5, 11.5, 15, 11.5, 3));
expect(doSubPixelOptimizeLine(5, 11.5, 15, 11.5, 4)).toEqual(makeParam(5, 12, 15, 12, 4));
done();
});
it('subPixelOptimize_rect', function (done) {
function doSubPixelOptimizeRect(x, y, width, height, lineWidth) {
return graphic.subPixelOptimizeRect(makeParam(x, y, width, height, lineWidth));
}
function makeParam(x, y, width, height, lineWidth) {
return {
shape: {x: x, y: y, width: width, height: height},
style: {lineWidth: lineWidth}
};
}
expect(doSubPixelOptimizeRect(5, 11, 3, 7, 1)).toEqual(makeParam(5.5, 11.5, 2, 6, 1));
expect(doSubPixelOptimizeRect(5, 11, 3, 7, 2)).toEqual(makeParam(5, 11, 3, 7, 2));
expect(doSubPixelOptimizeRect(5, 11, 3, 7, 3)).toEqual(makeParam(5.5, 11.5, 2, 6, 3));
// Boundary value tests
expect(doSubPixelOptimizeRect(5, 11, 1, 7, 1)).toEqual(makeParam(5.5, 11.5, 1, 6, 1));
expect(doSubPixelOptimizeRect(5, 11, 1, 0, 1)).toEqual(makeParam(5.5, 11.5, 1, 0, 1));
done();
});
});
});
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册