Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
missman
incubator-echarts
提交
dc929422
I
incubator-echarts
项目概览
missman
/
incubator-echarts
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
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,发现更多精彩内容 >>
提交
dc929422
编写于
12月 21, 2015
作者:
L
lang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Heat map on map
上级
9274a65c
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
287 addition
and
33 deletion
+287
-33
src/chart/heatmap/HeatmapLayer.js
src/chart/heatmap/HeatmapLayer.js
+133
-0
src/chart/heatmap/HeatmapSeries.js
src/chart/heatmap/HeatmapSeries.js
+1
-1
src/chart/heatmap/HeatmapView.js
src/chart/heatmap/HeatmapView.js
+131
-5
src/component/dataRange/visualCoding.js
src/component/dataRange/visualCoding.js
+0
-17
src/coord/View.js
src/coord/View.js
+7
-0
src/visual/VisualMapping.js
src/visual/VisualMapping.js
+15
-10
未找到文件。
src/chart/heatmap/HeatmapLayer.js
0 → 100644
浏览文件 @
dc929422
/**
* @file defines echarts Heatmap Chart
* @author Ovilia (me@zhangwenli.com)
* Inspired by https://github.com/mourner/simpleheat
*
* @module
*/
define
(
function
(
require
)
{
var
BRUSH_SIZE
=
20
;
var
GRADIENT_LEVELS
=
256
;
/**
* Heatmap Chart
*
* @class
*/
function
Heatmap
()
{
var
canvas
=
document
.
createElement
(
'
canvas
'
);
this
.
canvas
=
canvas
;
this
.
blurSize
=
30
;
this
.
opacity
=
1
;
this
.
_gradientPixels
=
{};
}
Heatmap
.
prototype
=
{
/**
* Renders Heatmap and returns the rendered canvas
* @param {Array} data array of data, each has x, y, value
* @param {number} width canvas width
* @param {number} height canvas height
*/
update
:
function
(
data
,
width
,
height
,
normalize
,
colorFunc
,
isInRange
)
{
var
brush
=
this
.
_getBrush
();
var
gradientInRange
=
this
.
_getGradient
(
data
,
colorFunc
,
'
inRange
'
);
var
gradientOutOfRange
=
this
.
_getGradient
(
data
,
colorFunc
,
'
outOfRange
'
);
var
r
=
BRUSH_SIZE
+
this
.
blurSize
;
var
canvas
=
this
.
canvas
;
var
ctx
=
canvas
.
getContext
(
'
2d
'
);
var
len
=
data
.
length
;
canvas
.
width
=
width
;
canvas
.
height
=
height
;
for
(
var
i
=
0
;
i
<
len
;
++
i
)
{
var
p
=
data
[
i
];
var
x
=
p
[
0
];
var
y
=
p
[
1
];
var
value
=
p
[
2
];
// calculate alpha using value
var
alpha
=
normalize
(
value
);
// draw with the circle brush with alpha
ctx
.
globalAlpha
=
alpha
;
ctx
.
drawImage
(
brush
,
x
-
r
,
y
-
r
);
}
// colorize the canvas using alpha value and set with gradient
var
imageData
=
ctx
.
getImageData
(
0
,
0
,
canvas
.
width
,
canvas
.
height
);
var
pixels
=
imageData
.
data
;
var
len
=
pixels
.
length
/
4
;
while
(
len
--
)
{
var
id
=
len
*
4
+
3
;
var
alpha
=
pixels
[
id
]
/
256
;
var
offset
=
Math
.
floor
(
alpha
*
(
GRADIENT_LEVELS
-
1
));
var
gradient
=
isInRange
(
alpha
)
?
gradientInRange
:
gradientOutOfRange
;
pixels
[
id
-
3
]
=
gradient
[
offset
*
4
];
pixels
[
id
-
2
]
=
gradient
[
offset
*
4
+
1
];
pixels
[
id
-
1
]
=
gradient
[
offset
*
4
+
2
];
pixels
[
id
]
*=
this
.
opacity
*
gradient
[
offset
*
4
+
3
];
}
ctx
.
putImageData
(
imageData
,
0
,
0
);
return
canvas
;
},
/**
* get canvas of a black circle brush used for canvas to draw later
* @private
* @returns {Object} circle brush canvas
*/
_getBrush
:
function
()
{
var
brushCanvas
=
this
.
_brushCanvas
||
(
this
.
_brushCanvas
=
document
.
createElement
(
'
canvas
'
));
// set brush size
var
r
=
BRUSH_SIZE
+
this
.
blurSize
;
var
d
=
r
*
2
;
brushCanvas
.
width
=
d
;
brushCanvas
.
height
=
d
;
var
ctx
=
brushCanvas
.
getContext
(
'
2d
'
);
ctx
.
clearRect
(
0
,
0
,
d
,
d
);
// in order to render shadow without the distinct circle,
// draw the distinct circle in an invisible place,
// and use shadowOffset to draw shadow in the center of the canvas
ctx
.
shadowOffsetX
=
d
;
ctx
.
shadowBlur
=
this
.
blurSize
;
// draw the shadow in black, and use alpha and shadow blur to generate
// color in color map
ctx
.
shadowColor
=
'
#000
'
;
// draw circle in the left to the canvas
ctx
.
beginPath
();
ctx
.
arc
(
-
r
,
r
,
BRUSH_SIZE
,
0
,
Math
.
PI
*
2
,
true
);
ctx
.
closePath
();
ctx
.
fill
();
return
brushCanvas
;
},
/**
* get gradient color map
* @private
*/
_getGradient
:
function
(
data
,
colorFunc
,
state
)
{
var
gradientPixels
=
this
.
_gradientPixels
;
var
pixelsSingleState
=
gradientPixels
[
state
]
||
(
gradientPixels
[
state
]
=
new
Uint8ClampedArray
(
256
*
4
));
var
color
=
[];
var
off
=
0
;
for
(
var
i
=
0
;
i
<
256
;
i
++
)
{
colorFunc
[
state
](
i
/
255
,
true
,
color
);
pixelsSingleState
[
off
++
]
=
color
[
0
];
pixelsSingleState
[
off
++
]
=
color
[
1
];
pixelsSingleState
[
off
++
]
=
color
[
2
];
pixelsSingleState
[
off
++
]
=
color
[
3
];
}
return
pixelsSingleState
;
}
};
return
Heatmap
;
});
src/chart/heatmap/HeatmapSeries.js
浏览文件 @
dc929422
...
...
@@ -28,7 +28,7 @@ define(function (require) {
// No blur
// Available when heatmap is on geo
blurSize
:
0
blurSize
:
2
0
}
});
});
\ No newline at end of file
src/chart/heatmap/HeatmapView.js
浏览文件 @
dc929422
define
(
function
(
require
)
{
var
graphic
=
require
(
'
../../util/graphic
'
);
var
HeatmapLayer
=
require
(
'
./HeatmapLayer
'
);
var
zrUtil
=
require
(
'
zrender/core/util
'
);
function
getIsInPiecewiseRange
(
dataExtent
,
pieceList
,
selected
)
{
var
dataSpan
=
dataExtent
[
1
]
-
dataExtent
[
0
];
pieceList
=
zrUtil
.
map
(
pieceList
,
function
(
piece
)
{
return
{
interval
:
[
(
piece
.
interval
[
0
]
-
dataExtent
[
0
])
/
dataSpan
,
(
piece
.
interval
[
1
]
-
dataExtent
[
0
])
/
dataSpan
]
};
});
var
len
=
pieceList
.
length
;
var
lastIndex
=
0
;
return
function
(
val
)
{
// Try to find in the location of the last found
for
(
var
i
=
lastIndex
;
i
<
len
;
i
++
)
{
var
interval
=
pieceList
[
i
].
interval
;
if
(
interval
[
0
]
<=
val
&&
val
<=
interval
[
1
])
{
lastIndex
=
i
;
break
;
}
}
if
(
i
===
len
)
{
// Not found, back interation
for
(
var
i
=
lastIndex
-
1
;
i
>=
0
;
i
--
)
{
var
interval
=
pieceList
[
i
].
interval
;
if
(
interval
[
0
]
<=
val
&&
val
<=
interval
[
1
])
{
lastIndex
=
i
;
break
;
}
}
}
return
i
>=
0
&&
i
<
len
&&
selected
[
i
];
};
}
function
getIsInContinuousRange
(
dataExtent
,
range
)
{
var
dataSpan
=
dataExtent
[
1
]
-
dataExtent
[
0
];
range
=
[
(
range
[
0
]
-
dataExtent
[
0
])
/
dataSpan
,
(
range
[
1
]
-
dataExtent
[
0
])
/
dataSpan
];
return
function
(
val
)
{
return
val
>=
range
[
0
]
&&
val
<=
range
[
1
];
};
}
return
require
(
'
../../echarts
'
).
extendChartView
({
type
:
'
heatmap
'
,
init
:
function
()
{
this
.
_hmLayer
=
new
HeatmapLayer
();
},
render
:
function
(
seriesModel
,
ecModel
,
api
)
{
var
dataRangeOfThisSeries
;
ecModel
.
eachComponent
(
'
dataRange
'
,
function
(
dataRange
)
{
dataRange
.
eachTargetSeries
(
function
(
targetSeries
)
{
if
(
targetSeries
===
seriesModel
)
{
dataRangeOfThisSeries
=
dataRange
;
}
});
});
if
(
!
dataRangeOfThisSeries
)
{
throw
new
Error
(
'
Heatmap must use with dataRange
'
);
}
this
.
group
.
removeAll
();
var
coordSys
=
seriesModel
.
coordinateSystem
;
if
(
coordSys
.
type
===
'
cartesian2d
'
)
{
this
.
_renderOnCartesian
(
coordSys
,
seriesModel
,
ecModel
,
api
);
this
.
_renderOnCartesian
(
coordSys
,
seriesModel
,
api
);
}
else
if
(
coordSys
.
type
===
'
geo
'
)
{
this
.
_renderOnGeo
(
coordSys
,
seriesModel
,
ecModel
,
api
);
this
.
_renderOnGeo
(
coordSys
,
seriesModel
,
dataRangeOfThisSeries
,
api
);
}
},
_renderOnCartesian
:
function
(
cartesian
,
seriesModel
,
ecModel
,
api
)
{
_renderOnCartesian
:
function
(
cartesian
,
seriesModel
,
api
)
{
var
xAxis
=
cartesian
.
getAxis
(
'
x
'
);
var
yAxis
=
cartesian
.
getAxis
(
'
y
'
);
var
group
=
this
.
group
;
group
.
removeAll
();
if
(
!
(
xAxis
.
type
===
'
category
'
&&
yAxis
.
type
===
'
category
'
))
{
throw
new
Error
(
'
Heatmap on cartesian must have two category axes
'
);
...
...
@@ -35,6 +101,10 @@ define(function (require) {
data
.
each
([
'
x
'
,
'
y
'
,
'
z
'
],
function
(
x
,
y
,
z
,
idx
)
{
var
itemModel
=
data
.
getItemModel
(
idx
);
var
point
=
cartesian
.
dataToPoint
([
x
,
y
]);
// Ignore empty data
if
(
isNaN
(
z
))
{
return
;
}
var
rect
=
new
graphic
.
Rect
({
shape
:
{
x
:
point
[
0
]
-
width
/
2
,
...
...
@@ -74,8 +144,64 @@ define(function (require) {
});
},
_renderOnGeo
:
function
(
geo
,
seriesModel
,
ecModel
,
api
)
{
_renderOnGeo
:
function
(
geo
,
seriesModel
,
dataRangeModel
,
api
)
{
var
inRangeVisuals
=
dataRangeModel
.
targetVisuals
.
inRange
;
var
outOfRangeVisuals
=
dataRangeModel
.
targetVisuals
.
outOfRange
;
// if (!visualMapping) {
// throw new Error('Data range must have color visuals');
// }
var
data
=
seriesModel
.
getData
();
var
hmLayer
=
this
.
_hmLayer
;
hmLayer
.
blurSize
=
seriesModel
.
get
(
'
blurSize
'
);
var
rect
=
geo
.
getViewRect
().
clone
();
var
roamTransform
=
geo
.
getRoamTransform
();
roamTransform
&&
rect
.
applyTransform
(
roamTransform
);
// Clamp on viewport
var
x
=
Math
.
max
(
rect
.
x
,
0
);
var
y
=
Math
.
max
(
rect
.
y
,
0
);
var
x2
=
Math
.
min
(
rect
.
width
+
rect
.
x
,
api
.
getWidth
());
var
y2
=
Math
.
min
(
rect
.
height
+
rect
.
y
,
api
.
getHeight
());
var
width
=
x2
-
x
;
var
height
=
y2
-
y
;
var
points
=
data
.
mapArray
([
'
lng
'
,
'
lat
'
,
'
value
'
],
function
(
lng
,
lat
,
value
)
{
var
pt
=
geo
.
dataToPoint
([
lng
,
lat
]);
pt
[
0
]
-=
x
;
pt
[
1
]
-=
y
;
pt
.
push
(
value
);
return
pt
;
});
var
dataExtent
=
dataRangeModel
.
getExtent
();
var
isInRange
=
dataRangeModel
.
type
===
'
dataRange.continuous
'
?
getIsInContinuousRange
(
dataExtent
,
dataRangeModel
.
option
.
range
)
:
getIsInPiecewiseRange
(
dataExtent
,
dataRangeModel
.
getPieceList
(),
dataRangeModel
.
option
.
selected
);
hmLayer
.
update
(
points
,
width
,
height
,
inRangeVisuals
.
color
.
getNormalizer
(),
{
inRange
:
inRangeVisuals
.
color
.
getColorMapper
(),
outOfRange
:
outOfRangeVisuals
.
color
.
getColorMapper
()
},
isInRange
);
var
img
=
new
graphic
.
Image
({
style
:
{
width
:
width
,
height
:
height
,
x
:
x
,
y
:
y
,
image
:
hmLayer
.
canvas
},
silent
:
true
});
this
.
group
.
add
(
img
);
}
});
});
\ No newline at end of file
src/component/dataRange/visualCoding.js
浏览文件 @
dc929422
...
...
@@ -16,26 +16,11 @@ define(function (require) {
function
processSingleDataRange
(
dataRangeModel
,
ecModel
)
{
var
visualMappings
=
dataRangeModel
.
targetVisuals
;
var
visualTypesMap
=
{};
var
colorFuncsMap
=
{};
zrUtil
.
each
([
'
inRange
'
,
'
outOfRange
'
],
function
(
state
)
{
var
visualTypes
=
VisualMapping
.
prepareVisualTypes
(
visualMappings
[
state
]);
var
colorFunc
=
zrUtil
.
filter
(
zrUtil
.
map
(
visualTypes
,
function
(
visualType
)
{
return
visualMappings
[
state
][
visualType
].
getColorMapper
;
}),
function
(
func
)
{
return
!!
func
;
})[
0
];
visualTypesMap
[
state
]
=
visualTypes
;
colorFuncsMap
[
state
]
=
colorFunc
;
});
// Cache color func
function
colorFunc
(
value
,
out
)
{
var
valueState
=
dataRangeModel
.
getValueState
(
value
);
var
colorFunc
=
colorFuncsMap
[
valueState
];
// PENDING
return
colorFunc
&&
colorFunc
(
value
,
out
);
}
dataRangeModel
.
eachTargetSeries
(
function
(
seriesModel
)
{
var
data
=
seriesModel
.
getData
();
var
dimension
=
dataRangeModel
.
getDataDimension
(
data
);
...
...
@@ -49,8 +34,6 @@ define(function (require) {
data
.
setItemVisual
(
dataIndex
,
key
,
value
);
}
data
.
setVisual
(
'
colorFunc
'
,
colorFunc
);
data
.
each
([
dimension
],
function
(
value
,
index
)
{
// For performance consideration, do not use curry.
dataIndex
=
index
;
...
...
src/coord/View.js
浏览文件 @
dc929422
...
...
@@ -118,6 +118,13 @@ define(function (require) {
this
.
_updateTransform
();
},
/**
* @return {Array.<number}
*/
getRoamTransform
:
function
()
{
return
this
.
_roamTransform
.
transform
;
},
/**
* Update transform from roam and mapLocation
* @private
...
...
src/visual/VisualMapping.js
浏览文件 @
dc929422
...
...
@@ -87,7 +87,11 @@ define(function (require) {
isValueActive
:
null
,
mapValueToVisual
:
null
mapValueToVisual
:
null
,
getNormalizer
:
function
()
{
return
zrUtil
.
bind
(
this
.
_normalizeData
,
this
);
}
};
var
visualHandlers
=
VisualMapping
.
visualHandlers
=
{
...
...
@@ -103,20 +107,21 @@ define(function (require) {
getColorMapper
:
function
()
{
var
visual
=
isCategory
(
this
)
?
this
.
option
.
visual
:
zrUtil
.
map
(
this
.
option
.
visual
,
zrUtil
.
parse
);
return
isCategory
(
this
)
?
function
(
value
)
{
return
getVisualForCategory
(
this
,
visual
,
this
.
_normalizeData
(
value
));
:
zrUtil
.
map
(
this
.
option
.
visual
,
zrColor
.
parse
);
return
zrUtil
.
bind
(
isCategory
(
this
)
?
function
(
value
,
isNormalized
)
{
!
isNormalized
&&
(
value
=
this
.
_normalizeData
(
value
));
return
getVisualForCategory
(
this
,
visual
,
value
);
}
:
function
(
value
,
out
)
{
:
function
(
value
,
isNormalized
,
out
)
{
// If output rgb array
// which will be much faster and useful in pixel manipulation
var
returnRGBArray
=
!!
out
;
out
=
zrColor
.
fastMapToColor
(
this
.
_normalizeData
(
value
),
visual
,
out
);
!
isNormalized
&&
(
value
=
this
.
_normalizeData
(
value
));
out
=
zrColor
.
fastMapToColor
(
value
,
visual
,
out
);
return
returnRGBArray
?
out
:
zrUtil
.
stringify
(
out
,
'
rgba
'
);
};
}
,
this
)
;
},
// value:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录