316 lines
9.3 KiB
Plaintext
316 lines
9.3 KiB
Plaintext
define(function (require) {
|
|
|
|
'use strict';
|
|
|
|
var completeDimensions = require('../../data/helper/completeDimensions');
|
|
var SeriesModel = require('../../model/Series');
|
|
var List = require('../../data/List');
|
|
var zrUtil = require('zrender/core/util');
|
|
var formatUtil = require('../../util/format');
|
|
var encodeHTML = formatUtil.encodeHTML;
|
|
var nest = require('../../util/array/nest');
|
|
|
|
var DATA_NAME_INDEX = 2;
|
|
|
|
var ThemeRiverSeries = SeriesModel.extend({
|
|
|
|
type: 'series.themeRiver',
|
|
|
|
dependencies: ['singleAxis'],
|
|
|
|
/**
|
|
* @readOnly
|
|
* @type {Object}
|
|
*/
|
|
nameMap: null,
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
init: function (option) {
|
|
ThemeRiverSeries.superApply(this, 'init', arguments);
|
|
|
|
// Enable legend selection for each data item
|
|
// Use a function instead of direct access because data reference may changed
|
|
this.legendDataProvider = function () {
|
|
return this._dataBeforeProcessed;
|
|
};
|
|
},
|
|
|
|
/**
|
|
* If there is no value of a certain point in the time for some event,set it value to 0.
|
|
*
|
|
* @param {Array} data
|
|
* @return {Array}
|
|
*/
|
|
fixData: function (data) {
|
|
var rawDataLength = data.length;
|
|
|
|
// grouped data by name
|
|
var dataByName = nest()
|
|
.key(function (dataItem) {
|
|
return dataItem[2] ;
|
|
})
|
|
.entries(data);
|
|
|
|
// data group in each layer
|
|
var layData = zrUtil.map(dataByName, function (d) {
|
|
return {
|
|
name: d.key,
|
|
dataList: d.values
|
|
};
|
|
});
|
|
|
|
var layerNum = layData.length;
|
|
var largestLayer = -1;
|
|
var index = -1;
|
|
for (var i = 0; i < layerNum; ++i) {
|
|
var len = layData[i].dataList.length;
|
|
if (len > largestLayer) {
|
|
largestLayer = len;
|
|
index = i;
|
|
}
|
|
}
|
|
|
|
for (var k = 0; k < layerNum; ++k) {
|
|
if (k === index) {
|
|
continue;
|
|
}
|
|
var name = layData[k].name;
|
|
for (var j = 0; j < largestLayer; ++j) {
|
|
var timeValue = layData[index].dataList[j][0];
|
|
var length = layData[k].dataList.length;
|
|
var keyIndex = -1;
|
|
for (var l = 0; l < length; ++l){
|
|
var value = layData[k].dataList[l][0];
|
|
if (value === timeValue) {
|
|
keyIndex = l;
|
|
break;
|
|
}
|
|
}
|
|
if (keyIndex === -1) {
|
|
data[rawDataLength] = [];
|
|
data[rawDataLength][0] = timeValue;
|
|
data[rawDataLength][1] = 0;
|
|
data[rawDataLength][2] = name;
|
|
rawDataLength++;
|
|
|
|
}
|
|
}
|
|
}
|
|
return data;
|
|
},
|
|
|
|
/**
|
|
* @override
|
|
* @param {Object} option the initial option that user gived
|
|
* @param {module:echarts/model/Model} ecModel
|
|
* @return {module:echarts/data/List}
|
|
*/
|
|
getInitialData: function (option, ecModel) {
|
|
|
|
var dimensions = [];
|
|
|
|
var singleAxisModel = ecModel.getComponent(
|
|
'singleAxis', this.option.singleAxisIndex
|
|
);
|
|
var axisType = singleAxisModel.get('type');
|
|
|
|
dimensions = [
|
|
{
|
|
name: 'time',
|
|
// FIXME
|
|
// common?
|
|
type: axisType === 'category'
|
|
? 'ordinal'
|
|
: axisType === 'time'
|
|
? 'time'
|
|
: 'float'
|
|
},
|
|
{
|
|
name: 'value',
|
|
type: 'float'
|
|
},
|
|
{
|
|
name: 'name',
|
|
type: 'ordinal'
|
|
}
|
|
];
|
|
|
|
var data = this.fixData(option.data);
|
|
var nameList = [];
|
|
var nameMap = this.nameMap = {};
|
|
var count = 0;
|
|
|
|
for (var i = 0; i < data.length; ++i) {
|
|
nameList.push(data[i][DATA_NAME_INDEX]);
|
|
if (!nameMap[data[i][DATA_NAME_INDEX]]) {
|
|
nameMap[data[i][DATA_NAME_INDEX]] = count++;
|
|
}
|
|
}
|
|
|
|
completeDimensions(dimensions, data);
|
|
|
|
var list = new List(dimensions, this);
|
|
|
|
list.initData(data, nameList);
|
|
|
|
return list;
|
|
},
|
|
|
|
/**
|
|
* used by single coordinate.
|
|
*
|
|
* @param {string} axisDim
|
|
* @return {Array.<string> } specified dimensions on the axis.
|
|
*/
|
|
coordDimToDataDim: function (axisDim) {
|
|
var dims = {
|
|
oneDim: ['time']
|
|
};
|
|
return dims[axisDim];
|
|
},
|
|
|
|
/**
|
|
* The raw data is divided into multiple layers and each layer
|
|
* has same name.
|
|
*
|
|
* @return {Array.<Array.<number>}
|
|
*/
|
|
getLayerSeries: function () {
|
|
var data = this.getData();
|
|
var lenCount = data.count();
|
|
var indexArr = [];
|
|
|
|
for (var i = 0; i < lenCount; ++i) {
|
|
indexArr[i] = i;
|
|
}
|
|
// data group by name
|
|
var dataByName = nest()
|
|
.key(function (index) {
|
|
return data.get('name', index);
|
|
})
|
|
.entries(indexArr);
|
|
|
|
var layerSeries = zrUtil.map(dataByName, function (d) {
|
|
return {
|
|
name: d.key,
|
|
indices: d.values
|
|
};
|
|
});
|
|
|
|
for(var j = 0; j < layerSeries.length; ++j) {
|
|
layerSeries[j].indices.sort(comparer);
|
|
}
|
|
|
|
function comparer(index1, index2) {
|
|
return data.get('time', index1) - data.get('time', index2);
|
|
}
|
|
|
|
return layerSeries;
|
|
},
|
|
|
|
/**
|
|
* Get data indices for show tooltip content.
|
|
*
|
|
* @param {Array.<string>} dim
|
|
* @param {Array.<number>} value
|
|
* @param {module:echarts/coord/single/SingleAxis} baseAxis
|
|
* @return {Array.<number>}
|
|
*/
|
|
getAxisTooltipDataIndex: function (dim, value, baseAxis) {
|
|
if (!zrUtil.isArray(dim)) {
|
|
dim = dim ? [dim] : [];
|
|
}
|
|
|
|
var data = this.getData();
|
|
|
|
if (baseAxis.orient === 'horizontal') {
|
|
value = value[0];
|
|
}
|
|
else {
|
|
value = value[1];
|
|
}
|
|
|
|
var layerSeries = this.getLayerSeries();
|
|
var indices = [];
|
|
var layerNum = layerSeries.length;
|
|
|
|
for (var i = 0; i < layerNum; ++i) {
|
|
var minDist = Number.MAX_VALUE;
|
|
var nearestIdx = -1;
|
|
var pointNum = layerSeries[i].indices.length;
|
|
for (var j = 0; j < pointNum; ++j) {
|
|
var dist = Math.abs(data.get(dim[0], layerSeries[i].indices[j]) - value);
|
|
if (dist <= minDist) {
|
|
minDist = dist;
|
|
nearestIdx = layerSeries[i].indices[j];
|
|
}
|
|
}
|
|
indices.push(nearestIdx);
|
|
}
|
|
return indices;
|
|
},
|
|
|
|
/**
|
|
* @override
|
|
* @param {Array.<number>} dataIndex
|
|
*/
|
|
formatTooltip: function (dataIndexs) {
|
|
var data = this.getData();
|
|
var len = dataIndexs.length;
|
|
var time = data.get('time', dataIndexs[0]);
|
|
var single = this.coordinateSystem;
|
|
var axis = single.getAxis();
|
|
|
|
if (axis.scale.type === 'time') {
|
|
time = formatUtil.formatTime('yyyy-MM-dd', time);
|
|
}
|
|
|
|
var html = time + '<br />';
|
|
for (var i = 0; i < len; ++i) {
|
|
var htmlName = data.get('name', dataIndexs[i]);
|
|
var htmlValue = data.get('value', dataIndexs[i]);
|
|
if (isNaN(htmlValue) || htmlValue == null) {
|
|
htmlValue = '-';
|
|
}
|
|
html += encodeHTML(htmlName) + ' : ' + htmlValue + '<br />';
|
|
}
|
|
return html;
|
|
},
|
|
|
|
defaultOption: {
|
|
zlevel: 0,
|
|
z: 2,
|
|
|
|
coordinateSystem: 'single',
|
|
|
|
// gap in axis's orthogonal orientation
|
|
boundaryGap: ['10%', '10%'],
|
|
|
|
// legendHoverLink: true,
|
|
|
|
singleAxisIndex: 0,
|
|
|
|
animationEasing: 'linear',
|
|
|
|
label: {
|
|
normal: {
|
|
margin: 4,
|
|
textAlign: 'right',
|
|
show: true,
|
|
position: 'left',
|
|
textStyle: {
|
|
color: '#000',
|
|
fontSize: 11
|
|
}
|
|
},
|
|
emphasis: {
|
|
show: true
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
return ThemeRiverSeries;
|
|
}); |