Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
x649585723
incubator-echarts
提交
bfc138af
I
incubator-echarts
项目概览
x649585723
/
incubator-echarts
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
I
incubator-echarts
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bfc138af
编写于
12月 01, 2017
作者:
S
sushuang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
tweak
上级
696293d9
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
406 addition
and
316 deletion
+406
-316
src/chart/helper/SymbolDrawStream.js
src/chart/helper/SymbolDrawStream.js
+5
-15
src/data/List.js
src/data/List.js
+117
-43
src/echarts.js
src/echarts.js
+65
-127
src/layout/points.js
src/layout/points.js
+4
-9
src/model/Global.js
src/model/Global.js
+10
-1
src/model/OptionManager.js
src/model/OptionManager.js
+8
-0
src/model/Series.js
src/model/Series.js
+19
-35
src/stream/Scheduler.js
src/stream/Scheduler.js
+174
-76
src/visual/symbol.js
src/visual/symbol.js
+4
-10
未找到文件。
src/chart/helper/SymbolDrawStream.js
浏览文件 @
bfc138af
...
...
@@ -62,14 +62,9 @@ symbolDrawProto.resetData = function (seriesModel, isIgnore) {
});
group
.
enableStream
();
group
.
renderTask
.
reset
();
dataEachTask
.
pipe
(
group
.
renderTask
);
// ??? better way?
dataEachTask
.
pipelineId
=
seriesModel
.
uid
;
dataEachTask
.
updateLayoutBase
=
true
;
return
dataEachTask
;
seriesModel
.
pipeTask
(
dataEachTask
,
'
render
'
,
'
updateLayoutBase
'
);
};
symbolDrawProto
.
updateLayout
=
function
()
{
...
...
@@ -82,8 +77,8 @@ symbolDrawProto.updateLayout = function () {
var
data
=
seriesModel
.
getData
();
var
t
ask
=
createTask
({
lis
t
:
data
,
var
dataEachT
ask
=
createTask
({
inpu
t
:
data
,
progress
:
function
(
params
,
notify
)
{
var
dueIndex
=
params
.
dueIndex
;
for
(;
dueIndex
<
params
.
dueEnd
;
dueIndex
++
)
{
...
...
@@ -97,14 +92,9 @@ symbolDrawProto.updateLayout = function () {
});
group
.
enableStream
();
// group.renderTask.reset({reuseData: true});
group
.
renderTask
.
reset
();
task
.
pipe
(
group
.
renderTask
);
// ??? better way?
task
.
pipelineId
=
group
.
renderTask
.
pipelineId
=
seriesModel
.
uid
;
return
task
;
dataEachTask
.
pipe
(
group
.
renderTask
);
seriesModel
.
pipeTask
(
dataEachTask
,
'
render
'
);
};
symbolDrawProto
.
remove
=
function
(
enableAnimation
)
{
...
...
src/data/List.js
浏览文件 @
bfc138af
...
...
@@ -266,6 +266,7 @@ listProto.initData = function (data, nameList, dimValueGetter) {
var
dimensionInfoMap
=
this
.
_dimensionInfos
;
var
size
=
data
.
count
();
var
storeSize
=
data
.
getMaxSize
?
data
.
getMaxSize
()
:
size
;
var
idList
=
[];
var
nameRepeatCount
=
this
.
_nameRepeatCount
=
{};
...
...
@@ -278,7 +279,7 @@ listProto.initData = function (data, nameList, dimValueGetter) {
var
dimInfo
=
dimensionInfoMap
[
dimensions
[
i
]];
dimInfo
.
otherDims
.
itemName
===
0
&&
(
nameDimIdx
=
i
);
var
DataCtor
=
dataCtors
[
dimInfo
.
type
];
storage
[
dimensions
[
i
]]
=
new
DataCtor
(
size
);
storage
[
dimensions
[
i
]]
=
new
DataCtor
(
s
toreS
ize
);
}
var
self
=
this
;
...
...
@@ -353,67 +354,125 @@ listProto.initData = function (data, nameList, dimValueGetter) {
this
.
_idList
=
idList
;
};
listProto
.
addData
=
function
(
moreData
,
moreNameList
)
{
moreNameList
=
moreNameList
||
[];
var
originalCount
=
data
.
count
();
var
data
=
this
.
_rawData
;
// ?????????
data
.
_data
.
push
(
moreData
);
listProto
.
getInitTask
=
function
()
{
if
(
!
this
.
_initTask
)
{
this
.
_initTask
=
createTask
({
input
:
this
.
_rawData
,
progress
:
zrUtil
.
bind
(
initProgress
,
this
)
});
}
return
this
.
_initTask
;
};
function
initProgress
(
params
,
notify
)
{
var
data
=
this
.
_rawData
;
var
storage
=
this
.
_storage
;
var
indices
=
this
.
indices
;
var
dimensions
=
this
.
dimensions
;
var
size
=
data
.
count
();
var
nameDimIdx
;
var
nameRepeatCount
=
this
.
_nameRepeatCount
;
var
nameList
=
this
.
_nameList
;
var
idList
=
this
.
_idList
;
var
nameDimIdx
;
// ??? nameReplaceCount is not supported!!!
// var nameRepeatCount = this._nameRepeatCount = {};
// extract ????????????
for
(
var
i
=
0
;
i
<
size
;
i
++
)
{
var
dataIndex
=
originalCount
+
i
;
var
dataItem
=
data
.
getItem
(
dataIndex
);
// ??? duplicated code
var
dueIndex
=
params
.
dueIndex
;
var
dueEnd
=
params
.
dueEnd
;
if
(
__DEV__
)
{
dimensions
.
length
&&
zrUtil
.
assert
(
storage
[
dimensions
[
0
]].
length
>=
dueEnd
);
}
for
(;
dueIndex
<
params
.
dueEnd
;
dueIndex
++
)
{
var
dataItem
=
data
.
getItem
(
dueIndex
);
// Store the data by dimensions
for
(
var
k
=
0
;
k
<
dimensions
.
length
;
k
++
)
{
var
dim
=
dimensions
[
k
];
var
dimStorage
=
storage
[
dim
];
// PENDING NULL is empty or zero
dimStorage
[
dataIndex
]
=
this
.
_dimValueGetter
(
dataItem
,
dim
,
dataIndex
,
k
);
// ??? enlarge TypedArray
dimStorage
[
dueIndex
]
=
this
.
_dimValueGetter
(
dataItem
,
dim
,
dueIndex
,
k
);
}
indices
.
push
(
dataIndex
);
}
// extract ??????????
// Use the name in option and create id
for
(
var
i
=
0
;
i
<
size
;
i
++
)
{
var
dataIndex
=
originalCount
+
i
;
var
dataItem
=
data
.
getItem
(
dataIndex
);
if
(
!
moreNameList
[
i
]
&&
dataItem
)
{
indices
.
push
(
dueIndex
);
// Use the name in option and create id
if
(
!
nameList
[
dueIndex
]
&&
dataItem
)
{
if
(
dataItem
.
name
!=
null
)
{
moreNameList
[
i
]
=
dataItem
.
name
;
nameList
[
dueIndex
]
=
dataItem
.
name
;
}
else
if
(
nameDimIdx
!=
null
)
{
moreNameList
[
i
]
=
storage
[
dimensions
[
nameDimIdx
]][
dataIndex
];
}
}
var
name
=
moreNameList
[
i
];
// Try using the id in option
var
id
=
dataItem
&&
dataItem
.
id
;
if
(
id
==
null
&&
name
)
{
// Use name as id and add counter to avoid same name
nameRepeatCount
[
name
]
=
nameRepeatCount
[
name
]
||
0
;
id
=
name
;
if
(
nameRepeatCount
[
name
]
>
0
)
{
id
+=
'
__ec__
'
+
nameRepeatCount
[
name
];
nameList
[
dueIndex
]
=
storage
[
dimensions
[
nameDimIdx
]][
dueIndex
];
}
nameRepeatCount
[
name
]
++
;
}
id
!=
null
&&
(
idList
[
dataIndex
]
=
id
);
nameList
[
dataIndex
]
=
moreNameList
[
i
];
// ??? do not fill idList and do not checked by nameRepeatCount.
}
};
notify
(
dueIndex
);
}
// listProto.addData = function (moreData, moreNameList) {
// moreNameList = moreNameList || [];
// var originalCount = data.count();
// var data = this._rawData;
// // ?????????
// data._data.push(moreData);
// var storage = this._storage;
// var indices = this.indices;
// var dimensions = this.dimensions;
// var size = data.count();
// var nameDimIdx;
// var nameRepeatCount = this._nameRepeatCount;
// var nameList = this._nameList;
// var idList = this._idList;
// // extract ????????????
// for (var i = 0; i < size; i++) {
// var dataIndex = originalCount + i;
// var dataItem = data.getItem(dataIndex);
// for (var k = 0; k < dimensions.length; k++) {
// var dim = dimensions[k];
// var dimStorage = storage[dim];
// // PENDING NULL is empty or zero
// dimStorage[dataIndex] = this._dimValueGetter(dataItem, dim, dataIndex, k);
// }
// indices.push(dataIndex);
// }
// // extract ??????????
// // Use the name in option and create id
// for (var i = 0; i < size; i++) {
// var dataIndex = originalCount + i;
// var dataItem = data.getItem(dataIndex);
// if (!moreNameList[i] && dataItem) {
// if (dataItem.name != null) {
// moreNameList[i] = dataItem.name;
// }
// else if (nameDimIdx != null) {
// moreNameList[i] = storage[dimensions[nameDimIdx]][dataIndex];
// }
// }
// var name = moreNameList[i];
// // Try using the id in option
// var id = dataItem && dataItem.id;
// if (id == null && name) {
// // Use name as id and add counter to avoid same name
// nameRepeatCount[name] = nameRepeatCount[name] || 0;
// id = name;
// if (nameRepeatCount[name] > 0) {
// id += '__ec__' + nameRepeatCount[name];
// }
// nameRepeatCount[name]++;
// }
// id != null && (idList[dataIndex] = id);
// nameList[dataIndex] = moreNameList[i];
// }
// };
/**
* @return {number}
...
...
@@ -814,7 +873,7 @@ listProto.createEachTask = function (dims, cb, stack) {
return
createTask
({
lis
t
:
list
,
inpu
t
:
list
,
progress
:
function
(
params
,
notify
)
{
var
dimSize
=
dims
.
length
;
...
...
@@ -1303,6 +1362,21 @@ listProto.cloneShallow = function () {
return
list
;
};
// ??? duplicate with cloneShallow?
listProto
.
createCloneShallowTask
=
function
()
{
return
createTask
({
input
:
this
,
output
:
this
.
cloneShallow
(),
progress
:
function
(
params
,
notify
)
{
var
dueIndex
=
params
.
dueIndex
;
for
(;
dueIndex
<
params
.
dueEnd
;
dueIndex
++
)
{
this
.
output
.
indices
[
dueIndex
]
=
this
.
input
.
indices
[
dueIndex
];
}
notify
(
dueIndex
);
}
});
};
// ???
listProto
.
getFrameDataIndex
=
function
()
{
return
this
.
_frameDataIndex
;
...
...
src/echarts.js
浏览文件 @
bfc138af
...
...
@@ -43,7 +43,6 @@ export var dependencies = {
// ??? frame remain time in UI thread: 20ms? 16ms?
var
TEST_FRAME_REMAIN_TIME
=
1
;
var
TEST_PROGRESS_STEP
=
300
;
var
PRIORITY_PROCESSOR_FILTER
=
1000
;
var
PRIORITY_PROCESSOR_STATISTIC
=
5000
;
...
...
@@ -80,11 +79,9 @@ var HAS_GRADIENT_OR_PATTERN_BG = '__hasGradientOrPatternBg';
var
OPTION_UPDATED
=
'
__optionUpdated
'
;
var
ACTION_REG
=
/^
[
a-zA-Z0-9_
]
+$/
;
var
UNFINISHED_INDEX_DATA
=
0
;
var
UNFINISHED_INDEX_PROCESSOR
=
1
;
var
UNFINISHED_INDEX_VISUAL
=
2
;
var
UNFINISHED_INDEX_RENDER
=
3
;
// ??? defined in scheduler?
var
STAGE_DATA_INIT
=
'
dataInit
'
;
var
STAGE_DATA_CLONE
=
'
dataClone
'
;
var
STAGE_PROCESSOR
=
'
processor
'
;
var
STAGE_VISUAL
=
'
visual
'
;
var
STAGE_RENDER
=
'
render
'
;
...
...
@@ -206,13 +203,6 @@ function ECharts(dom, theme, opts) {
*/
this
.
_api
=
createExtensionAPI
(
this
);
// ??? reset when setOption(not merge)?
/**
* @type {Array.<boolean>}
*/
this
.
_unfinished
=
[];
// ??? reset when setOption(not merge)?
/**
* @type {module:echarts/stream/Scheduler}
*/
...
...
@@ -252,8 +242,7 @@ function ECharts(dom, theme, opts) {
var
echartsProto
=
ECharts
.
prototype
;
echartsProto
.
_onframe
=
function
()
{
// ???
if
(
this
.
isDisposed
())
{
if
(
this
.
_disposed
)
{
return
;
}
...
...
@@ -263,6 +252,7 @@ echartsProto._onframe = function () {
this
[
IN_MAIN_PROCESS
]
=
true
;
// ??? conflict?
updateMethods
.
prepareAndUpdate
.
call
(
this
);
this
[
IN_MAIN_PROCESS
]
=
false
;
...
...
@@ -274,46 +264,32 @@ echartsProto._onframe = function () {
triggerUpdatedEvent
.
call
(
this
,
silent
);
}
progressInFrame
(
this
);
};
function
progressInFrame
(
ecIns
)
{
// Stream progress.
var
remainTime
=
TEST_FRAME_REMAIN_TIME
;
var
unfinished
=
ecIns
.
_unfinished
;
var
b
;
do
{
var
startTime
=
+
new
Date
();
if
(
unfinished
[
UNFINISHED_INDEX_PROCESSOR
])
{
b
=
1
;
updateUnfinished
(
unfinished
,
progressStage
(
ecIns
,
STAGE_PROCESSOR
),
UNFINISHED_INDEX_PROCESSOR
);
}
var
scheduler
=
this
.
_scheduler
;
// ???
// coordSys update
if
(
scheduler
.
unfinished
)
{
scheduler
.
unfinished
=
false
;
do
{
var
startTime
=
+
new
Date
();
scheduler
.
progressStage
(
STAGE_DATA_INIT
);
scheduler
.
progressStage
(
STAGE_DATA_CLONE
);
scheduler
.
progressStage
(
STAGE_PROCESSOR
);
// ???
// coordSys update
if
(
unfinished
[
UNFINISHED_INDEX_VISUAL
])
{
// console.log('------------- ec frame visual -------------', remainTime);
b
=
1
;
updateUnfinished
(
unfinished
,
progressStage
(
ecIns
,
STAGE_VISUAL
),
UNFINISHED_INDEX_VISUAL
);
}
if
(
unfinished
[
UNFINISHED_INDEX_RENDER
])
{
b
=
1
;
updateUnfinished
(
unfinished
,
progressRender
(
ecIns
,
ecIns
.
_model
),
UNFINISHED_INDEX_RENDER
);
}
scheduler
.
progressStage
(
STAGE_VISUAL
);
remainTime
-=
(
+
new
Date
()
-
startTime
);
}
while
(
remainTime
>
0
&&
(
unfinished
[
UNFINISHED_INDEX_PROCESSOR
]
||
unfinished
[
UNFINISHED_INDEX_VISUAL
]
||
unfinished
[
UNFINISHED_INDEX_RENDER
]
));
progressRender
(
this
,
this
.
_model
);
if
(
b
)
{
console
.
log
(
ecIns
.
_scheduler
.
_pipelines
);
}
}
remainTime
-=
(
+
new
Date
()
-
startTime
);
}
while
(
remainTime
>
0
&&
scheduler
.
unfinished
);
}
};
/**
...
...
@@ -362,6 +338,7 @@ echartsProto.setOption = function (option, notMerge, lazyUpdate) {
var
optionManager
=
new
OptionManager
(
this
.
_api
);
var
theme
=
this
.
_theme
;
var
ecModel
=
this
.
_model
=
new
GlobalModel
(
null
,
null
,
theme
,
optionManager
);
ecModel
.
scheduler
=
this
.
_scheduler
;
ecModel
.
init
(
null
,
null
,
theme
,
optionManager
);
}
...
...
@@ -770,20 +747,18 @@ var updateMethods = {
var
api
=
this
.
_api
;
var
zr
=
this
.
_zr
;
var
coordSysMgr
=
this
.
_coordSysMgr
;
var
scheduler
=
this
.
_scheduler
;
// update before setOption
if
(
!
ecModel
)
{
return
;
}
scheduler
.
clearTemps
();
// Fixme First time update ?
ecModel
.
restoreData
();
// Reset pipeline.
this
.
_scheduler
.
clear
();
each
(
ecModel
.
getSeries
(),
function
(
series
)
{
this
.
_scheduler
.
addPipeline
(
series
.
uid
);
},
this
);
// 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.
...
...
@@ -804,6 +779,8 @@ var updateMethods = {
startRender
(
this
,
ecModel
,
api
,
payload
);
scheduler
.
flushTemps
(
'
updateBase
'
);
// Set background
var
backgroundColor
=
ecModel
.
get
(
'
backgroundColor
'
)
||
'
transparent
'
;
...
...
@@ -864,14 +841,18 @@ var updateMethods = {
return
;
}
this
.
_scheduler
.
clearTemps
();
ecModel
.
eachSeries
(
function
(
seriesModel
)
{
seriesModel
.
getData
().
clearAllVisual
();
});
// Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
startVisualEncoding
(
this
,
ecModel
,
this
.
_api
,
payload
,
null
,
'
updateViewBase
'
);
startVisualEncoding
(
this
,
ecModel
,
this
.
_api
,
payload
,
null
);
invokeUpdateMethod
.
call
(
this
,
'
updateView
'
,
ecModel
,
payload
);
this
.
_scheduler
.
flushTemps
(
'
updateViewBase
'
);
},
/**
...
...
@@ -886,14 +867,18 @@ var updateMethods = {
return
;
}
this
.
_scheduler
.
clearTemps
();
ecModel
.
eachSeries
(
function
(
seriesModel
)
{
seriesModel
.
getData
().
clearAllVisual
();
});
// Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
startVisualEncoding
(
this
,
ecModel
,
this
.
_api
,
payload
,
false
,
'
updateVisualBase
'
);
startVisualEncoding
(
this
,
ecModel
,
this
.
_api
,
payload
,
false
);
invokeUpdateMethod
.
call
(
this
,
'
updateVisual
'
,
ecModel
,
payload
);
this
.
_scheduler
.
flushTemps
(
'
updateVisualBase
'
);
},
/**
...
...
@@ -908,10 +893,14 @@ var updateMethods = {
return
;
}
this
.
_scheduler
.
clearTemps
();
// Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
startVisualEncoding
(
this
,
ecModel
,
this
.
_api
,
payload
,
true
,
'
updateLayoutBase
'
);
startVisualEncoding
(
this
,
ecModel
,
this
.
_api
,
payload
,
true
);
invokeUpdateMethod
.
call
(
this
,
'
updateLayout
'
,
ecModel
,
payload
);
this
.
_scheduler
.
flushTemps
(
'
updateLayoutBase
'
);
},
/**
...
...
@@ -1179,32 +1168,19 @@ function triggerUpdatedEvent(silent) {
!
silent
&&
this
.
trigger
(
'
updated
'
);
}
// ??????
// echartsProto.addData = function (params) {
// var seriesIndex = params.seriesIndex;
// var moreData = params.data;
// var ecModel = this.getModel();
// var seriesModel = ecModel.getSeries(seriesIndex);
// var rawData = seriesModel.getRawData();
// rawData.addData(moreData);
// // ?????
// ???
echartsProto
.
addData
=
function
(
params
)
{
var
seriesIndex
=
params
.
seriesIndex
;
var
ecModel
=
this
.
getModel
();
var
seriesModel
=
ecModel
.
getSeries
(
seriesIndex
);
// // ??? addData 应该是继续渲染而不是重启全部渲染?
// // 什么场景下需要重启全部渲染?
// updateMethods.update();
// // ??????
// if (rawData.count() > rawData.getChunkSize()) {
// requestAnimationFrame(step);
// }
if
(
__DEV__
)
{
zrUtil
.
assert
(
params
.
data
&&
seriesModel
);
}
// function step() {
// // if (rawData.
// }
// };
var
rawData
=
seriesModel
.
getRawData
();
rawData
.
addData
(
params
.
data
);
};
/**
* Register event
...
...
@@ -1232,11 +1208,9 @@ function invokeUpdateMethod(methodName, ecModel, payload) {
// ??? duplicate code with `startRender`?
// Upate all charts
var
scheduler
=
this
.
_scheduler
;
ecModel
.
eachSeries
(
function
(
seriesModel
,
idx
)
{
var
chart
=
this
.
_chartsMap
[
seriesModel
.
__viewId
];
var
task
=
chart
[
methodName
](
seriesModel
,
ecModel
,
api
,
payload
);
task
&&
scheduler
.
pipeTasks
([
task
],
STAGE_RENDER
);
chart
[
methodName
](
seriesModel
,
ecModel
,
api
,
payload
);
// ??? updateZ(seriesModel, chart);
...
...
@@ -1346,10 +1320,8 @@ function stackSeriesData(ecModel) {
*/
function
startProcessors
(
ecIns
,
ecModel
,
api
)
{
each
(
dataProcessorFuncs
,
function
(
processor
,
index
)
{
var
tasks
=
processor
.
func
(
ecModel
,
api
);
ecIns
.
_scheduler
.
pipeTasks
(
tasks
,
STAGE_PROCESSOR
);
processor
.
func
(
ecModel
,
api
);
});
updateUnfinished
(
ecIns
.
_unfinished
,
true
,
UNFINISHED_INDEX_PROCESSOR
);
}
/**
...
...
@@ -1360,10 +1332,10 @@ function startProcessors(ecIns, ecModel, api) {
* @param {boolean} [layoutFilter] `true`: only layout,
* `false`: only not layout,
* `null`/`undefined`: all.
* @param {string}
partialBase
* @param {string}
taskBaseTag
* @private
*/
function
startVisualEncoding
(
ecIns
,
ecModel
,
api
,
payload
,
layoutFilter
,
partialBase
)
{
function
startVisualEncoding
(
ecIns
,
ecModel
,
api
,
payload
,
layoutFilter
)
{
if
(
layoutFilter
!==
true
)
{
ecModel
.
clearColorPalette
();
ecModel
.
eachSeries
(
function
(
seriesModel
)
{
...
...
@@ -1377,12 +1349,9 @@ function startVisualEncoding(ecIns, ecModel, api, payload, layoutFilter, partial
||
(
layoutFilter
===
false
&&
!
isLayout
)
||
(
layoutFilter
===
true
&&
isLayout
)
)
{
var
tasks
=
visual
.
func
(
ecModel
,
api
,
payload
);
ecIns
.
_scheduler
.
pipeTasks
(
tasks
,
STAGE_VISUAL
,
partialBase
);
visual
.
func
(
ecModel
,
api
,
payload
);
}
});
updateUnfinished
(
ecIns
.
_unfinished
,
true
,
UNFINISHED_INDEX_VISUAL
);
}
/**
...
...
@@ -1402,16 +1371,13 @@ function startRender(ecIns, ecModel, api, payload) {
chart
.
__alive
=
false
;
});
var
scheduler
=
ecIns
.
_scheduler
;
// ??? The key should be `__viewId` but not index. consider view change !!!
// Render all charts
ecModel
.
eachSeries
(
function
(
seriesModel
)
{
var
chartView
=
ecIns
.
_chartsMap
[
seriesModel
.
__viewId
];
chartView
.
__alive
=
true
;
var
task
=
chartView
.
render
(
seriesModel
,
ecModel
,
api
,
payload
);
task
&&
scheduler
.
pipeTasks
([
task
],
STAGE_RENDER
);
chartView
.
render
(
seriesModel
,
ecModel
,
api
,
payload
);
// ??? chartView.group.silent = !!seriesModel.get('silent');
...
...
@@ -1430,15 +1396,11 @@ function startRender(ecIns, ecModel, api, payload) {
chart
.
remove
(
ecModel
,
api
);
}
});
// ??? add upateUnfinished to other partial update render!
updateUnfinished
(
ecIns
.
_unfinished
,
true
,
UNFINISHED_INDEX_RENDER
);
}
function
progressRender
(
ecIns
,
ecModel
)
{
var
unfinished
;
unfinished
|=
progressStage
(
ecIns
,
STAGE_RENDER
);
ecIns
.
_scheduler
.
progressStage
(
STAGE_RENDER
);
// ???
// ecModel.eachSeries(function (seriesModel, idx) {
...
...
@@ -1450,23 +1412,8 @@ function progressRender(ecIns, ecModel) {
// ??? updateProgressiveAndBlend(seriesModel, chartView);
// });
return
unfinished
;
}
function
progressStage
(
ecIns
,
stage
)
{
var
unfinished
;
var
tasks
=
ecIns
.
_scheduler
.
getTasksByStage
(
stage
);
each
(
tasks
,
function
(
task
)
{
task
.
progress
({
step
:
TEST_PROGRESS_STEP
});
unfinished
|=
task
.
unfinished
();
});
return
unfinished
;
}
var
MOUSE_EVENT_NAMES
=
[
'
click
'
,
'
dblclick
'
,
'
mouseover
'
,
'
mouseout
'
,
'
mousemove
'
,
'
mousedown
'
,
'
mouseup
'
,
'
globalout
'
,
'
contextmenu
'
...
...
@@ -1616,15 +1563,6 @@ function updateProgressiveAndBlend(seriesModel, chartView) {
});
}
function
updateUnfinished
(
undefinedRecord
,
unfi
,
stageIndex
)
{
var
count
=
Math
.
max
(
undefinedRecord
.
length
,
stageIndex
+
1
);
undefinedRecord
[
stageIndex
]
=
unfi
;
for
(
++
stageIndex
;
stageIndex
<
count
;
stageIndex
++
)
{
// update process should clear consequent visual stage using xor.
undefinedRecord
[
stageIndex
]
|=
unfi
;
}
}
/**
* @param {module:echarts/model/Series|module:echarts/model/Component} model
* @param {module:echarts/view/Component|module:echarts/view/Chart} view
...
...
src/layout/points.js
浏览文件 @
bfc138af
export
default
function
(
seriesType
,
ecModel
)
{
var
tasks
=
[];
ecModel
.
eachSeriesByType
(
seriesType
,
function
(
seriesModel
)
{
var
task
=
createTask
(
seriesType
,
seriesModel
);
if
(
task
)
{
// ??? better way?
task
.
pipelineId
=
seriesModel
.
uid
;
tasks
.
push
(
task
);
}
seriesModel
.
pipeTask
(
createTask
(
seriesType
,
seriesModel
),
'
visual
'
);
});
return
tasks
;
}
function
createTask
(
seriesType
,
seriesModel
)
{
...
...
src/model/Global.js
浏览文件 @
bfc138af
...
...
@@ -126,6 +126,7 @@ var GlobalModel = Model.extend({
var
option
=
this
.
option
;
var
componentsMap
=
this
.
_componentsMap
;
var
newCptTypes
=
[];
var
scheduler
=
this
.
scheduler
;
// 如果不存在对应的 component model 则直接 merge
each
(
newOption
,
function
(
componentOption
,
mainType
)
{
...
...
@@ -151,6 +152,7 @@ var GlobalModel = Model.extend({
this
.
_seriesIndices
=
this
.
_seriesIndices
||
[];
function
visitComponent
(
mainType
,
dependencies
)
{
var
newCptOptionList
=
modelUtil
.
normalizeToArray
(
newOption
[
mainType
]);
var
mapResult
=
modelUtil
.
mappingToExists
(
...
...
@@ -213,6 +215,9 @@ var GlobalModel = Model.extend({
componentModel
=
new
ComponentModelClass
(
newCptOption
,
this
,
this
,
extraOpt
);
if
(
mainType
===
'
series
'
)
{
this
.
scheduler
.
initPipeline
(
componentModel
);
}
zrUtil
.
extend
(
componentModel
,
extraOpt
);
componentModel
.
init
(
newCptOption
,
this
,
this
,
extraOpt
);
// Call optionUpdated after init.
...
...
@@ -229,7 +234,11 @@ var GlobalModel = Model.extend({
// Backup series for filtering.
if
(
mainType
===
'
series
'
)
{
this
.
_seriesIndices
=
createSeriesIndices
(
componentsMap
.
get
(
'
series
'
));
var
seriesModels
=
componentsMap
.
get
(
'
series
'
);
this
.
_seriesIndices
=
createSeriesIndices
(
seriesModels
);
// Reset pipeline, should be after `restoreData`.
scheduler
.
clearUnusedPipelines
(
seriesModels
);
scheduler
.
flushTemps
(
'
start
'
,
seriesModels
);
}
}
},
...
...
src/model/OptionManager.js
浏览文件 @
bfc138af
...
...
@@ -139,6 +139,14 @@ OptionManager.prototype = {
* @return {Object} Init option
*/
setOption
:
function
(
rawOption
,
optionPreprocessorFuncs
)
{
// ??? not a good way?
if
(
rawOption
)
{
// axis.data?
zrUtil
.
each
(
modelUtil
.
normalizeToArray
(
rawOption
.
series
),
function
(
series
)
{
series
&&
series
.
data
&&
zrUtil
.
setAsPrimitive
(
series
.
data
);
});
}
rawOption
=
clone
(
rawOption
,
true
);
// FIXME
...
...
src/model/Series.js
浏览文件 @
bfc138af
...
...
@@ -82,18 +82,14 @@ var SeriesModel = ComponentModel.extend({
*/
set
(
this
,
'
dataBeforeProcessed
'
,
data
);
/**
* @type {Array}
* @private
*/
set
(
this
,
'
tasks
'
,
[]);
// If we reverse the order (make data firstly, and then make
// dataBeforeProcessed by cloneShallow), cloneShallow will
// cause data.graph.data !== data when using
// module:echarts/data/Graph or module:echarts/data/Tree.
// See module:echarts/data/helper/linkList
this
.
restoreData
();
// ??? should not restoreData here? but called by echart?
// this.restoreData();
},
/**
...
...
@@ -140,10 +136,11 @@ var SeriesModel = ComponentModel.extend({
}
var
data
=
this
.
getInitialData
(
newSeriesOption
,
ecModel
);
// TODO Merge data?
if
(
data
)
{
set
(
this
,
'
data
'
,
data
);
set
(
this
,
'
dataBeforeProcessed
'
,
data
.
cloneShallow
());
// ??? progress data?
set
(
this
,
'
dataBeforeProcessed
'
,
data
);
// ??? should not restoreData here? but called by echart?
// this.restoreData();
}
},
...
...
@@ -324,7 +321,14 @@ var SeriesModel = ComponentModel.extend({
},
restoreData
:
function
()
{
set
(
this
,
'
data
'
,
get
(
this
,
'
dataBeforeProcessed
'
).
cloneShallow
());
var
dataBeforeProcessed
=
get
(
this
,
'
dataBeforeProcessed
'
);
var
dataCloneTask
=
dataBeforeProcessed
.
createCloneShallowTask
();
set
(
this
,
'
data
'
,
dataCloneTask
.
output
);
var
dataInitTask
=
dataBeforeProcessed
.
getInitTask
();
this
.
pipeTask
(
dataInitTask
,
'
dataInit
'
);
this
.
pipeTask
(
dataCloneTask
,
'
dataClone
'
,
'
updateBase
'
);
},
getColorFromPalette
:
function
(
name
,
scope
)
{
...
...
@@ -355,30 +359,10 @@ var SeriesModel = ComponentModel.extend({
*/
getTooltipPosition
:
null
,
// clearPipedTasks: function () {
// get(this, 'tasks').length = 0;
// },
// pipe: function (task) {
// var tasks = get(this, 'tasks');
// var lastTask = tasks[tasks.length - 1];
// lastTask && lastTask.pipe(task);
// tasks.push(task);
// // ??? parallel task? multi-dependency?
// // ??? A bad practice?
// var originalRemove = task.leave;
// task.leave = function () {
// var i = 0;
// for (; i < tasks.length; i++) {
// if (tasks[i] === task) {
// break;
// }
// }
// tasks.length = i;
// originalRemove.call(this);
// };
// }
/**
* @see {module:echarts/stream/Scheduler}
*/
pipeTask
:
null
// /**
// * @public
...
...
src/stream/Scheduler.js
浏览文件 @
bfc138af
...
...
@@ -3,63 +3,135 @@
*/
import
{
__DEV__
}
from
'
../config
'
;
import
{
assert
,
each
}
from
'
zrender/src/core/util
'
;
import
{
assert
,
each
,
createHashMap
,
makeInner
}
from
'
zrender/src/core/util
'
;
import
{
normalizeToArray
}
from
'
../util/model
'
;
var
inner
=
makeInner
();
/**
* @const
*/
var
STAGE
=
{
dataInit
:
0
,
dataClone
:
1
,
processor
:
2
,
visual
:
3
,
render
:
4
};
var
TAG
=
{
updateBase
:
1
,
updateLayoutBase
:
1
,
updateVisualBase
:
1
,
updateViewBase
:
1
};
var
TEST_PROGRESS_STEP
=
300
;
/**
* @constructor
*/
function
Scheduler
()
{
this
.
clear
();
this
.
_pipelineMap
=
createHashMap
();
var
stageMap
=
this
.
_stageMap
=
createHashMap
();
each
(
STAGE
,
function
(
value
,
name
)
{
stageMap
.
set
(
name
,
[]);
});
// this._stageUnfinished = [];
this
.
unfinished
;
}
var
proto
=
Scheduler
.
prototype
;
/**
* Clear all tasks.
*/
proto
.
clear
=
function
()
{
this
.
_pipelines
=
{};
this
.
_stage
=
{
processor
:
[],
visual
:
[],
render
:
[]
};
};
proto
.
progressStage
=
function
(
stage
)
{
// if (!this._stageUnfinished[STAGE[stage]]) {
// return;
// }
proto
.
addPipeline
=
function
(
pipelineId
)
{
this
.
_pipelines
[
pipelineId
]
=
[];
var
unfinished
;
var
tasks
=
this
.
getTasksByStage
(
stage
);
each
(
tasks
,
function
(
task
)
{
task
.
progress
({
step
:
TEST_PROGRESS_STEP
});
unfinished
|=
task
.
unfinished
();
});
this
.
unfinished
|=
unfinished
;
};
/**
* @param {Array} tasks Can be `null`/`undefined`. Should has `task.pipelineId`. // ???
* @param {string} stage 'processor', 'visual', 'render'
* @param {string} [partialBase] 'updateLayoutBase', 'updateVisualBase' or 'updateViewBase'
* @param {Object} host Should has uid.
*/
proto
.
pipeTasks
=
function
(
tasks
,
stage
,
partialBase
)
{
var
pipelines
=
this
.
_pipelines
;
each
(
tasks
,
function
(
task
)
{
var
pipeline
=
pipelines
[
task
.
pipelineId
];
proto
.
initPipeline
=
function
(
host
)
{
var
pipelineId
=
host
.
uid
;
if
(
__DEV__
)
{
assert
(
!
this
.
_pipelineMap
.
get
(
pipelineId
)
&&
!
host
.
pipeTask
);
}
var
pipeline
=
{
tasks
:
[],
temps
:
[]};
this
.
_pipelineMap
.
set
(
pipelineId
,
pipeline
);
if
(
__DEV__
)
{
assert
(
pipeline
);
each
(
pipeline
,
function
(
taskInPipeline
)
{
assert
(
taskInPipeline
!=
task
);
});
}
// Inject method pipeTask
host
.
pipeTask
=
hostPipeTask
;
inner
(
host
).
temps
=
pipeline
.
temps
;
};
var
baseTask
=
partialBase
?
findAddClearPartialBase
(
pipeline
,
partialBase
)
:
pipeline
[
pipeline
.
length
-
1
];
function
hostPipeTask
(
task
,
stage
,
tags
)
{
task
&&
inner
(
this
).
temps
.
push
({
task
:
task
,
stage
:
stage
,
tags
:
tags
});
}
baseTask
&&
baseTask
.
pipe
(
task
);
/**
* @param {Array.<Object>} allHosts Should has uid.
*/
proto
.
clearUnusedPipelines
=
function
(
allHosts
)
{
var
pipelineMap
=
this
.
_pipelineMap
;
var
idMap
=
createHashMap
();
var
stageMap
=
this
.
_stageMap
;
each
(
allHosts
,
function
(
host
)
{
idMap
.
set
(
host
.
uid
,
1
);
});
pipelineMap
.
each
(
function
(
pipeline
,
id
)
{
if
(
!
idMap
.
get
(
id
))
{
clearPipeline
(
stageMap
,
pipeline
,
-
1
);
pipelineMap
.
set
(
id
,
null
);
}
});
};
pipeline
.
push
(
task
);
proto
.
clearTemps
=
function
()
{
this
.
_pipelineMap
.
each
(
clearPipelineTemp
);
};
// ??? Should keep the original register order of tasks
// within single stage. Especially visual and layout.
stage
&&
this
.
_stage
[
stage
].
push
(
task
);
function
clearPipelineTemp
(
pipeline
)
{
pipeline
.
temps
.
length
=
0
;
}
},
this
);
/**
* @param {string} tag
* @param {Array.<Object>} [hosts]
*/
proto
.
flushTemps
=
function
(
tag
,
hosts
)
{
var
pipelineMap
=
this
.
_pipelineMap
;
var
stageMap
=
this
.
_stageMap
;
var
self
=
this
;
hosts
?
each
(
hosts
,
function
(
host
)
{
flushPipelineTemps
(
pipelineMap
.
get
(
host
.
uid
));
})
:
pipelineMap
.
each
(
flushPipelineTemps
);
function
flushPipelineTemps
(
pipeline
)
{
clearPipelineDownstreams
(
stageMap
,
pipeline
,
tag
);
each
(
pipeline
.
temps
,
function
(
tmp
)
{
self
.
unfinished
=
true
;
pipeTask
(
stageMap
,
pipeline
.
tasks
,
tmp
.
task
,
tmp
.
stage
,
tmp
.
tags
);
},
this
);
clearPipelineTemp
(
pipeline
);
}
};
/**
...
...
@@ -68,56 +140,82 @@ proto.pipeTasks = function (tasks, stage, partialBase) {
* who are partial streams, depending on the render task of the full stream,
* and should be cleared if another partial stream is started.
*/
function
findAddClearPartialBase
(
pipeline
,
partialBase
)
{
function
clearPipelineDownstreams
(
stageMap
,
pipeline
,
tag
)
{
var
tasks
=
pipeline
.
tasks
;
var
baseIndex
;
for
(
var
i
=
0
;
i
<
pipeline
.
length
;
i
++
)
{
if
(
pipeline
[
i
][
partialBase
])
{
baseIndex
=
i
;
break
;
if
(
tag
===
'
start
'
)
{
baseIndex
=
-
1
;
}
else
{
for
(
var
i
=
0
;
i
<
tasks
.
length
;
i
++
)
{
if
(
inner
(
tasks
[
i
])[
tag
])
{
baseIndex
=
i
;
break
;
}
}
}
clearPipeline
(
stageMap
,
pipeline
,
baseIndex
);
}
function
pipeTask
(
stageMap
,
pipelineTasks
,
task
,
stage
,
tags
)
{
if
(
__DEV__
)
{
// In case the developer do not mark a task by partailBase.
assert
(
baseIndex
!=
null
);
// In case typo.
stage
&&
assert
(
STAGE
[
stage
]
!=
null
);
each
(
pipelineTasks
,
function
(
taskInPipeline
)
{
assert
(
taskInPipeline
!=
task
);
});
}
// Clear from baseTask
var
baseTask
=
pipeline
[
baseIndex
];
baseTask
.
clearDownstreams
();
pipeline
.
length
=
baseIndex
+
1
;
each
(
normalizeToArray
(
tags
),
function
(
tag
)
{
if
(
__DEV__
)
{
assert
(
TAG
[
tag
]);
}
inner
(
task
)[
tag
]
=
true
;
});
pipelineTasks
.
length
&&
pipelineTasks
[
pipelineTasks
.
length
-
1
].
pipe
(
task
);
pipelineTasks
.
push
(
task
);
return
baseTask
;
// ??? Should keep the original register order of tasks
// within single stage. Especially visual and layout.
stage
&&
stageMap
.
get
(
stage
).
push
(
task
);
}
// keyInfo: {stage, tag}
proto
.
getTasksByStage
=
function
(
stage
)
{
return
this
.
_stage
[
stage
]
.
slice
();
return
this
.
_stage
Map
.
get
(
stage
)
.
slice
();
};
// ???
// // keyInfo: {stage, tag}
// proto.getTasksByTag = function (pipelineId, tag) {
// var tasks = [];
// each(this._pipelines[pipelineId], function (wrap) {
// wrap.tag === tag && tasks.push(wrap.task);
// });
// return tasks;
// };
// ???
// proto.unpipeTaskByKey = function (key) {
// each(this._pipelines, function (pipeline) {
// var index = 0;
// for (; index < pipeline.length; index++) {
// if (pipeline[index].key === key) {
// break;
// }
// }
// if (index > 0 && index < pipeline.length) {
// pipeline[index - 1].unpipe(pipeline[index]);
// }
// pipeline.length = index;
// });
// };
// taskBaseIndex can be -1;
function
clearPipeline
(
stageMap
,
pipeline
,
taskBaseIndex
)
{
var
tasks
=
pipeline
.
tasks
;
if
(
!
tasks
.
length
)
{
return
;
}
if
(
taskBaseIndex
===
-
1
)
{
var
taskBase
=
tasks
[
0
];
taskBase
.
clearDownstreams
();
taskBase
.
reset
();
}
else
{
tasks
[
taskBaseIndex
].
clearDownstreams
();
}
for
(
var
i
=
taskBaseIndex
+
1
;
i
<
tasks
.
length
;
i
++
)
{
inner
(
tasks
[
i
]).
cleared
=
1
;
}
tasks
.
length
=
taskBaseIndex
+
1
;
stageMap
.
each
(
function
(
stageTasks
)
{
for
(
var
i
=
stageTasks
.
length
-
1
;
i
>=
0
;
i
--
)
{
if
(
inner
(
stageTasks
[
i
]).
cleared
)
{
stageTasks
.
splice
(
i
,
1
);
}
}
});
i
=
10
;
}
export
default
Scheduler
;
src/visual/symbol.js
浏览文件 @
bfc138af
export
default
function
(
seriesType
,
defaultSymbolType
,
legendSymbol
,
ecModel
)
{
var
tasks
=
[];
// Encoding visual for all series include which is filtered for legend drawing
ecModel
.
eachRawSeriesByType
(
seriesType
,
function
(
seriesModel
)
{
var
task
=
createTask
(
seriesModel
,
defaultSymbolType
,
legendSymbol
,
ecModel
);
if
(
task
)
{
// ??? better way?
task
.
pipelineId
=
seriesModel
.
uid
;
tasks
.
push
(
task
);
}
seriesModel
.
pipeTask
(
createTask
(
seriesModel
,
defaultSymbolType
,
legendSymbol
,
ecModel
),
'
visual
'
);
});
return
tasks
;
}
function
createTask
(
seriesModel
,
defaultSymbolType
,
legendSymbol
,
ecModel
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录