Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
alon@wen
echarts
提交
de539a6b
E
echarts
项目概览
alon@wen
/
echarts
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
echarts
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
de539a6b
编写于
9月 13, 2015
作者:
L
lang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Optimize list for large data
上级
2a3b7d46
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
432 addition
and
18 deletion
+432
-18
src/data/LargeList.js
src/data/LargeList.js
+343
-0
src/processor/seriesStack.js
src/processor/seriesStack.js
+0
-18
test/ut/spec/data/List.js
test/ut/spec/data/List.js
+89
-0
未找到文件。
src/data/LargeList.js
0 → 100644
浏览文件 @
de539a6b
/**
* List for data storage
*/
define
(
function
(
require
)
{
var
UNDEFINED
=
'
undefined
'
;
var
global
=
window
;
var
Float32Array
=
typeof
global
.
Float32Array
===
UNDEFINED
?
Array
:
global
.
Float32Array
;
var
Int32Array
=
typeof
global
.
Int32Array
===
UNDEFINED
?
Array
:
global
.
Int32Array
;
var
Model
=
require
(
'
../model/Model
'
);
var
List
=
function
(
dimensions
,
seriesModel
)
{
/**
* @readOnly
* @type {Array.<string>}
*/
this
.
dimensions
=
dimensions
||
[
'
x
'
,
'
y
'
];
/**
* @type {module:echarts/model/Model}
*/
this
.
seriesModel
=
seriesModel
;
/**
* Data storage
* @type {Object.<key, Array.<number>>}
* @private
*/
this
.
_storage
=
{};
/**
* Indices stores the indices of data subset after filtered.
* This data subset will be used by chart.
* @type {Array.<number>}
* @private
*/
this
.
_indices
=
[];
/**
* Models of data option is stored sparse for optimizing memory cost
* @type {Array.<module:echarts/model/Model>}
* @private
*/
this
.
_optionModels
=
[];
/**
* @param {module:echarts/data/List}
*/
this
.
stackedOn
=
null
;
}
var
listProto
=
List
.
prototype
;
/**
* Initialize from data
*/
listProto
.
initData
=
function
(
data
)
{
// Clear
var
optionModels
=
this
.
_optionModels
=
[];
var
storage
=
this
.
_storage
=
{};
var
indices
=
this
.
_indices
=
[];
var
dimensions
=
this
.
dimensions
;
var
size
=
data
.
length
;
// Init storage
for
(
var
i
=
0
;
i
<
dimensions
.
length
;
i
++
)
{
storage
[
dimensions
[
i
]]
=
new
Float32Array
(
size
);
}
storage
[
this
.
value
]
=
new
Float32Array
(
size
);
// Special storage of indices of option model
// It is used for indexing the model in List#_optionModels
var
optionModelIndices
=
storage
.
$optionModelIndices
=
new
Int32Array
(
size
);
var
tempValue
=
[];
for
(
var
idx
=
0
;
idx
<
data
.
length
;
idx
++
)
{
var
value
=
data
[
idx
];
// Each data item contains value and option
if
(
data
[
idx
]
!=
null
&&
data
[
idx
].
hasOwnProperty
(
'
value
'
))
{
value
=
data
[
idx
].
value
;
var
model
=
new
Model
(
data
[
idx
],
this
.
seriesModel
);
var
modelIdx
=
optionModels
.
length
;
optionModelIndices
[
idx
]
=
modelIdx
;
optionModels
.
push
(
model
);
}
// Bar chart, line chart which uses category axis
// only gives the 'y' value. 'x' value is the indices of cateogry
if
(
typeof
(
value
)
===
'
number
'
)
{
// Use a tempValue to normalize the value to be a (x, y) value
tempValue
[
0
]
=
idx
;
tempValue
[
1
]
=
value
;
value
=
tempValue
;
}
// Store the data by dimensions
for
(
var
k
=
0
;
k
<
dimensions
.
length
;
k
++
)
{
var
dim
=
dimensions
[
k
];
var
dimStorage
=
storage
[
dim
];
var
dimValue
=
value
[
k
];
// PENDING NULL is empty or zero
if
(
dimValue
==
null
||
dimValue
===
'
-
'
)
{
dimValue
=
NaN
;
}
dimStorage
[
idx
]
=
dimValue
;
}
indices
.
push
(
idx
);
}
};
/**
* @return {number}
*/
listProto
.
count
=
function
()
{
return
this
.
_indices
.
length
;
};
/**
* Get value
*/
listProto
.
get
=
function
(
dim
,
idx
,
stack
)
{
var
storage
=
this
.
_storage
;
var
dataIndex
=
this
.
_indices
[
idx
];
var
value
=
storage
[
dim
]
&&
storage
[
dim
][
dataIndex
];
if
(
stack
&&
this
.
stackedOn
)
{
var
stackedValue
=
this
.
stackedOn
.
get
(
dim
,
idx
,
stack
);
// Ignore the empty data
if
(
!
isNaN
(
stackedValue
))
{
if
(
value
>=
0
&&
stackedValue
>
0
// Positive stack
||
(
value
<=
0
&&
stackedValue
<
0
)
// Negative stack
)
{
value
+=
stackedValue
;
}
}
}
return
value
;
};
/**
* Get raw data index
*/
listProto
.
getDataIndex
=
function
(
idx
)
{
return
this
.
_indices
[
idx
];
};
function
normalizeDimensions
(
dimensions
)
{
if
(
typeof
(
dimensions
)
===
'
number
'
)
{
dimensions
=
[
dimensions
];
}
return
dimensions
;
}
/**
* Data iteration
* @param {string|Array.<string>}
* @param {Function} cb
* @param {boolean} [stack=false]
* @param {*} [context=this]
*
* @example
* list.each('x', function (x) {});
* list.each(['x', 'y'], function (x, y) {});
*/
listProto
.
each
=
function
(
dimensions
,
cb
,
stack
,
context
)
{
dimensions
=
normalizeDimensions
(
dimensions
);
var
value
=
[];
var
dimSize
=
dimensions
.
length
;
var
indices
=
this
.
_indices
;
context
=
context
||
this
;
for
(
var
i
=
0
;
i
<
indices
.
length
;
i
++
)
{
// Simple optimization
if
(
dimSize
===
1
)
{
cb
&&
cb
.
call
(
context
,
this
.
get
(
dimensions
[
0
],
i
,
stack
));
}
else
{
for
(
var
k
=
0
;
k
<
dimSize
;
k
++
)
{
value
[
k
]
=
this
.
get
(
dimensions
[
k
],
i
,
stack
);
}
cb
.
apply
(
context
,
value
);
}
}
};
/**
* Data filter
* @param {string|Array.<string>}
* @param {Function} cb
* @param {boolean} [stack=false]
* @param {*} [context=this]
*/
listProto
.
filterSelf
=
function
(
dimensions
,
cb
,
stack
,
context
)
{
dimensions
=
normalizeDimensions
(
dimensions
);
var
newIndices
=
[];
var
value
=
[];
var
dimSize
=
dimensions
.
length
;
var
indices
=
this
.
_indices
;
context
=
context
||
this
;
for
(
var
i
=
0
;
i
<
indices
.
length
;
i
++
)
{
var
keep
;
// Simple optimization
if
(
dimSize
===
1
)
{
keep
=
cb
&&
cb
.
call
(
context
,
this
.
get
(
dimensions
[
0
],
i
,
stack
));
}
else
{
for
(
var
k
=
0
;
k
<
dimSize
;
k
++
)
{
value
[
k
]
=
this
.
get
(
dimensions
[
k
],
i
,
stack
);
}
keep
=
cb
.
apply
(
context
,
value
);
}
if
(
keep
)
{
newIndices
.
push
(
indices
[
i
]);
}
}
this
.
_indices
=
newIndices
;
return
this
;
};
/**
* Data mapping
* @param {string|Array.<string>}
* @param {Function} cb
* @param {boolean} [stack=false]
* @param {*} [context=this]
*/
listProto
.
map
=
function
(
dimensions
,
cb
,
stack
,
context
)
{
var
result
=
[];
this
.
each
(
dimensions
,
function
()
{
result
.
push
(
cb
&&
cb
.
apply
(
this
,
arguments
));
},
stack
,
context
);
return
result
;
};
/**
* Get model of one data item
*/
listProto
.
getDataModel
=
function
(
idx
)
{
var
storage
=
this
.
_storage
;
var
optionModelIndices
=
storage
.
$optionModelIndices
;
var
modelIndex
=
optionModelIndices
&&
optionModelIndices
[
idx
];
return
this
.
_optionModels
[
modelIndex
];
};
/**
* Shallow clone a new list.
* New list only change the _indices.
*/
listProto
.
cloneShallow
=
function
()
{
var
list
=
new
List
(
this
.
dimensions
,
this
.
seriesModel
);
list
.
stackedOn
=
this
.
stackedOn
;
list
.
_storage
=
this
.
_storage
;
list
.
_indices
=
this
.
_indices
.
slice
();
list
.
_optionModels
=
this
.
_optionModels
;
return
list
;
};
/**
* Helper function to create a list from option data
*/
List
.
fromArray
=
function
(
data
,
seriesModel
,
ecModel
)
{
var
coordinateSystem
=
seriesModel
.
get
(
'
coordinateSystem
'
);
var
dimensions
;
var
categoryAxisModel
;
// FIXME
// 这里 List 跟几个坐标系和坐标系 Model 耦合了
if
(
coordinateSystem
===
'
cartesian2d
'
)
{
var
xAxisModel
=
ecModel
.
getComponent
(
'
xAxis
'
,
seriesModel
.
get
(
'
xAxisIndex
'
));
var
yAxisModel
=
ecModel
.
getComponent
(
'
yAxis
'
,
seriesModel
.
get
(
'
yAxisIndex
'
));
if
(
xAxisModel
.
get
(
'
type
'
)
===
'
category
'
)
{
dimensions
=
[
'
x
'
,
'
y
'
];
categoryAxisModel
=
xAxisModel
;
}
else
if
(
yAxisModel
.
get
(
'
type
'
)
===
'
category
'
)
{
dimensions
=
[
'
y
'
,
'
x
'
];
categoryAxisModel
=
yAxisModel
;
}
else
{
// PENDING
var
dimSize
=
data
[
0
]
&&
data
[
0
].
length
;
if
(
dimSize
===
2
)
{
dimensions
=
[
'
x
'
,
'
y
'
];
}
else
if
(
dimSize
===
3
)
{
dimensions
=
[
'
x
'
,
'
y
'
,
'
z
'
];
}
}
}
else
if
(
coordinateSystem
===
'
polar
'
)
{
var
axisFinder
=
function
(
axisModel
)
{
return
axisModel
.
get
(
'
polarIndex
'
)
===
polarIndex
;
}
var
polarIndex
=
seriesModel
.
get
(
'
polarIndex
'
)
||
0
;
var
angleAxisModel
=
ecModel
.
findComponent
(
'
angleAxis
'
,
axisFinder
);
var
radiusAxisModel
=
ecModel
.
findComponent
(
'
radiusAxis
'
,
axisFinder
);
if
(
angleAxisModel
.
get
(
'
type
'
)
===
'
category
'
)
{
dimensions
=
[
'
angle
'
,
'
radius
'
];
categoryAxisModel
=
angleAxisModel
;
}
else
if
(
radiusAxisModel
.
get
(
'
type
'
)
===
'
category
'
)
{
dimensions
=
[
'
radius
'
,
'
angle
'
];
categoryAxisModel
=
radiusAxisModel
;
}
else
{
// PENDING
var
dimSize
=
data
[
0
]
&&
data
[
0
].
length
;
if
(
dimSize
===
2
)
{
dimensions
=
[
'
radius
'
,
'
angle
'
];
}
else
if
(
dimSize
===
3
)
{
dimensions
=
[
'
radius
'
,
'
angle
'
,
'
value
'
];
}
}
}
var
list
=
new
List
(
dimensions
,
seriesModel
);
list
.
initData
(
data
);
};
return
List
;
});
\ No newline at end of file
src/processor/seriesStack.js
已删除
100644 → 0
浏览文件 @
2a3b7d46
define
(
function
()
{
'
use strict
'
;
return
function
(
option
)
{
var
stackedMap
=
{};
option
.
eachSeries
(
function
(
series
)
{
var
data
=
series
.
getData
();
var
stack
=
series
.
get
(
'
stack
'
);
if
(
stack
&&
data
.
type
===
'
list
'
)
{
data
.
eachY
(
function
(
y
,
idx
)
{
stackedMap
[
idx
]
=
stackedMap
[
idx
]
||
0
;
stackedMap
[
idx
]
+=
y
;
});
}
});
};
});
\ No newline at end of file
test/ut/spec/data/List.js
0 → 100644
浏览文件 @
de539a6b
describe
(
'
List
'
,
function
()
{
var
utHelper
=
window
.
utHelper
;
beforeEach
(
function
(
done
)
{
utHelper
.
resetPackageLoader
(
done
);
});
describe
(
'
Data Manipulation
'
,
function
()
{
function
testCase
(
name
,
doTest
)
{
it
(
name
,
function
(
done
)
{
window
.
require
([
'
echarts/data/LargeList
'
],
function
()
{
doTest
.
apply
(
null
,
arguments
);
done
();
});
});
}
testCase
(
'
initData 1d
'
,
function
(
List
)
{
var
list
=
new
List
([
'
x
'
,
'
y
'
]);
list
.
initData
([
10
,
20
,
30
]);
expect
(
list
.
get
(
'
x
'
,
0
)).
toEqual
(
0
);
expect
(
list
.
get
(
'
x
'
,
1
)).
toEqual
(
1
);
expect
(
list
.
get
(
'
x
'
,
2
)).
toEqual
(
2
);
expect
(
list
.
get
(
'
y
'
,
1
)).
toEqual
(
20
);
});
testCase
(
'
initData 2d
'
,
function
(
List
)
{
var
list
=
new
List
([
'
x
'
,
'
y
'
]);
list
.
initData
([[
10
,
15
],
[
20
,
25
],
[
30
,
35
]]);
expect
(
list
.
get
(
'
x
'
,
1
)).
toEqual
(
20
);
expect
(
list
.
get
(
'
y
'
,
1
)).
toEqual
(
25
);
});
testCase
(
'
initData 2d yx
'
,
function
(
List
)
{
var
list
=
new
List
([
'
y
'
,
'
x
'
]);
list
.
initData
([[
10
,
15
],
[
20
,
25
],
[
30
,
35
]]);
expect
(
list
.
get
(
'
x
'
,
1
)).
toEqual
(
25
);
expect
(
list
.
get
(
'
y
'
,
1
)).
toEqual
(
20
);
});
testCase
(
'
Data with option 1d
'
,
function
(
List
)
{
var
list
=
new
List
([
'
x
'
,
'
y
'
]);
list
.
initData
([
1
,
{
value
:
2
,
somProp
:
'
foo
'
}]);
expect
(
list
.
getDataModel
(
1
).
get
(
'
somProp
'
)).
toEqual
(
'
foo
'
);
});
testCase
(
'
Empty data
'
,
function
(
List
)
{
var
list
=
new
List
([
'
x
'
,
'
y
'
]);
list
.
initData
([
1
,
'
-
'
]);
expect
(
list
.
get
(
'
y
'
,
1
)).
toBeNaN
();
});
testCase
(
'
Stacked data
'
,
function
(
List
)
{
var
list1
=
new
List
([
'
x
'
,
'
y
'
]);
var
list2
=
new
List
([
'
x
'
,
'
y
'
]);
list1
.
initData
([
1
,
'
-
'
,
2
,
-
2
]);
list2
.
initData
([
1
,
2
,
3
,
2
]);
list2
.
stackedOn
=
list1
;
expect
(
list2
.
get
(
'
y
'
,
1
,
true
)).
toEqual
(
2
);
expect
(
list2
.
get
(
'
y
'
,
2
,
true
)).
toEqual
(
5
);
expect
(
list2
.
get
(
'
y
'
,
3
,
true
)).
toEqual
(
2
);
});
testCase
(
'
map
'
,
function
(
List
)
{
var
list
=
new
List
([
'
x
'
,
'
y
'
]);
list
.
initData
([[
10
,
15
],
[
20
,
25
],
[
30
,
35
]]);
expect
(
list
.
map
([
'
x
'
,
'
y
'
],
function
(
x
,
y
)
{
return
[
x
,
y
];
})).
toEqual
([[
10
,
15
],
[
20
,
25
],
[
30
,
35
]]);
});
testCase
(
'
filterSelf
'
,
function
(
List
)
{
var
list
=
new
List
([
'
x
'
,
'
y
'
]);
list
.
initData
([[
10
,
15
],
[
20
,
25
],
[
30
,
35
]]);
expect
(
list
.
filterSelf
([
'
x
'
,
'
y
'
],
function
(
x
,
y
)
{
return
x
<
30
&&
x
>
10
;
}).
map
(
'
x
'
,
function
(
x
)
{
return
x
;
})).
toEqual
([
20
]);
});
});
});
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录