提交 762d906b 编写于 作者: P pah100

组件注册稍微调整一下。不仅series,组件也可以加子组件。

上级 0bfadbde
......@@ -11,7 +11,7 @@ define(function (require) {
require('../echarts').registerLayout(zrUtil.curry(barLayoutGrid, 'bar'));
// Visual coding for legend
require('../echarts').registerVisualCoding(function (ecModel) {
require('../echarts').registerVisualCoding('chart', function (ecModel) {
ecModel.eachSeriesByType('bar', function (seriesModel) {
var data = seriesModel.getData();
data.setVisual('legendSymbol', 'roundRect');
......
......@@ -6,7 +6,7 @@ define(function (require) {
require('./line/LineSeries');
require('./line/LineView');
echarts.registerVisualCoding(zrUtil.curry(
echarts.registerVisualCoding('chart', zrUtil.curry(
require('../visual/symbol'), 'line', 'circle', 'line'
));
echarts.registerLayout(zrUtil.curry(
......
......@@ -6,7 +6,7 @@ define(function (require) {
require('./scatter/ScatterSeries');
require('./scatter/ScatterView');
echarts.registerVisualCoding(zrUtil.curry(
echarts.registerVisualCoding('chart', zrUtil.curry(
require('../visual/symbol'), 'scatter', 'circle', null
));
echarts.registerLayout(zrUtil.curry(
......
define(function (require) {
var echarts = require('../../echarts');
var zrUtil = require('zrender/core/util');
var graphic = require('../../util/graphic');
var textContain = require('zrender/contain/text');
return echarts.extendComponentView({
type: 'dataRange',
/**
* @readOnly
* @type {Object}
*/
autoPositionValues: {left: 1, right: 1, top: 1, bottom: 1},
init: function (api) {
/**
* @private
* @type {Object}
*/
this._updatableShapes = {};
/**
* @protected
* @type {module:echarts/component/dataZoom/DataZoomLayout}
*/
this.layout;
/**
* @private
* @type {string}
*/
this._orient;
},
/**
* @protected
*/
getTextRect: function (text) {
var textStyleModel = this.textStyleModel;
return textContain.getTextRect(
text,
textStyleModel.get('font'),
textStyleModel.get('align'),
textStyleModel.get('baseline')
);
},
/**
* @protected
*/
initLayout: function () {
var dataRangeModel = this.dataRangeModel;
var orient = dataRangeModel.get('orient');
var x = dataRangeModel.get('x');
var y = dataRangeModel.get('y');
var api = this.api;
var ecWidth = api.getWidth();
var ecHeight = api.getHeight();
this.layout = {
orient: orient,
maxWidth: this.autoPositionValues[x] ? ecWidth : ecWidth - x,
ecWidth: ecWidth,
ecHeight: ecHeight,
x: x,
y: y
};
},
/**
* @private
*/
_layoutOuter: function () {
// Depends on contentLayout
var layout = this.layout;
var contentLayout = layout.content;
var dataRangeModel = this.dataRangeModel;
var x = dataRangeModel.get('x');
var y = dataRangeModel.get('y');
layout.x = x === 'left'
? 0
: x === 'right'
? layout.ecWidth - contentLayout.width
: x;
layout.y = y === 'top'
? 0
: y === 'bottom'
? layout.ecHeight - contentLayout.height
: y;
// TODO
// 考虑padding boder
},
/**
* @protected
*/
render: function () {
// FIXME
// padding
// var padding = this.reformCssArray(this.dataRangeOption.padding);
// TODO : TEST
// 文字不超出边界,例如x 'right' orient 'vertical'时。
var dataRangeModel = this.dataRangeModel;
var layout = this.layout;
this.initLayout();
this.layoutContent();
this._layoutOuter();
this.group.push(new graphic.Rect({
// zlevel: this.getZlevelBase(),
// z: this.getZBase(),
hoverable: false,
shape: {
x: layout.x,
y: layout.y,
width: layout.width,
height: layout.height
},
style: {
brushType: dataRangeModel.get('borderWidth') === 0 ? 'fill' : 'both',
color: dataRangeModel.get('backgroundColor'),
strokeColor: dataRangeModel.get('borderColor'),
lineWidth: dataRangeModel.get('borderWidth')
}
}));
this.rendercontent();
},
/**
* @protected
* @abstract
*/
layoutContent: zrUtil.noop,
/**
* @protected
* @abstract
*/
renderContent: zrUtil.noop
});
});
\ No newline at end of file
......@@ -6,7 +6,9 @@ define(function(require) {
var zrUtil = require('zrender/core/util');
var env = require('zrender/core/env');
var echarts = require('../../echarts');
var helper = require('./helper');
var modelUtil = require('../../util/model');
var asc = require('../../util/number').asc;
var eachAxisDim = modelUtil.eachAxisDim;
return echarts.extendComponentModel({
......@@ -35,13 +37,14 @@ define(function(require) {
handleColor: 'rgba(70,130,180,0.8)', // 手柄颜色
handleSize: 10,
showDetail: true,
// xAxisIndex: [], // 默认控制所有横向类目
// yAxisIndex: [], // 默认控制所有横向类目
xAxisIndex: null, // 默认控制所有横向类目
yAxisIndex: null, // 默认控制所有横向类目
start: 0, // 默认为0
end: 100, // 默认为全部 100%
start2: 0, // 默认为0
end2: 100, // 默认为全部 100%
realtime: true
realtime: true,
inverse: false // 默认与所控制的轴相同
// zoomLock: false // 是否锁定选择区域大小
},
......@@ -50,13 +53,15 @@ define(function(require) {
*/
init: function (option, parentModel, ecModel) {
this.mergeDefaultAndTheme(option, ecModel);
this.mergeOption({});
this.mergeOption({}, true);
this._autoAxisIndex = false;
},
/**
* @override
*/
mergeOption: function (newOption) {
mergeOption: function (newOption, isInit) {
var thisOption = this.option;
newOption && zrUtil.merge(thisOption, newOption);
......@@ -66,6 +71,7 @@ define(function(require) {
thisOption.realtime = false;
}
this._resetAutoIndex(newOption, isInit);
// FIXME
// 是否有toolbox zoom控件时,自动加一个dataZoom option,而非和某个dataZoom option共用?
// dataZoom option中可加type来判断是普通还是toolbox还是移动端需要的图面拖拽。
......@@ -76,23 +82,29 @@ define(function(require) {
this._resetInverse();
},
_resetAutoIndex: function (newOption, isInit) {
// Consider this case:
// There is no axisIndex specified at the begining,
// which means that auto choise of axisIndex is required.
// Then user modifies series using setOption and do not specify axisIndex either.
// At that moment axisIndex should be re-choised.
var option = isInit ? this.option : newOption;
this._autoAxisIndex = true;
eachAxisDim(function (dimNames) {
option[dimNames.axisIndex] != null && (this._autoAxisIndex = false);
}, this);
},
_resetTargetAxes: function (newOption) {
var thisOption = this.option;
var noAxisDefined = true;
helper.eachAxisDim(function (dimNames) {
// Overlap these arrays but not merge.
var axisIndices = helper.toArray(helper.retrieveValue(
newOption[dimNames.axisIndex], thisOption[dimNames.axisIndex], []
));
thisOption[dimNames.axisIndex] = axisIndices;
var autoAxisIndex = this._autoAxisIndex;
if (axisIndices.length) {
noAxisDefined = false;
}
eachAxisDim(function (dimNames) {
thisOption[dimNames.axisIndex] = autoAxisIndex
? [] : modelUtil.normalizeToArray(thisOption[dimNames.axisIndex]);
}, this);
if (noAxisDefined) {
if (autoAxisIndex) {
// Find axis that parallel to dataZoom as default.
var dimNames = this.get('orient') === 'vertical'
? {dim: 'y', axisIndex: 'yAxisIndex', axis: 'yAxis'}
......@@ -100,14 +112,14 @@ define(function(require) {
if (this.dependentModels[dimNames.axis].length) {
thisOption[dimNames.axisIndex] = [0];
noAxisDefined = false;
autoAxisIndex = false;
}
}
if (noAxisDefined) {
if (autoAxisIndex) {
// Find the first category axis as default. (consider polar)
helper.eachAxisDim(function (dimNames) {
if (!noAxisDefined) {
eachAxisDim(function (dimNames) {
if (!autoAxisIndex) {
return;
}
var axisIndices = [];
......@@ -121,12 +133,12 @@ define(function(require) {
}
thisOption[dimNames.axisIndex] = axisIndices;
if (axisIndices.length) {
noAxisDefined = false;
autoAxisIndex = false;
}
}, this);
}
if (noAxisDefined) {
if (autoAxisIndex) {
// FIXME
// 这里是兼容ec2的写法(没指定xAxisIndex和yAxisIndex时把scatter和双数值轴折柱纳入dataZoom控制),
// 但是实际是否需要Grid.js#getScaleByOption来判断(考虑time,log等axis type)?
......@@ -136,7 +148,7 @@ define(function(require) {
// both xAxis and yAxis which type is 'value'.
this.ecModel.eachSeries(function (seriesModel) {
if (this._isSeriesHasAllAxesTypeOf(seriesModel, 'value')) {
helper.eachAxisDim(function (dimNames) {
eachAxisDim(function (dimNames) {
var axisIndices = thisOption[dimNames.axisIndex];
var axisIndex = seriesModel.get(dimNames.axisIndex);
if (zrUtil.indexOf(axisIndices, axisIndex) < 0) {
......@@ -154,7 +166,7 @@ define(function(require) {
// 例如series.type === scatter时。
var is = true;
helper.eachAxisDim(function (dimNames) {
eachAxisDim(function (dimNames) {
var seriesAxisIndex = seriesModel.get(dimNames.axisIndex);
var axisModel = this.dependentModels[dimNames.axis][seriesAxisIndex];
......@@ -178,9 +190,9 @@ define(function(require) {
// When only xAxisIndex or only yAxisIndex is specified, start/end controls them.
// targetDim === false means that both xAxisIndex and yAxisIndex are specified.
var targetDim;
helper.eachAxisDim(function (dimNames) {
eachAxisDim(function (dimNames) {
if (thisOption[dimNames.axisIndex].length) {
targetDim = targetDim != null ? false : dimNames.dim;
targetDim = targetDim != null ? false : dimNames.name;
}
});
......@@ -199,7 +211,6 @@ define(function(require) {
targetDim2 && (optAttrs[targetDim2] = {start: 'start2', end: 'end2'});
zrUtil.each(optAttrs, function (dimItem, targetDim) {
var axisModels = this.dependentModels[targetDim + 'Axis'];
var startValue = thisOption[dimItem.start];
var endValue = thisOption[dimItem.end];
......@@ -221,13 +232,9 @@ define(function(require) {
* @private
*/
_resetInverse: function () {
var orient = this.get('orient');
// Just use the first axis to determine mapping.
var targetAxisModel = this._getFirstTargetAxisModel();
var inverse = targetAxisModel && targetAxisModel.get('inverse');
this.option.inverse =
(orient === 'horizontal' && inverse)
|| (orient === 'vertical' && !inverse);
this.option.inverse = targetAxisModel && targetAxisModel.get('inverse');
},
/**
......@@ -235,7 +242,7 @@ define(function(require) {
*/
_getFirstTargetAxisModel: function () {
var firstAxisModel;
helper.eachAxisDim(function (dimNames) {
eachAxisDim(function (dimNames) {
if (firstAxisModel == null) {
var indices = this.get(dimNames.axisIndex);
if (indices.length) {
......@@ -253,7 +260,7 @@ define(function(require) {
*/
eachTargetAxis: function (callback, context) {
var ecModel = this.ecModel;
helper.eachAxisDim(function (dimNames) {
eachAxisDim(function (dimNames) {
zrUtil.each(
this.get(dimNames.axisIndex),
function (axisIndex) {
......@@ -281,19 +288,15 @@ define(function(require) {
/**
* @public
* @param {Object} param
* @param {number=} [param.start]
* @param {number=} [param.end]
* @param {number=} [param.start2]
* @param {number=} [param.end2]
* @param {Array} param [start, end]
*/
setRange: function (param) {
// FIXME
// 接口改变
var thisOption = this.option;
param.start != null && (thisOption.start = param.start);
param.end != null && (thisOption.end = param.end);
param.start2 != null && (thisOption.start2 = param.start2);
param.end2 != null && (thisOption.end2 = param.end2);
param[0] != null && (thisOption.start = param[0]);
param[1] != null && (thisOption.end = param[1]);
this._resetRange();
},
......@@ -303,12 +306,15 @@ define(function(require) {
*/
getRange: function () {
var thisOption = this.option;
return {
start: thisOption.start,
end: thisOption.end,
star2: thisOption.star2,
end2: thisOption.end2
};
var range = asc([thisOption.start, thisOption.end]);
// Clamp
range[0] > 100 && (range[0] = 100);
range[1] > 100 && (range[1] = 100);
range[0] < 0 && (range[0] = 0);
range[1] < 0 && (range[1] = 0);
return range;
}
});
......
......@@ -45,17 +45,22 @@ define(function (require) {
this._orient = dataZoomModel.get('orient');
if (!event || event.type !== 'dataZoom' || event.from !== this.uid) {
this.group.removeAll();
var group = this.group;
group.removeAll();
if (this.dataZoomModel.get('show') === false) {
return;
}
// Layout
this._layout = new DataZoomLayout(dataZoomModel, ecModel, api);
this._layout.reset();
var layoutIns = this._layout = new DataZoomLayout(dataZoomModel, ecModel, api);
layoutIns.reset();
// Render
group.position[0] = layoutIns.layout.x;
group.position[1] = layoutIns.layout.y;
this._renderBackground();
this._renderDataShadow();
this._renderFrame();
......@@ -66,18 +71,18 @@ define(function (require) {
_renderBackground : function () {
var dataZoomModel = this.dataZoomModel;
var location = this._layout.layout.location;
var layout = this._layout.layout;
this.group.add(new this.api.Rect({
// FIXME
// zlevel: this.getZlevelBase(),
// z: this.getZBase(),
hoverable:false,
hoverable: false,
shape: {
x: location.x,
y: location.y,
width: location.width,
height: location.height
x: 0,
y: 0,
width: layout.width,
height: layout.height
},
style: {
fill: dataZoomModel.get('backgroundColor')
......@@ -86,30 +91,24 @@ define(function (require) {
},
_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
)));
zrUtil.each(['startFrame', 'endFrame'], function (name) {
var cfg = {
// 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)'
}
};
cfg = zrUtil.merge(cfg, this._layout.layout[name]);
this.group.add(this._updatableShapes[name] = new this.api.Rect(cfg));
}, this);
},
_renderDataShadow: function () {
......@@ -118,74 +117,53 @@ define(function (require) {
},
_renderFiller: function () {
this.group.add(
this._updatableShapes.filler = new this.api.Rect(zrUtil.merge(
{
// FIXME
// zlevel: this.getZlevelBase(),
// 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._layout.layout.filler
))
);
},
_renderHandle: function () {
var dataZoomModel = this.dataZoomModel;
var layout = this._layout.layout;
var updatableShapes = this._updatableShapes;
// FIXME
// var detailInfo = this.zoomOption.showDetail ? this._getDetail() : {start: '',end: ''};
var baseHandle = {
var cfg = {
// FIXME
// zlevel: this.getZlevelBase(),
// z: this.getZBase(),
draggable: this._orient,
draggable: true,
cursor: 'move',
drift: zrUtil.bind(this._onDrift, this, this._getUpdateArg()),
ondragend: zrUtil.bind(this._onDragEnd, this),
style: {
fill: dataZoomModel.get('handleColor'),
textColor: DEFAULT_HANDLE_INNER_COLOR,
text: '=',
textPosition: 'inside'
fill: this.dataZoomModel.get('fillerColor'),
text: this._orient === 'horizontal' ? ':::' : '::',
textPosition : 'inside'
}
// FIXME
// highlightStyle: {
// text: detail.start,
// brushType: 'fill',
// textPosition: 'left'
// },
// color: 'rgba(0,0,0,0)'
// }
};
cfg = zrUtil.merge(cfg, this._layout.layout.filler);
this.group
.add(updatableShapes.handle1 = new this.api.Rect(zrUtil.mergeAll(
{
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)
this.group.add(this._updatableShapes.filler = new this.api.Rect(cfg));
},
_renderHandle: function () {
// FIXME
// var detailInfo = this.zoomOption.showDetail ? this._getDetail() : {start: '',end: ''};
zrUtil.each(['handle1', 'handle2'], function (name) {
var cfg = {
style: {
fill: this.dataZoomModel.get('handleColor'),
textColor: DEFAULT_HANDLE_INNER_COLOR,
text: '=',
textPosition: 'inside'
},
baseHandle,
layout.handle2
)));
cursor: 'move',
draggable: true,
drift: zrUtil.bind(this._onDrift, this, this._getUpdateArg(name)),
ondragend: zrUtil.bind(this._onDragEnd, this)
};
cfg = zrUtil.merge(cfg, this._layout.layout[name]);
this.group.add(this._updatableShapes[name] = new this.api.Rect(cfg));
}, this);
},
_updateView: function () {
......@@ -210,16 +188,15 @@ define(function (require) {
}
},
_getUpdateArgs: function (arg) {
return (!arg || this.dataZoomModel.get('zoomLock'))
? ['handle1', 'handle2']
: [arg];
_getUpdateArg: function (arg) {
return (arg && !this.dataZoomModel.get('zoomLock'))
? arg : null;
},
_onDrift: function (rangeArgs, dx, dy) {
_onDrift: function (rangeArg, dx, dy) {
var dataZoomModel = this.dataZoomModel;
this._layout.update({rangeArgs: rangeArgs, dx: dx, dy: dy});
this._layout.update({rangeArg: rangeArg, dx: dx, dy: dy});
this._updateView();
......
......@@ -4,8 +4,9 @@
define(function(require) {
var zrUtil = require('zrender/core/util');
var modelUtil = require('../../util/model');
var echarts = require('../../echarts');
var helper = require('./helper');
echarts.registerAction('dataZoom', function (event, ecModel) {
......@@ -14,22 +15,18 @@ define(function(require) {
return;
}
var linkSet = helper.findLinkSet(
var linkedNodesFinder = modelUtil.createLinkedNodesFinder(
zrUtil.bind(ecModel.eachComponent, ecModel, 'dataZoom'),
modelUtil.eachAxisDim,
function (model, dimNames) {
return model.get(dimNames.axisIndex);
},
fromDataZoomModel
}
);
var dataZoomRange = event.dataZoomRange;
zrUtil.each(linkSet.models, function (dataZoomModel) {
dataZoomModel.setRange({
start: dataZoomRange.start,
end: dataZoomRange.end,
start2: dataZoomRange.start2,
end2: dataZoomRange.end2
});
var effectedModels = linkedNodesFinder(fromDataZoomModel).nodes;
zrUtil.each(effectedModels, function (dataZoomModel) {
dataZoomModel.setRange(event.dataZoomRange);
});
});
......
......@@ -30,7 +30,7 @@ define(function (require) {
// Process axis data
var axisModel = ecModel.getComponent(dimNames.axis, axisIndex);
var isCategoryFilter = axisModel.get('type') === 'category';
var seriesModels = dataZoomModel.getTargetSeriesModels(dimNames.dim, axisIndex);
var seriesModels = dataZoomModel.getTargetSeriesModels(dimNames.name, axisIndex);
var dataExtent = calculateDataExtent(dimNames, axisModel, seriesModels);
var dataWindow = calculateDataWindow(axisModel, dataZoomModel, dataExtent, isCategoryFilter);
......@@ -66,7 +66,7 @@ define(function (require) {
// return value >= dataWindow[0] && value <= dataWindow[1];
// });
// }
seriesData.filterSelf(dimNames.dim, function (value) {
seriesData.filterSelf(dimNames.name, function (value) {
return value >= dataWindow[0] && value <= dataWindow[1];
});
......@@ -91,7 +91,7 @@ define(function (require) {
zrUtil.each(seriesModels, function (seriesModel) {
var seriesData = seriesModel.getData();
if (seriesData) {
var seriesExtent = seriesData.getDataExtent(dimNames.dim);
var seriesExtent = seriesData.getDataExtent(dimNames.name);
seriesExtent[0] < dataExtent[0] && (dataExtent[0] = seriesExtent[0]);
seriesExtent[1] > dataExtent[1] && (dataExtent[1] = seriesExtent[1]);
}
......@@ -106,8 +106,8 @@ define(function (require) {
var percentExtent = [0, 100];
var result = [
linearMap(dataZoomRange.start, percentExtent, dataExtent, true),
linearMap(dataZoomRange.end, percentExtent, dataExtent, true)
linearMap(dataZoomRange[0], percentExtent, dataExtent, true),
linearMap(dataZoomRange[1], percentExtent, dataExtent, true)
];
if (isCategoryFilter) {
result = [Math.floor(result[0]), Math.ceil(result[1])];
......
/**
* @file Data zoom helper
*/
define(function(require) {
var zrUtil = require('zrender/core/util');
var helper = {};
var AXIS_DIMS = ['x', 'y', 'z', 'radius', 'angle'];
// FIXME
// 公用?
helper.eachAxisDim = function (callback, context) {
zrUtil.each(AXIS_DIMS, function (axisDim) {
var capital = axisDim[0].toUpperCase() + axisDim.substr(1);
var names = {
axisIndex: axisDim + 'AxisIndex',
axis: axisDim + 'Axis',
dim: axisDim,
capital: capital,
index: axisDim + 'Index'
};
callback.call(context, names);
});
};
// FIXME
// 公用?
/**
* If value1 is not null, then return value1, otherwise judget rest of values.
* @param {*...} values
* @return {*} Final value
*/
helper.retrieveValue = function (values) {
for (var i = 0, len = arguments.length; i < len; i++) {
if (arguments[i] != null) {
return arguments[i];
}
}
};
// FIXME
// 公用?
/**
* If value is not array, then translate it to array.
* @param {*} value
* @return {Array} [value] or value
*/
helper.toArray = function (value) {
return zrUtil.isArray(value) ? value : (value == null ? [] : [value]);
};
/**
* @public
*/
helper.findLinkSet = function (forEachModel, axisIndicesGetter, sourceModel) {
var result = {models: [], dims: {}};
var dimRecords = {};
helper.eachAxisDim(function (dimNames) {
result.dims[dimNames.dim] = [];
dimRecords[dimNames.dim] = [];
});
if (!sourceModel) {
return result;
}
absorb(sourceModel);
var existsLink;
do {
existsLink = false;
forEachModel(processSingleModel);
}
while (existsLink);
wrapUpResult();
return result;
function processSingleModel(model) {
if (!isModelAbsorded(model) && isLink(model)) {
absorb(model);
existsLink = true;
}
}
function isModelAbsorded(model) {
return zrUtil.indexOf(result.models, model) >= 0;
}
function isLink(model) {
var hasLink = false;
helper.eachAxisDim(function (dimNames) {
var axisIndices = axisIndicesGetter(model, dimNames);
var singleDimSet = dimRecords[dimNames.dim];
for (var i = 0, len = axisIndices.length; i < len; i++) {
if (singleDimSet[axisIndices[i]]) {
hasLink = true;
return;
}
}
});
return hasLink;
}
function absorb(model) {
result.models.push(model);
helper.eachAxisDim(function (dimNames) {
var axisIndices = axisIndicesGetter(model, dimNames);
var singleDimSet = dimRecords[dimNames.dim];
for (var i = 0, len = axisIndices.length; i < len; i++) {
singleDimSet[axisIndices[i]] = true;
}
});
}
function wrapUpResult() {
helper.eachAxisDim(function (dimNames) {
var dimRecord = dimRecords[dimNames.dim];
for (var i = 0; i < dimRecord.length; i++) {
if (dimRecord[i]) {
result.dims[dimNames.dim].push(i);
}
}
});
}
};
return helper;
});
\ No newline at end of file
......@@ -36,7 +36,7 @@ define(function(require) {
axis: null,
init: function (axisOption, parentModel, ecModel) {
zrUtil.merge(axisOption, this.defaultOption, false);
zrUtil.merge(axisOption, this.getDefaultOption(), false);
mergeDefault(axisOption, ecModel);
},
......@@ -62,7 +62,7 @@ define(function(require) {
axis: null,
init: function (axisOption, parentModel, ecModel) {
zrUtil.merge(axisOption, this.defaultOption, false);
zrUtil.merge(axisOption, this.getDefaultOption(), false);
mergeDefault(axisOption, ecModel);
},
......
......@@ -21,6 +21,8 @@ define(function (require) {
var zrender = require('zrender');
var zrUtil = require('zrender/core/util');
var VISUAL_CODING_STAGES = ['echarts', 'chart', 'component'];
/**
* @inner
*/
......@@ -232,11 +234,12 @@ define(function (require) {
var id = getSeriesId(seriesModel.option, idx);
var chart = chartsMap[id];
if (! chart) {
chart = ChartView.create(
if (!chart) {
var Clazz = ChartView.getClass(
ComponentModel.parseComponentType(seriesModel.type).sub
);
if (chart) {
if (Clazz) {
chart = new Clazz();
chart.init(ecModel, this._extensionAPI);
chartsMap[id] = chart;
chartsList.push(chart);
......@@ -274,25 +277,30 @@ define(function (require) {
componentsList[i].__keepAlive = true;
}
ComponentView.eachAvailableComponent(function (componentType) {
ecModel.eachComponent(function (componentType, componentModel, idx) {
if (componentType === 'series') {
return;
}
var id = componentType + '_' + idx;
var component = componentsMap[id];
if (!component) {
// Create and add component
var Clazz = ComponentView.getClass(componentType, componentModel.option);
ecModel.eachComponent(componentType, function (componentModel, idx) {
var id = componentType + '_' + idx;
var component = componentsMap[id];
if (! component) {
// Create and add component
component = ComponentView.create(componentType, componentModel);
if (Clazz) {
component = new Clazz();
component.init(ecModel, this._extensionAPI);
componentsMap[id] = component;
componentsList.push(component);
this._zr.add(component.group);
}
component.__id = id;
component.__keepAlive = true;
// Used in rendering
component.__model = componentModel;
}, this);
}
component.__id = id;
component.__keepAlive = true;
// Used in rendering
component.__model = componentModel;
}, this);
for (var i = 0; i < componentsList.length;) {
......@@ -361,8 +369,10 @@ define(function (require) {
* @private
*/
_doVisualCoding: function (ecModel) {
zrUtil.each(visualCodingFuncs, function (visualCoding) {
visualCoding(ecModel);
zrUtil.each(VISUAL_CODING_STAGES, function (stage) {
zrUtil.each(visualCodingFuncs[stage] || [], function (visualCoding) {
visualCoding(ecModel);
});
});
},
......@@ -417,7 +427,7 @@ define(function (require) {
var layoutFuncs = [];
var visualCodingFuncs = [];
var visualCodingFuncs = {};
/**
* @module echarts
......@@ -471,8 +481,12 @@ define(function (require) {
}
},
registerVisualCoding: function (visualCodingFunc) {
visualCodingFuncs.push(visualCodingFunc);
registerVisualCoding: function (stage, visualCodingFunc) {
if (zrUtil.indexOf(VISUAL_CODING_STAGES, stage) < 0) {
throw new Error('stage should be one of ' + VISUAL_CODING_STAGES);
}
var funcs = visualCodingFuncs[stage] || (visualCodingFuncs[stage] = []);
funcs.push(visualCodingFunc);
},
/**
......@@ -504,7 +518,7 @@ define(function (require) {
}
};
echarts.registerVisualCoding(require('./visual/defaultColor'));
echarts.registerVisualCoding('echarts', require('./visual/defaultColor'));
return echarts;
});
\ No newline at end of file
......@@ -10,20 +10,7 @@ define(function(require) {
var Model = require('./Model');
var zrUtil = require('zrender/core/util');
var arrayPush = Array.prototype.push;
var unique = require('../util/unique');
var TYPE_DELIMITER = '.';
var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';
/**
* Component model classes
* key: componentType,
* value:
* componentClass, when componentType is 'xxx'
* or Array.<componentClass>, when componentType is 'xxx.yy'
* @type {Object}
*/
var componentModelClasses = {};
var componentUtil = require('../util/component');
/**
* @alias module:echarts/model/Component
......@@ -62,7 +49,26 @@ define(function(require) {
mergeDefaultAndTheme: function (option, ecModel) {
zrUtil.merge(option, ecModel.getTheme().get(this.type));
zrUtil.merge(option, this.defaultOption);
zrUtil.merge(option, this.getDefaultOption());
},
getDefaultOption: function () {
if (!this.hasOwnProperty('__defaultOption')) {
var optList = [];
var Class = this.constructor;
while (Class) {
var opt = Class.prototype.defaultOption;
opt && optList.push(opt);
Class = Class.superClass;
}
var defaultOption = {};
for (var i = optList.length - 1; i >= 0; i--) {
defaultOption = zrUtil.merge(defaultOption, optList[i], true);
}
this.__defaultOption = defaultOption;
}
return this.__defaultOption;
}
});
......@@ -76,191 +82,31 @@ define(function(require) {
* @public
* @readOnly
*/
this.uid = unique.getUID('componentModel');
this.uid = componentUtil.getUID('componentModel');
ComponentModel.apply(this, arguments);
};
for (var name in proto) {
if (proto.hasOwnProperty(name)) {
SubComponentModel.prototype[name] = proto[name];
}
}
zrUtil.extend(SubComponentModel.prototype, proto);
var Super = this;
SubComponentModel.extend = Super.extend;
zrUtil.inherits(SubComponentModel, Super);
return registerComponentClass(SubComponentModel, proto.type);
return ComponentModel.registerClass(SubComponentModel, proto.type);
};
function registerComponentClass(SubComponentModel, componentType) {
if (componentType) {
componentType = ComponentModel.parseComponentType(componentType);
// And capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
componentUtil.enableClassManagement(ComponentModel, true);
if (!componentType.sub) {
if (componentModelClasses[componentType.main]) {
throw new Error(componentType.main + 'exists');
}
componentModelClasses[componentType.main] = SubComponentModel;
}
else if (componentType.sub !== IS_CONTAINER) {
var container = makeContainer(componentType);
container[componentType.sub] = SubComponentModel;
}
}
return SubComponentModel;
}
ComponentModel.getComponentModelClass = function (componentType, option, throwWhenNotFound) {
var fullComponentType = componentType;
if (option && option.type) {
fullComponentType = componentType + TYPE_DELIMITER + option.type;
}
var ComponentClass = getClassOrContainer(fullComponentType);
if (ComponentClass[IS_CONTAINER]) {
ComponentClass = ComponentClass[option.type];
}
if (throwWhenNotFound && !ComponentClass) {
throw new Error('Component ' + fullComponentType + ' not exists');
}
return ComponentClass;
};
ComponentModel.has = function (componentType) {
return !!getClassOrContainer(componentType);
};
ComponentModel.parseComponentType = function (componentType) {
var ret = {main: '', sub: ''};
if (componentType) {
componentType = componentType.split(TYPE_DELIMITER);
ret.main = componentType[0] || '';
ret.sub = componentType[1] || '';
}
return ret;
};
function makeContainer(componentType) {
var container = componentModelClasses[componentType.main];
if (!container || !container[IS_CONTAINER]) {
container = componentModelClasses[componentType.main] = {};
container[IS_CONTAINER] = true;
}
return container;
}
function getClassOrContainer(componentType) {
componentType = ComponentModel.parseComponentType(componentType);
return componentModelClasses[componentType.main];
}
/**
* Topological travel on Activity Network (Activity On Vertices).
* Dependencies is defined in Model.prototype.dependencies, like ['xAxis', 'yAxis'].
* If 'xAxis' or 'yAxis' is absent in componentTypeList, just ignore it in topology.
*
* @public
* @param {Array.<string>} componentTypeList Target Component type list.
* @param {Function} callback Params: componentType, dependencies.
*/
ComponentModel.topologicalTravel = function (componentTypeList, callback, scope) {
if (!componentTypeList.length) {
return;
}
var result = makeDepndencyGraph(componentTypeList);
var graph = result.graph;
var stack = result.noEntryList;
if (!stack.length) {
throw new Error('Circle exists in dependency graph.');
}
while (stack.length) {
var currComponentType = stack.pop();
var currVertex = graph[currComponentType];
callback.call(scope, currComponentType, currVertex.originalDeps.slice());
zrUtil.each(currVertex.successor, removeEdge);
}
function removeEdge(succComponentType) {
graph[succComponentType].entryCount--;
if (graph[succComponentType].entryCount === 0) {
stack.push(succComponentType);
}
}
};
/**
* DepndencyGraph: {Object}
* key: conponentType,
* value: {
* successor: [conponentTypes...],
* originalDeps: [conponentTypes...],
* entryCount: {number}
* }
*/
function makeDepndencyGraph(componentTypeList) {
var graph = {};
var noEntryList = [];
zrUtil.each(componentTypeList, function (componentType) {
var thisItem = createDependencyGraphItem(graph, componentType);
var originalDeps = thisItem.originalDeps = getDependencies(componentType);
var availableDeps = getAvailableDependencies(originalDeps, componentTypeList);
thisItem.entryCount = availableDeps.length;
if (thisItem.entryCount === 0) {
noEntryList.push(componentType);
}
zrUtil.each(availableDeps, function (depComponentType) {
if (zrUtil.indexOf(thisItem.predecessor, depComponentType) < 0) {
thisItem.predecessor.push(depComponentType);
}
var thatItem = createDependencyGraphItem(graph, depComponentType);
if (zrUtil.indexOf(thatItem.successor, depComponentType) < 0) {
thatItem.successor.push(componentType);
}
});
});
return {graph: graph, noEntryList: noEntryList};
}
componentUtil.enableTopologicalTravel(ComponentModel, getDependencies);
function getDependencies(componentType) {
componentType = ComponentModel.parseComponentType(componentType);
var deps = [];
var obj = componentModelClasses[componentType.main];
if (obj && obj[IS_CONTAINER]) {
zrUtil.each(obj, function (ComponentClass, componentType) {
if (componentType !== IS_CONTAINER) {
arrayPush.apply(deps, ComponentClass.prototype.dependencies || []);
}
});
}
else if (obj) {
arrayPush.apply(deps, obj.prototype.dependencies || []);
}
return deps;
}
function createDependencyGraphItem(graph, componentType) {
if (!graph[componentType]) {
graph[componentType] = {predecessor: [], successor: []};
}
return graph[componentType];
}
function getAvailableDependencies(originalDeps, componentTypeList) {
var availableDeps = [];
zrUtil.each(originalDeps, function (dep) {
zrUtil.indexOf(componentTypeList, dep) >= 0 && availableDeps.push(dep);
zrUtil.each(ComponentModel.getClassesByMainType(componentType), function (Clazz) {
arrayPush.apply(deps, Clazz.prototype.dependencies || []);
});
return availableDeps;
return deps;
}
return ComponentModel;
......
......@@ -101,7 +101,7 @@ define(function (require) {
// 如果不存在对应的 component model 则直接 merge
zrUtil.each(newOption, function (componentOption, componentType) {
if (!ComponentModel.has(componentType)) {
if (!ComponentModel.hasClass(componentType)) {
if (componentOption && typeof componentOption === 'object') {
option[componentType] = option[componentType] == null
? zrUtil.clone(componentOption)
......@@ -131,7 +131,10 @@ define(function (require) {
for (var i = 0; i < componentOption.length; i++) {
var componentModel = componentsMap[componentType][i];
var ComponentModelClass = ComponentModel.getComponentModelClass(
ComponentModel.completeSubType(componentType, componentOption[i]);
var ComponentModelClass = ComponentModel.getClass(
componentType, componentOption[i], true
);
......@@ -187,12 +190,32 @@ define(function (require) {
},
/**
* @param {string} type
* @usage
* eachComponent('legend', function (legendModel, index) {
* ...
* });
* eachComponent(function (componentType, model, index) {
* // componentType does not include subType
* // (componentType is 'xxx' but not 'xxx.aa')
* });
*
* @param {string=} type
* @param {Function} cb
* @param {*} context
*/
eachComponent: function (type, cb, context) {
zrUtil.each(this._componentsMap[type], cb, context);
if (typeof type === 'function') {
context = cb;
cb = type;
zrUtil.each(this._componentsMap, function (components, componentType) {
zrUtil.each(components, function (component, index) {
cb.call(this, componentType, component, index);
}, this);
}, context);
}
else {
zrUtil.each(this._componentsMap[type], cb, context);
}
},
/**
......
......@@ -63,7 +63,7 @@ define(function(require) {
option,
ecModel.getTheme().get(ComponentModel.parseComponentType(this.type).sub)
);
zrUtil.merge(option, this.defaultOption);
zrUtil.merge(option, this.getDefaultOption());
},
mergeOption: function (newSeriesOption, ecModel) {
......
define(function(require) {
var zrUtil = require('zrender/core/util');
var base = 0;
var DELIMITER = '_';
var TYPE_DELIMITER = '.';
var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';
var util = {};
/**
* @public
* @param {string} type
* @return {string}
*/
util.getUID = function (type) {
// Considering the case of crossing js context,
// use Math.random to make id as unique as possible.
return [(type || ''), base++, Math.random()].join(DELIMITER);
};
/**
* @public
* @param {string} uid
* @return {string} Type
*/
util.getUIDType = function (uid) {
if (uid) {
return uid.split(DELIMITER)[0];
}
};
/**
* @public
*/
var parseComponentType = util.parseComponentType = function (componentType) {
var ret = {main: '', sub: ''};
if (componentType) {
componentType = componentType.split(TYPE_DELIMITER);
ret.main = componentType[0] || '';
ret.sub = componentType[1] || '';
}
return ret;
};
/**
* @public
*/
util.enableClassManagement = function (entity, enableSubTypeDefaulter) {
/**
* Component model classes
* key: componentType,
* value:
* componentClass, when componentType is 'xxx'
* or Object.<subKey, componentClass>, when componentType is 'xxx.yy'
* @type {Object}
*/
var storage = {};
entity.registerClass = function (Clazz, componentType) {
if (componentType) {
componentType = parseComponentType(componentType);
if (!componentType.sub) {
if (storage[componentType.main]) {
throw new Error(componentType.main + 'exists');
}
storage[componentType.main] = Clazz;
}
else if (componentType.sub !== IS_CONTAINER) {
var container = makeContainer(componentType);
container[componentType.sub] = Clazz;
}
}
return Clazz;
};
entity.getClass = function (componentTypeMain, option, throwWhenNotFound) {
var Clazz = storage[componentTypeMain];
var subType = option && option.type;
if (Clazz && Clazz[IS_CONTAINER] && subType) {
Clazz = Clazz[subType];
}
if (throwWhenNotFound && !Clazz) {
throw new Error(
'Component ' + componentTypeMain + '.' + (subType || '') + ' not exists'
);
}
return Clazz;
};
entity.getClassesByMainType = function (componentType) {
componentType = parseComponentType(componentType);
var result = [];
var obj = storage[componentType.main];
if (obj && obj[IS_CONTAINER]) {
zrUtil.each(obj, function (ComponentClass, componentType) {
if (componentType !== IS_CONTAINER) {
result.push(ComponentClass);
}
});
}
else {
result.push(obj);
}
return result;
};
entity.hasClass = function (componentType) {
// Just consider componentType.main.
componentType = parseComponentType(componentType);
return !!storage[componentType.main];
};
entity.parseComponentType = parseComponentType;
function makeContainer(componentType) {
var container = storage[componentType.main];
if (!container || !container[IS_CONTAINER]) {
container = storage[componentType.main] = {};
container[IS_CONTAINER] = true;
}
return container;
}
if (enableSubTypeDefaulter) {
enableSubTypeDefaulterManager(entity, storage);
}
return entity;
};
/**
* @inner
*/
function enableSubTypeDefaulterManager(entity, storage) {
var subTypeDefaulters = {};
entity.registerSubTypeDefaulter = function (componentType, defaulter) {
componentType = parseComponentType(componentType);
subTypeDefaulters[componentType.main] = defaulter;
};
entity.completeSubType = function (componentType, option) {
if (!option.type) {
var componentTypeMain = parseComponentType(componentType).main;
var Clazz = storage[componentTypeMain];
Clazz
&& Clazz[IS_CONTAINER]
&& subTypeDefaulters[componentTypeMain]
&& subTypeDefaulters[componentTypeMain](option);
}
};
return entity;
}
/**
* Topological travel on Activity Network (Activity On Vertices).
* Dependencies is defined in Model.prototype.dependencies, like ['xAxis', 'yAxis'].
* If 'xAxis' or 'yAxis' is absent in componentTypeList, just ignore it in topology.
*
*/
util.enableTopologicalTravel = function (entity, dependencyGetter) {
/**
* @public
* @param {Array.<string>} componentTypeList Target Component type list.
* Can be ['aa', 'bb', 'aa.xx']
* @param {Function} callback Params: componentType, dependencies.
* @param {Object} context Scope of callback.
*/
entity.topologicalTravel = function (componentTypeList, callback, context) {
if (!componentTypeList.length) {
return;
}
var result = makeDepndencyGraph(componentTypeList);
var graph = result.graph;
var stack = result.noEntryList;
if (!stack.length) {
throw new Error('Circle exists in dependency graph.');
}
while (stack.length) {
var currComponentType = stack.pop();
var currVertex = graph[currComponentType];
callback.call(context, currComponentType, currVertex.originalDeps.slice());
zrUtil.each(currVertex.successor, removeEdge);
}
function removeEdge(succComponentType) {
graph[succComponentType].entryCount--;
if (graph[succComponentType].entryCount === 0) {
stack.push(succComponentType);
}
}
};
/**
* DepndencyGraph: {Object}
* key: conponentType,
* value: {
* successor: [conponentTypes...],
* originalDeps: [conponentTypes...],
* entryCount: {number}
* }
*/
function makeDepndencyGraph(componentTypeList) {
var graph = {};
var noEntryList = [];
zrUtil.each(componentTypeList, function (componentType) {
var thisItem = createDependencyGraphItem(graph, componentType);
var originalDeps = thisItem.originalDeps = dependencyGetter(componentType);
var availableDeps = getAvailableDependencies(originalDeps, componentTypeList);
thisItem.entryCount = availableDeps.length;
if (thisItem.entryCount === 0) {
noEntryList.push(componentType);
}
zrUtil.each(availableDeps, function (depComponentType) {
if (zrUtil.indexOf(thisItem.predecessor, depComponentType) < 0) {
thisItem.predecessor.push(depComponentType);
}
var thatItem = createDependencyGraphItem(graph, depComponentType);
if (zrUtil.indexOf(thatItem.successor, depComponentType) < 0) {
thatItem.successor.push(componentType);
}
});
});
return {graph: graph, noEntryList: noEntryList};
}
function createDependencyGraphItem(graph, componentType) {
if (!graph[componentType]) {
graph[componentType] = {predecessor: [], successor: []};
}
return graph[componentType];
}
function getAvailableDependencies(originalDeps, componentTypeList) {
var availableDeps = [];
zrUtil.each(originalDeps, function (dep) {
zrUtil.indexOf(componentTypeList, dep) >= 0 && availableDeps.push(dep);
});
return availableDeps;
}
};
return util;
});
\ No newline at end of file
define(function(require) {
var zrUtil = require('zrender/core/util');
var AXIS_DIMS = ['x', 'y', 'z', 'radius', 'angle'];
var util = {};
/**
* Create "each" method to iterate names.
*
* @pubilc
* @param {Array.<string>} names
* @param {Array.<string>=} attrs
* @return {Function}
*/
util.createNameEach = function (names, attrs) {
names = names.slice();
var capitalNames = zrUtil.map(names, util.capticalFirst);
attrs = (attrs || []).slice();
var capitalAttrs = zrUtil.map(attrs, util.capticalFirst);
return function (callback, context) {
zrUtil.each(names, function (name, index) {
var nameObj = {name: name, capital: capitalNames[index]};
for (var j = 0; j < attrs.length; j++) {
nameObj[attrs[j]] = name + capitalAttrs[j];
}
callback.call(context, nameObj);
});
};
};
/**
* @public
*/
util.capticalFirst = function (str) {
return str ? str[0].toUpperCase() + str.substr(1) : str;
};
/**
* Iterate each dimension name.
*
* @public
* @param {Function} callback The parameter is like:
* {
* name: 'angle',
* capital: 'Angle',
* axis: 'angleAxis',
* axisIndex: 'angleAixs',
* index: 'angleIndex'
* }
* @param {Object} context
*/
util.eachAxisDim = util.createNameEach(AXIS_DIMS, ['axisIndex', 'axis', 'index']);
/**
* If value1 is not null, then return value1, otherwise judget rest of values.
* @param {*...} values
* @return {*} Final value
*/
util.retrieveValue = function (values) {
for (var i = 0, len = arguments.length; i < len; i++) {
if (arguments[i] != null) {
return arguments[i];
}
}
};
/**
* If value is not array, then translate it to array.
* @param {*} value
* @return {Array} [value] or value
*/
util.normalizeToArray = function (value) {
return zrUtil.isArray(value)
? value
: value == null
? []
: [value];
};
/**
* If tow dataZoomModels has the same axis controlled, we say that they are 'linked'.
* dataZoomModels and 'links' make up one or more graphics.
* This function finds the graphic where the source dataZoomModel is in.
*
* @public
* @param {Function} forEachNode Node iterator.
* @param {Function} forEachEdgeType edgeType iterator
* @param {Function} edgeIdGetter Giving node and edgeType, return an array of edge id.
* @return {Function} Input: sourceNode, Output: Like {nodes: [], dims: {}}
*/
util.createLinkedNodesFinder = function (forEachNode, forEachEdgeType, edgeIdGetter) {
return function (sourceNode) {
var result = {
nodes: [],
records: {} // key: edgeType.name, value: Object (key: edge id, value: boolean).
};
forEachEdgeType(function (edgeType) {
result.records[edgeType.name] = {};
});
if (!sourceNode) {
return result;
}
absorb(sourceNode, result);
var existsLink;
do {
existsLink = false;
forEachNode(processSingleNode);
}
while (existsLink);
function processSingleNode(node) {
if (!isNodeAbsorded(node, result) && isLinked(node, result)) {
absorb(node, result);
existsLink = true;
}
}
return result;
};
function isNodeAbsorded(node, result) {
return zrUtil.indexOf(result.nodes, node) >= 0;
}
function isLinked(node, result) {
var hasLink = false;
forEachEdgeType(function (edgeType) {
zrUtil.each(edgeIdGetter(node, edgeType) || [], function (edgeId) {
result.records[edgeType.name][edgeId] && (hasLink = true);
});
});
return hasLink;
}
function absorb(node, result) {
result.nodes.push(node);
forEachEdgeType(function (edgeType) {
zrUtil.each(edgeIdGetter(node, edgeType) || [], function (edgeId) {
result.records[edgeType.name][edgeId] = true;
});
});
}
};
return util;
});
\ No newline at end of file
......@@ -72,12 +72,21 @@ define(function (require) {
return +(+x).toFixed(12);
}
function asc(arr) {
arr.sort(function (a, b) {
return a - b;
});
return arr;
}
return {
linearMap: linearMap,
parsePercent: parsePercent,
round: round
round: round,
asc: asc
};
});
\ No newline at end of file
define(function(require) {
'use strict';
var unique = {};
var base = 0;
var DELIMITER = '_';
/**
* @public
* @param {string} type
* @return {string}
*/
unique.getUID = function (type) {
// Considering the case of crossing js context,
// use Math.random to make id as unique as possible.
return [(type || ''), base++, Math.random()].join(DELIMITER);
};
/**
* @public
* @param {string} uid
* @return {string} Type
*/
unique.getType = function (uid) {
if (uid) {
return uid.split(DELIMITER)[0];
}
};
return unique;
});
\ No newline at end of file
......@@ -2,7 +2,7 @@ define(function (require) {
var zrUtil = require('zrender/core/util');
var Group = require('zrender/container/Group');
var unique = require('../util/unique');
var componentUtil = require('../util/component');
function Chart() {
......@@ -16,7 +16,7 @@ define(function (require) {
* @type {string}
* @readOnly
*/
this.uid = unique.getUID('viewChart');
this.uid = componentUtil.getUID('viewChart');
}
Chart.prototype = {
......@@ -34,8 +34,6 @@ define(function (require) {
dispose: function () {}
};
var chartClassStore = {};
Chart.extend = function (proto) {
var Super = this;
......@@ -43,34 +41,17 @@ define(function (require) {
Super.call(this);
};
for (var name in proto) {
ExtendedChart.prototype[name] = proto[name];
}
zrUtil.extend(ExtendedChart.prototype, proto);
ExtendedChart.extend = Super.extend;
zrUtil.inherits(ExtendedChart, Super);
if (proto.type) {
if (chartClassStore[proto.type]) {
// Warning
}
chartClassStore[proto.type] = ExtendedChart;
}
return ExtendedChart;
return Chart.registerClass(ExtendedChart, proto.type);
};
/**
* Create a chart by a given option
*/
Chart.create = function (chartType) {
var ExtendedChart = chartClassStore[chartType];
if (! ExtendedChart) {
// Error
}
return new ExtendedChart();
};
// And capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
componentUtil.enableClassManagement(Chart);
return Chart;
});
\ No newline at end of file
......@@ -2,7 +2,7 @@ define(function (require) {
var zrUtil = require('zrender/core/util');
var Group = require('zrender/container/Group');
var unique = require('../util/unique');
var componentUtil = require('../util/component');
var Component = function () {
/**
......@@ -15,7 +15,7 @@ define(function (require) {
* @type {string}
* @readOnly
*/
this.uid = unique.getUID('viewComponent');
this.uid = componentUtil.getUID('viewComponent');
};
Component.prototype = {
......@@ -29,9 +29,6 @@ define(function (require) {
dispose: function () {}
};
var componentClassStore = {};
var componentTypeList = [];
Component.extend = function (proto) {
var Super = this;
......@@ -39,37 +36,17 @@ define(function (require) {
Super.call(this);
};
for (var name in proto) {
ExtendedComponent.prototype[name] = proto[name];
}
zrUtil.extend(ExtendedComponent.prototype, proto);
ExtendedComponent.extend = Super.extend;
zrUtil.inherits(ExtendedComponent, Super);
if (proto.type) {
if (componentClassStore[proto.type]) {
// Error exists
return;
}
componentClassStore[proto.type] = ExtendedComponent;
componentTypeList.push(proto.type);
}
return ExtendedComponent;
};
Component.eachAvailableComponent = function (cb, context) {
zrUtil.each(componentTypeList, cb, context);
return Component.registerClass(ExtendedComponent, proto.type);
};
Component.create = function (type) {
var Component = componentClassStore[type];
if (! Component) {
// Error
}
return new Component();
}
// And capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
componentUtil.enableClassManagement(Component);
return Component;
});
\ No newline at end of file
/**
* @file Visual coding.
*/
define(function (require) {
var echarts = require('../../echarts');
var zrUtil = require('zrender/core/util');
var linearMap = require('../util/number').linearMap;
var VisualCoding = function (option, ecModel, extendMethods) {
this.option = option;
this.ecModel = ecModel;
/**
* @readOnly
*/
this.type = option.type;
zrUtil.extend(this, visualHandlers[this.type]);
zrUtil.extend(this, extendMethods);
}
VisualCoding.prototype = {
get: function (attr) {
return this.option[attr];
},
constructor: VisualCoding,
setDataVisual: zrUtil.noop,
isValueActive: zrUtil.noop,
mapValueToVisual: zrUtil.noop,
getValueExtent: zrUtil.noop,
};
var visualHandlers = {
color: {
setDataVisual: function (data) {
// FIXME
// 目前只考虑了List
data.each(['value'], function (value, index) {
var color = this.isValueActive(value)
? this.mapValueToVisual(value)
: this.option.inactiveVisual // FIXME
data.setItemVisual(index, color);
})
},
mapValueToVisual: function (value) {
var thisOption = this.option;
var visualData = thisOption.data;
var valueExtent = this.getValueExtent();
return linearMap()
}
}
};
return VisualCoding;
});
<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/scatter',
'echarts/component/legend',
'echarts/component/grid',
'echarts/component/dataRangePiecewise'
], function (echarts) {
var chart = echarts.init(document.getElementById('main'), null, {
renderer: 'canvas'
});
var data1 = [];
var data2 = [];
var data3 = [];
for (var i = 0; i < 100; i++) {
data1.push([Math.random() * 5, Math.random() * 4, Math.random()]);
data2.push([Math.random() * 10, Math.random() * 5, Math.random()]);
data3.push([Math.random() * 15, Math.random() * 10, Math.random()]);
}
chart.setOption({
legend: {
data: ['scatter', 'scatter2', 'scatter3']
},
xAxis: {
type: 'value',
splitLine: {
show: false
}
},
yAxis: {
type: 'value',
splitLine: {
show: false
}
},
dataRange: {
show: true,
splitNumber: 7
},
series: [{
name: 'scatter',
type: 'scatter',
itemStyle: {
normal: {
opacity: 0.8,
shadowBlur: 10,
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
symbolSize: function (val) {
return val[2] * 40;
},
data: data1
}, {
name: 'scatter2',
type: 'scatter',
itemStyle: {
normal: {
opacity: 0.8,
shadowBlur: 10,
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
symbolSize: function (val) {
return val[2] * 40;
},
data: data2
}, {
name: 'scatter3',
type: 'scatter',
itemStyle: {
normal: {
opacity: 0.8,
shadowBlur: 10,
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
symbolSize: function (val) {
return val[2] * 40;
},
data: data3
}]
});
})
</script>
</body>
</html>
\ No newline at end of file
......@@ -34,7 +34,7 @@
for (var i = 0; i < 200; i++) {
xAxisData.push('类目' + i);
data1.push(Math.random() * 5);
data1.push(Math.random() * 4);
data2.push(Math.random());
data3.push(Math.random());
}
......
......@@ -2,7 +2,7 @@ document.write('<script src="ut/core/utHelper.js"><\/script>');
// Specs ...
document.write('<script src="ut/spec/util/graphic.js"><\/script>');
document.write('<script src="ut/spec/util/model.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/data/List.js"><\/script>');
......@@ -8,6 +8,19 @@
var nativeSlice = Array.prototype.slice;
/**
* @param {*} target
* @param {*} source
*/
helper.extend = function (target, source) {
for (var key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key];
}
}
return target;
}
/**
* @public
*/
......
describe('dataZoom#helper', function() {
describe('util/model', function() {
var utHelper = window.utHelper;
var helper;
var modelUtil;
beforeAll(function (done) { // jshint ignore:line
utHelper.resetPackageLoader(function () {
window.require(['echarts/component/dataZoom/helper'], function (h) {
helper = h;
window.require(['echarts/util/model'], function (h) {
modelUtil = h;
done();
});
});
});
describe('findLinkSet', function () {
function makeRecords(result) {
var o = {};
modelUtil.eachAxisDim(function (dimNames) {
o[dimNames.name] = {};
var r = result[dimNames.name] || [];
for (var i = 0; i < r.length; i++) {
o[dimNames.name][r[i]] = true;
}
});
return o;
}
describe('findLinkedNodes', function () {
function forEachModel(models, callback) {
for (var i = 0; i < models.length; i++) {
......@@ -24,26 +36,26 @@ describe('dataZoom#helper', function() {
return model[dimNames.axisIndex];
}
it('findLinkSet_base', function (done) {
it('findLinkedNodes_base', function (done) {
var models = [
{xAxisIndex: [1, 2], yAxisIndex: [0]},
{xAxisIndex: [3], yAxisIndex: [1]},
{xAxisIndex: [5], yAxisIndex: []},
{xAxisIndex: [2, 5], yAxisIndex: []}
];
var result = helper.findLinkSet(
var result = modelUtil.createLinkedNodesFinder(
utHelper.curry(forEachModel, models),
axisIndicesGetter,
models[0]
);
modelUtil.eachAxisDim,
axisIndicesGetter
)(models[0]);
expect(result).toEqual({
models: [models[0], models[3], models[2]],
dims: {x: [1, 2, 5], y: [0]}
nodes: [models[0], models[3], models[2]],
records: makeRecords({x: [1, 2, 5], y: [0]})
});
done();
});
it('findLinkSet_crossXY', function (done) {
it('findLinkedNodes_crossXY', function (done) {
var models = [
{xAxisIndex: [1, 2], yAxisIndex: [0]},
{xAxisIndex: [3], yAxisIndex: [3, 0]},
......@@ -51,19 +63,19 @@ describe('dataZoom#helper', function() {
{xAxisIndex: [5, 3], yAxisIndex: []},
{xAxisIndex: [8], yAxisIndex: [4]}
];
var result = helper.findLinkSet(
var result = modelUtil.createLinkedNodesFinder(
utHelper.curry(forEachModel, models),
axisIndicesGetter,
models[0]
);
modelUtil.eachAxisDim,
axisIndicesGetter
)(models[0]);
expect(result).toEqual({
models: [models[0], models[1], models[2], models[3]],
dims: {x: [1, 2, 3, 5, 6], y: [0, 3, 9]}
nodes: [models[0], models[1], models[2], models[3]],
records: makeRecords({x: [1, 2, 3, 5, 6], y: [0, 3, 9]})
});
done();
});
it('findLinkSet_emptySourceModel', function (done) {
it('findLinkedNodes_emptySourceModel', function (done) {
var models = [
{xAxisIndex: [1, 2], yAxisIndex: [0]},
{xAxisIndex: [3], yAxisIndex: [3, 0]},
......@@ -71,13 +83,14 @@ describe('dataZoom#helper', function() {
{xAxisIndex: [5, 3], yAxisIndex: []},
{xAxisIndex: [8], yAxisIndex: [4]}
];
var result = helper.findLinkSet(
var result = modelUtil.createLinkedNodesFinder(
utHelper.curry(forEachModel, models),
modelUtil.eachAxisDim,
axisIndicesGetter
);
)();
expect(result).toEqual({
models: [],
dims: {x: [], y: []}
nodes: [],
records: makeRecords({x: [], y: []})
});
done();
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册