提交 254db8de 编写于 作者: L lang

Geo add regions property, can be selectable, has click event. #2362

上级 a89fd0d7
......@@ -63,25 +63,6 @@ define(function (require) {
}
}
// function lineAfterUpdate() {
// Ignore scale
// var m = this.transform;
// if (m) {
// var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
// var sy = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
// m[0] /= sx;
// m[1] /= sx;
// m[2] /= sy;
// m[3] /= sy;
// matrix.invert(this.invTransform, m);
// }
// }
// function isSymbolArrow(symbol) {
// return symbol.type === 'symbol' && symbol.shape.symbolType === 'arrow';
// }
function updateSymbolAndLabelBeforeLineUpdate () {
var lineGroup = this;
var symbolFrom = lineGroup.childOfName('fromSymbol');
......
define(function (require) {
var List = require('../../data/List');
var echarts = require('../../echarts');
var SeriesModel = require('../../model/Series');
var zrUtil = require('zrender/core/util');
var completeDimensions = require('../../data/helper/completeDimensions');
......@@ -10,26 +9,9 @@ define(function (require) {
var encodeHTML = formatUtil.encodeHTML;
var addCommas = formatUtil.addCommas;
var dataSelectableMixin = require('../helper/dataSelectableMixin');
var dataSelectableMixin = require('../../component/helper/selectableMixin');
function fillData(dataOpt, geoJson) {
var dataNameMap = {};
var features = geoJson.features;
for (var i = 0; i < dataOpt.length; i++) {
dataNameMap[dataOpt[i].name] = dataOpt[i];
}
for (var i = 0; i < features.length; i++) {
var name = features[i].properties.name;
if (!dataNameMap[name]) {
dataOpt.push({
value: NaN,
name: name
});
}
}
return dataOpt;
}
var geoCreator = require('../../coord/geo/geoCreator');
var MapSeries = SeriesModel.extend({
......@@ -54,7 +36,7 @@ define(function (require) {
MapSeries.superApply(this, 'init', arguments);
this.updateSelectedMap();
this.updateSelectedMap(option.data);
},
getInitialData: function (option) {
......@@ -74,16 +56,14 @@ define(function (require) {
MapSeries.superCall(this, 'mergeOption', newOption);
this.updateSelectedMap();
this.updateSelectedMap(this.option.data);
},
_fillOption: function (option, mapName) {
// Shallow clone
option = zrUtil.extend({}, option);
var map = echarts.getMap(mapName);
var geoJson = map && map.geoJson;
geoJson && (option.data = fillData((option.data || []), geoJson));
option.data = geoCreator.getFilledRegions(option.data, mapName);
return option;
},
......@@ -94,6 +74,16 @@ define(function (require) {
return this._data.get('value', dataIndex);
},
/**
* Get model of region
* @param {string} name
* @return {module:echarts/model/Model}
*/
getRegionModel: function (regionName) {
var data = this.getData();
return data.getItemModel(data.indexOfName(regionName));
},
/**
* Map tooltip formatter
*
......
......@@ -7,7 +7,7 @@ define(function(require) {
var modelUtil = require('../../util/model');
var completeDimensions = require('../../data/helper/completeDimensions');
var dataSelectableMixin = require('../helper/dataSelectableMixin');
var dataSelectableMixin = require('../../component/helper/selectableMixin');
var PieSeries = require('../../echarts').extendSeriesModel({
......@@ -23,7 +23,7 @@ define(function(require) {
return this._dataBeforeProcessed;
};
this.updateSelectedMap();
this.updateSelectedMap(option.data);
this._defaultLabelLine(option);
},
......@@ -31,7 +31,7 @@ define(function(require) {
// Overwrite
mergeOption: function (newOption) {
PieSeries.superCall(this, 'mergeOption', newOption);
this.updateSelectedMap();
this.updateSelectedMap(this.option.data);
},
getInitialData: function (option, ecModel) {
......
define(function (require) {
require('../coord/geo/GeoModel');
require('../coord/geo/geoCreator');
require('./geo/GeoView');
require('../action/geoRoam');
var echarts = require('../echarts');
var zrUtil = require('zrender/core/util');
function makeAction(method, actionInfo) {
actionInfo.update = 'updateView';
echarts.registerAction(actionInfo, function (payload, ecModel) {
var selected = {};
ecModel.eachComponent(
{ mainType: 'geo', query: payload},
function (geoModel) {
geoModel[method](payload.name);
var geo = geoModel.coordinateSystem;
zrUtil.each(geo.regions, function (region) {
selected[region.name] = geoModel.isSelected(region.name) || false;
});
}
);
return {
selected: selected,
name: payload.name
}
});
}
makeAction('toggleSelected', {
type: 'geoToggleSelect',
event: 'geoselectchanged'
});
makeAction('select', {
type: 'geoSelect',
event: 'geoselected'
});
makeAction('unSelect', {
type: 'geoUnSelect',
event: 'geounselected'
});
});
\ No newline at end of file
......@@ -16,8 +16,20 @@ define(function (require) {
},
render: function (geoModel, ecModel, api, payload) {
geoModel.get('show') &&
this._mapDraw.draw(geoModel, ecModel, api, this, payload);
// Not render if it is an toggleSelect action from self
if (payload && payload.type === 'geoToggleSelect'
&& payload.from === this.uid
) {
return;
}
var mapDraw = this._mapDraw;
if (geoModel.get('show')) {
mapDraw.draw(geoModel, ecModel, api, this, payload);
}
else {
this._mapDraw.group.removeAll();
}
}
});
});
\ No newline at end of file
......@@ -17,30 +17,38 @@ define(function (require) {
return itemStyle;
}
function updateMapSelectHandler(mapOrGeoModel, data, group, api, fromView) {
function updateMapSelectHandler(mapOrGeoModel, group, api, fromView) {
group.off('click');
mapOrGeoModel.get('selectedMode')
&& group.on('click', function (e) {
var dataIndex = e.target.dataIndex;
if (dataIndex != null) {
var name = data.getName(dataIndex);
api.dispatchAction({
type: 'mapToggleSelect',
seriesId: mapOrGeoModel.id,
name: name,
from: fromView.uid
});
updateMapSelected(mapOrGeoModel, data, api);
var el = e.target;
while (!el.__region) {
el = el.parent;
}
if (!el) {
return;
}
var region = el.__region;
var action = {
type: (mapOrGeoModel.mainType === 'geo' ? 'geo' : 'map') + 'ToggleSelect',
name: region.name,
from: fromView.uid
};
action[mapOrGeoModel.mainType + 'Id'] = mapOrGeoModel.id;
api.dispatchAction(action);
updateMapSelected(mapOrGeoModel, group);
});
}
function updateMapSelected(mapOrGeoModel, data) {
data.eachItemGraphicEl(function (el, idx) {
var name = data.getName(idx);
el.trigger(mapOrGeoModel.isSelected(name) ? 'emphasis' : 'normal');
function updateMapSelected(mapOrGeoModel, group) {
// FIXME
group.eachChild(function (otherRegionEl) {
if (otherRegionEl.__region) {
otherRegionEl.trigger(mapOrGeoModel.isSelected(otherRegionEl.__region.name) ? 'emphasis' : 'normal');
}
});
}
......@@ -103,28 +111,10 @@ define(function (require) {
group.removeAll();
var itemStyleModel;
var hoverItemStyleModel;
var itemStyle;
var hoverItemStyle;
var labelModel;
var hoverLabelModel;
var itemStyleAccessPath = ['itemStyle', 'normal'];
var hoverItemStyleAccessPath = ['itemStyle', 'emphasis'];
var labelAccessPath = ['label', 'normal'];
var hoverLabelAccessPath = ['label', 'emphasis'];
if (!data) {
itemStyleModel = mapOrGeoModel.getModel(itemStyleAccessPath);
hoverItemStyleModel = mapOrGeoModel.getModel(hoverItemStyleAccessPath);
itemStyle = getFixedItemStyle(itemStyleModel, scale);
hoverItemStyle = getFixedItemStyle(hoverItemStyleModel, scale);
labelModel = mapOrGeoModel.getModel(labelAccessPath);
hoverLabelModel = mapOrGeoModel.getModel(hoverLabelAccessPath);
}
zrUtil.each(geo.regions, function (region) {
......@@ -135,32 +125,31 @@ define(function (require) {
}
});
regionGroup.add(compoundPath);
var regionModel = mapOrGeoModel.getRegionModel(region.name) || mapOrGeoModel;
var itemStyleModel = regionModel.getModel(itemStyleAccessPath);
var hoverItemStyleModel = regionModel.getModel(hoverItemStyleAccessPath);
var itemStyle = getFixedItemStyle(itemStyleModel, scale);
var hoverItemStyle = getFixedItemStyle(hoverItemStyleModel, scale);
var labelModel = regionModel.getModel(labelAccessPath);
var hoverLabelModel = regionModel.getModel(hoverLabelAccessPath);
var dataIdx;
// Use the itemStyle in data if has data
if (data) {
// FIXME If dataIdx < 0
dataIdx = data.indexOfName(region.name);
var itemModel = data.getItemModel(dataIdx);
// Only visual color of each item will be used. It can be encoded by dataRange
// But visual color of series is used in symbol drawing
//
// Visual color for each series is for the symbol draw
var visualColor = data.getItemVisual(dataIdx, 'color', true);
itemStyleModel = itemModel.getModel(itemStyleAccessPath);
hoverItemStyleModel = itemModel.getModel(hoverItemStyleAccessPath);
itemStyle = getFixedItemStyle(itemStyleModel, scale);
hoverItemStyle = getFixedItemStyle(hoverItemStyleModel, scale);
labelModel = itemModel.getModel(labelAccessPath);
hoverLabelModel = itemModel.getModel(hoverLabelAccessPath);
if (visualColor) {
itemStyle.fill = visualColor;
}
}
var textStyleModel = labelModel.getModel('textStyle');
var hoverTextStyleModel = hoverLabelModel.getModel('textStyle');
......@@ -219,7 +208,21 @@ define(function (require) {
// setItemGraphicEl, setHoverStyle after all polygons and labels
// are added to the rigionGroup
data && data.setItemGraphicEl(dataIdx, regionGroup);
if (data) {
data.setItemGraphicEl(dataIdx, regionGroup);
}
else {
var regionModel = mapOrGeoModel.getRegionModel(region.name);
// Package custom mouse event for geo component
compoundPath.eventData = {
componentType: 'geo',
geoIndex: mapOrGeoModel.componentIndex,
name: region.name,
region: (regionModel && regionModel.option) || {}
};
}
regionGroup.__region = region;
graphic.setHoverStyle(regionGroup, hoverItemStyle);
......@@ -228,9 +231,9 @@ define(function (require) {
this._updateController(mapOrGeoModel, ecModel, api);
data && updateMapSelectHandler(mapOrGeoModel, data, group, api, fromView);
updateMapSelectHandler(mapOrGeoModel, group, api, fromView);
data && updateMapSelected(mapOrGeoModel, data);
updateMapSelected(mapOrGeoModel, group);
},
remove: function () {
......
......@@ -11,11 +11,10 @@ define(function (require) {
return {
updateSelectedMap: function () {
var option = this.option;
this._dataOptMap = zrUtil.reduce(option.data, function (dataOptMap, dataOpt) {
dataOptMap[dataOpt.name] = dataOpt;
return dataOptMap;
updateSelectedMap: function (targetList) {
this._selectTargetMap = zrUtil.reduce(targetList || [], function (targetMap, target) {
targetMap[target.name] = target;
return targetMap;
}, {});
},
/**
......@@ -23,35 +22,35 @@ define(function (require) {
*/
// PENGING If selectedMode is null ?
select: function (name) {
var dataOptMap = this._dataOptMap;
var dataOpt = dataOptMap[name];
var targetMap = this._selectTargetMap;
var target = targetMap[name];
var selectedMode = this.get('selectedMode');
if (selectedMode === 'single') {
zrUtil.each(dataOptMap, function (dataOpt) {
dataOpt.selected = false;
zrUtil.each(targetMap, function (target) {
target.selected = false;
});
}
dataOpt && (dataOpt.selected = true);
target && (target.selected = true);
},
/**
* @param {string} name
*/
unSelect: function (name) {
var dataOpt = this._dataOptMap[name];
var target = this._selectTargetMap[name];
// var selectedMode = this.get('selectedMode');
// selectedMode !== 'single' && dataOpt && (dataOpt.selected = false);
dataOpt && (dataOpt.selected = false);
// selectedMode !== 'single' && target && (target.selected = false);
target && (target.selected = false);
},
/**
* @param {string} name
*/
toggleSelected: function (name) {
var dataOpt = this._dataOptMap[name];
if (dataOpt != null) {
this[dataOpt.selected ? 'unSelect' : 'select'](name);
return dataOpt.selected;
var target = this._selectTargetMap[name];
if (target != null) {
this[target.selected ? 'unSelect' : 'select'](name);
return target.selected;
}
},
......@@ -59,8 +58,8 @@ define(function (require) {
* @param {string} name
*/
isSelected: function (name) {
var dataOpt = this._dataOptMap[name];
return dataOpt && dataOpt.selected;
var target = this._selectTargetMap[name];
return target && target.selected;
}
};
});
\ No newline at end of file
......@@ -3,8 +3,14 @@ define(function (require) {
'use strict';
var modelUtil = require('../../util/model');
var ComponentModel = require('../../model/Component');
var Model = require('../../model/Model');
var zrUtil = require('zrender/core/util');
ComponentModel.extend({
var selectableMixin = require('../../component/helper/selectableMixin');
var geoCreator = require('./geoCreator');
var GeoModel = ComponentModel.extend({
type: 'geo',
......@@ -22,6 +28,22 @@ define(function (require) {
);
},
optionUpdated: function () {
var option = this.option;
var self = this;
option.regions = geoCreator.getFilledRegions(option.regions, option.map);
this._optionModelMap = zrUtil.reduce(option.regions || [], function (obj, regionOpt) {
if (regionOpt.name) {
obj[regionOpt.name] = new Model(regionOpt, self);
}
return obj;
}, {});
this.updateSelectedMap(option.regions);
},
defaultOption: {
zlevel: 0,
......@@ -50,6 +72,8 @@ define(function (require) {
scaleLimit: null,
// selectedMode: false
label: {
normal: {
show: false,
......@@ -75,7 +99,18 @@ define(function (require) {
emphasis: { // 也是选中样式
color: 'rgba(255,215,0,0.8)'
}
}
},
regions: []
},
/**
* Get model of region
* @param {string} name
* @return {module:echarts/model/Model}
*/
getRegionModel: function (name) {
return this._optionModelMap[name];
},
/**
......@@ -106,4 +141,8 @@ define(function (require) {
this.option.center = center;
}
});
zrUtil.mixin(GeoModel, selectableMixin);
return GeoModel;
});
\ No newline at end of file
define(function (require) {
require('./GeoModel');
var Geo = require('./Geo');
var layout = require('../../util/layout');
......@@ -170,6 +168,36 @@ define(function (require) {
*/
getMap: function (mapName) {
return mapDataStores[mapName];
},
/**
* Fill given regions array
* @param {Array.<Object>} originRegionArr
* @param {string} mapName
* @return {Array}
*/
getFilledRegions: function (originRegionArr, mapName) {
// Not use the original
var regionsArr = (originRegionArr || []).slice();
var map = geoCreator.getMap(mapName);
var geoJson = map && map.geoJson;
var dataNameMap = {};
var features = geoJson.features;
for (var i = 0; i < regionsArr.length; i++) {
dataNameMap[regionsArr[i].name] = regionsArr[i];
}
for (var i = 0; i < features.length; i++) {
var name = features[i].properties.name;
if (!dataNameMap[name]) {
regionsArr.push({
name: name
});
}
}
return regionsArr;
}
};
......@@ -184,4 +212,6 @@ define(function (require) {
echarts.loadMap = function () {};
echarts.registerCoordinateSystem('geo', geoCreator);
return geoCreator;
});
\ No newline at end of file
......@@ -256,19 +256,37 @@
legend: {
data: ['scatter', 'scatter2']
},
geo: {
geo: [{
map: 'china',
roam: true,
left: 10,
width: 300,
// zoom: 1.5,
scaleLimit: {
min: 1,
min: 1.5,
max: 2
},
roamDetail: {
x: -200,
y: -200,
zoom: 1.5
}
},
regions: [{
name: '新疆',
label: {
normal: {
show: true
}
},
itemStyle: {
normal: {
areaColor: '#aaa'
}
}
}]
}, {
map: 'china',
roam: true,
selectedMode: 'single',
left: null,
right: 10,
width: 300
}],
tooltip: {
trigger: 'axis',
axisPointer: {
......@@ -293,6 +311,10 @@
data: data2
}]
});
chart.on('click', function (param) {
console.log(param);
});
});
});
......
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="esl.js"></script>
<script src="config.js"></script>
</head>
<body>
<style>
html, body, #main {
width: 100%;
height: 100%;
}
</style>
<div id="main"></div>
<script>
require([
'echarts',
'echarts/chart/line',
'echarts/component/legend'
], function (echarts) {
var chart = echarts.init(document.getElementById('main'));
chart.setOption({
xAxis: {
data: ['类目1', '类目2', '类目3', '类目4', '类目5']
},
yAxis: {
minInterval: 1
},
series: [{
name: 'line',
type: 'line',
stack: 'all',
symbol: 'circle',
symbolSize: 10,
data: [0, 0, 0, 0, 0]
}]
});
});
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册