提交 3426bd0e 编写于 作者: P pah100

fix single axis, theme river, tweak label position, rotation, trigger logic.

上级 7ba19c32
......@@ -223,70 +223,53 @@ define(function (require) {
* Get data indices for show tooltip content
*
* @param {Array.<string>|string} dim single coordinate dimension
* @param {Array.<number>} value coordinate value
* @param {number} value axis value
* @param {module:echarts/coord/single/SingleAxis} baseAxis single Axis used
* the themeRiver.
* @return {Array.<number>}
* @return {Object} {dataIndices, nestestValue}
*/
getAxisTooltipDataIndex: function (dim, value, baseAxis) {
getAxisTooltipData: 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;
var nestestValue;
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);
var theValue = data.get(dim[0], layerSeries[i].indices[j]);
var dist = Math.abs(theValue - value);
if (dist <= minDist) {
nestestValue = theValue;
minDist = dist;
nearestIdx = layerSeries[i].indices[j];
}
}
indices.push(nearestIdx);
}
return indices;
return {dataIndices: indices, nestestValue: nestestValue};
},
/**
* @override
* @param {Array.<number>} dataIndexs index of data
* @param {number} dataIndex index of data
*/
formatTooltip: function (dataIndexs) {
formatTooltip: function (dataIndex) {
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 = encodeHTML(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 />';
var htmlName = data.get('name', dataIndex);
var htmlValue = data.get('value', dataIndex);
if (isNaN(htmlValue) || htmlValue == null) {
htmlValue = '-';
}
return html;
return encodeHTML(htmlName + ' : ' + htmlValue);
},
defaultOption: {
......
......@@ -55,7 +55,7 @@ define(function (require) {
* @param {string} [opt.axisLabelShow] default get from axisModel.
* @param {string} [opt.axisName] default get from axisModel.
* @param {number} [opt.axisNameAvailableWidth]
* @param {number} [opt.labelRotation] by degree, default get from axisModel.
* @param {number} [opt.labelRotate] by degree, default get from axisModel.
* @param {number} [opt.labelInterval] Default label interval when label
* interval from model is null or 'auto'.
* @param {number} [opt.strokeContainThreshold] Default label interval when label
......@@ -254,9 +254,9 @@ define(function (require) {
var labels = axisModel.getFormattedLabels();
// Special label rotate.
var labelRotation = retrieve(opt.labelRotation, labelModel.get('rotate')) || 0;
// To radian.
labelRotation = labelRotation * PI / 180;
var labelRotation = (
retrieve(opt.labelRotate, labelModel.get('rotate')) || 0
) * PI / 180;
var labelLayout = innerTextLayout(opt.rotation, labelRotation, opt.labelDirection);
var categoryData = axisModel.get('data');
......@@ -497,6 +497,11 @@ define(function (require) {
* @param {number} axisRotation in radian
* @param {number} textRotation in radian
* @param {number} direction
* @return {Object} {
* rotation, // according to axis
* textAlign,
* textVerticalAlign
* }
*/
var innerTextLayout = AxisBuilder.innerTextLayout = function (axisRotation, textRotation, direction) {
var rotationDiff = remRadian(textRotation - axisRotation);
......
......@@ -138,7 +138,7 @@ define(function (require) {
labelDirection: -1,
tickDirection: -1,
nameDirection: 1,
labelRotation: radiusAxisModel.getModel('axisLabel').get('rotate'),
labelRotate: radiusAxisModel.getModel('axisLabel').get('rotate'),
// Over splitLine and splitArea
z2: 1
};
......
......@@ -14,13 +14,13 @@ define(function (require) {
var selfBuilderAttr = 'splitLine';
var AxisView = require('./AxisView').extend({
var SingleAxisView = require('./AxisView').extend({
type: 'singleAxis',
axisPointerClass: SingleAxisPointer,
render: function (axisModel, ecModel) {
render: function (axisModel, ecModel, api, payload) {
var group = this.group;
......@@ -37,6 +37,8 @@ define(function (require) {
if (axisModel.get(selfBuilderAttr + '.show')) {
this['_' + selfBuilderAttr](axisModel, layout.labelInterval);
}
SingleAxisView.superCall(this, 'render', axisModel, ecModel, api, payload);
},
_splitLine: function(axisModel, labelInterval) {
......@@ -112,6 +114,6 @@ define(function (require) {
}
});
return AxisView;
return SingleAxisView;
});
\ No newline at end of file
define(function (require) {
var zrUtil = require('zrender/core/util');
var helper = {};
helper.layout = function (gridModel, axisModel) {
/**
* @param {Object} opt {labelInside}
* @return {Object} {
* position, rotation, labelDirection, labelOffset,
* tickDirection, labelRotate, labelInterval, z2
* }
*/
helper.layout = function (gridModel, axisModel, opt) {
opt = opt || {};
var grid = gridModel.coordinateSystem;
var axis = axisModel.axis;
var layout = {};
......@@ -45,16 +55,16 @@ define(function (require) {
layout.labelDirection = layout.tickDirection = layout.nameDirection = dirMap[rawAxisPosition];
layout.labelOffset = axis.onZero ? posMap[axisDim][rawAxisPosition] - posMap[axisDim].onZero : 0;
if (axisModel.getModel('axisTick').get('inside')) {
if (axisModel.get('axisTick.inside')) {
layout.tickDirection = -layout.tickDirection;
}
if (axisModel.getModel('axisLabel').get('inside')) {
if (zrUtil.retrieve(opt.labelInside, axisModel.get('axisLabel.inside'))) {
layout.labelDirection = -layout.labelDirection;
}
// Special label rotation
var labelRotation = axisModel.getModel('axisLabel').get('rotate');
layout.labelRotation = axisPosition === 'top' ? -labelRotation : labelRotation;
var labelRotate = axisModel.get('axisLabel.rotate');
layout.labelRotate = axisPosition === 'top' ? -labelRotate : labelRotate;
// label interval when auto mode.
layout.labelInterval = axis.getLabelInterval();
......
define(function (require) {
var zrUtil = require('zrender/core/util');
var helper = {};
helper.layout = function (axisModel) {
/**
* @param {Object} opt {labelInside}
* @return {Object} {
* position, rotation, labelDirection, labelOffset,
* tickDirection, labelRotate, labelInterval, z2
* }
*/
helper.layout = function (axisModel, opt) {
opt = opt || {};
var single = axisModel.coordinateSystem;
var axis = axisModel.axis;
var layout = {};
......@@ -36,15 +46,16 @@ define(function (require) {
= layout.nameDirection
= directionMap[axisPosition];
if (axisModel.getModel('axisTick').get('inside')) {
if (axisModel.get('axisTick.inside')) {
layout.tickDirection = -layout.tickDirection;
}
if (axisModel.getModel('axisLabel').get('inside')) {
if (zrUtil.retrieve(opt.labelInside, axisModel.get('axisLabel.inside'))) {
layout.labelDirection = -layout.labelDirection;
}
var labelRotation = axisModel.getModel('axisLabel').get('rotate');
var labelRotation = opt.rotate;
labelRotation == null && (labelRotation = axisModel.get('axisLabel.rotate'));
layout.labelRotation = axisPosition === 'top' ? -labelRotation : labelRotation;
layout.labelInterval = axis.getLabelInterval();
......
......@@ -12,7 +12,7 @@ define(function(require) {
// 'auto' means that show when triggered by tooltip or handle.
show: 'auto',
// 'auto' | 'click' | 'mousemove' | 'handle' | 'none'
triggerOn: 'mousemove',
triggerOn: ['mousemove', 'click'],
zlevel: 0,
z: 50,
......@@ -50,6 +50,7 @@ define(function(require) {
formatter: null, // string | Function
precision: 'auto', // Or a number like 0, 1, 2 ...
margin: 3,
rotate: 0, // in degree.
textStyle: {
color: '#fff',
fontSize: 12
......
......@@ -7,17 +7,11 @@ define(function (require) {
type: 'axisPointer',
render: function (globalAxisPointerModel, ecModel, api) {
var tooltipModel = ecModel.getComponent('tooltip');
var showDelay = (
tooltipModel && tooltipModel.get('showDelay')
) || globalAxisPointerModel.get('showDelay') || 0;
// Register global listener in AxisPointerView to enable
// AxisPointerView to be independent to Tooltip.
globalListener.register(
'axisPointer',
api,
{delay: showDelay},
function (currTrigger, e, dispatchAction) {
dispatchAction({
type: 'updateAxisPointer',
......
......@@ -89,7 +89,7 @@ define(function(require) {
// Otherwise status is 'show'
var elOption = {};
this.makeElOption(elOption, value, axisModel, axisPointerModel);
this.makeElOption(elOption, value, axisModel, axisPointerModel, api);
// Enable change axis pointer type.
var graphicKey = elOption.graphicKey;
......@@ -160,7 +160,7 @@ define(function(require) {
* add {pointer, label, graphicKey} to elOption
* @protected
*/
makeElOption: function (elOption, value, axisModel, axisPointerModel) {
makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
// Shoule be implemenented by sub-class.
},
......@@ -196,6 +196,7 @@ define(function(require) {
var labelEl = get(group).labelEl = new graphic.Rect(
extend(clone(basicOpt), elOption.label)
);
group.add(labelEl);
updateLabelShowHide(labelEl, axisPointerModel);
},
......@@ -244,7 +245,7 @@ define(function(require) {
* @private
*/
_renderHandle: function (value, moveAnimation, axisModel, axisPointerModel, api) {
if (this._dragging) {
if (this._dragging || !this.updateHandleTransform) {
return;
}
......@@ -374,17 +375,17 @@ define(function(require) {
},
/**
* Should be implemenented by sub-class if support `handle`.
* @protected
* @param {number} value
* @param {module:echarts/model/Model} axisModel
* @param {module:echarts/model/Model} axisPointerModel
* @return {Object} {position: [x, y], rotation: 0}
*/
getHandleTransform: function () {
// Should be implemenented by sub-class.
},
getHandleTransform: null,
/**
* * Should be implemenented by sub-class if support `handle`.
* @protected
* @param {Object} transform {position, rotation}
* @param {Array.<number>} delta [dx, dy]
......@@ -392,9 +393,7 @@ define(function(require) {
* @param {module:echarts/model/Model} axisPointerModel
* @return {Object} {position: [x, y], rotation: 0, cursorPoint: [x, y]}
*/
updateHandleTransform: function () {
// Should be implemenented by sub-class.
},
updateHandleTransform: null,
/**
* @private
......
define(function(require) {
'use strict';
var zrUtil = require('zrender/core/util');
var graphic = require('../../util/graphic');
var BaseAxisPointer = require('./BaseAxisPointer');
var viewHelper = require('./viewHelper');
var cartesianAxisHelper = require('../axis/cartesianAxisHelper');
var matrix = require('zrender/core/matrix');
var AxisBuilder = require('../axis/AxisBuilder');
var CartesianAxisPointer = BaseAxisPointer.extend({
/**
* @override
*/
makeElOption: function (elOption, value, axisModel, axisPointerModel) {
makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
var axis = axisModel.axis;
var grid = axis.grid;
var axisPointerType = axisPointerModel.get('type');
......@@ -28,23 +25,23 @@ define(function(require) {
elOption.graphicKey = pointerOption.type;
elOption.pointer = pointerOption;
var labelMargin = axisPointerModel.get('label.margin');
var labelPos = getLabelPosition(value, axisModel, axisPointerModel, grid, labelMargin);
viewHelper.buildLabelElOption(elOption, value, labelPos, axisModel, axisPointerModel);
var layoutInfo = cartesianAxisHelper.layout(grid.model, axisModel);
viewHelper.buildCartesianSingleLabelElOption(
value, elOption, layoutInfo, axisModel, axisPointerModel, api
);
},
/**
* @override
*/
getHandleTransform: function (value, axisModel, axisPointerModel) {
var handleMargin = axisPointerModel.get('handle.margin');
var handlePos = getLabelPosition(
value, axisModel, axisPointerModel, axisModel.axis.grid, handleMargin
);
var layoutInfo = cartesianAxisHelper.layout(axisModel.axis.grid.model, axisModel, {
labelInside: false
});
layoutInfo.labelMargin = axisPointerModel.get('handle.margin');
return {
position: handlePos.position,
rotation: handlePos.rotation
position: viewHelper.getTransformedPosition(axisModel.axis, value, layoutInfo),
rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
};
},
......@@ -70,32 +67,6 @@ define(function(require) {
});
function getLabelPosition(value, axisModel, axisPointerModel, grid, labelMargin) {
var axis = axisModel.axis;
var layout = cartesianAxisHelper.layout(grid.model, axisModel);
var transform = matrix.create();
matrix.rotate(transform, transform, layout.rotation);
matrix.translate(transform, transform, layout.position);
var position = graphic.applyTransform([
axis.dataToCoord(value),
layout.labelOffset + layout.labelDirection * labelMargin
], transform);
var labelRotation = zrUtil.retrieve(layout.labelRotation, axisPointerModel.get('label.rotate')) || 0;
labelRotation = labelRotation * Math.PI / 180;
var labelLayout = AxisBuilder.innerTextLayout(layout.rotation, labelRotation, layout.labelDirection);
return {
position: position,
align: labelLayout.textAlign,
verticalAlign: labelLayout.textVerticalAlign,
rotation: -layout.rotation
};
}
function getCartesian(grid, axis) {
var opt = {};
opt[axis.dim + 'AxisIndex'] = axis.index;
......
......@@ -13,7 +13,7 @@ define(function(require) {
/**
* @override
*/
makeElOption: function (elOption, value, axisModel, axisPointerModel) {
makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
var axis = axisModel.axis;
if (axis.dim === 'angle') {
......@@ -38,9 +38,11 @@ define(function(require) {
var labelMargin = axisPointerModel.get('label.margin');
var labelPos = getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin);
viewHelper.buildLabelElOption(elOption, value, labelPos, axisModel, axisPointerModel);
viewHelper.buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos);
}
// Do not support handle, utill any user requires it.
});
function getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin) {
......@@ -59,7 +61,7 @@ define(function(require) {
matrix.translate(transform, transform, [polar.cx, polar.cy]);
position = graphic.applyTransform([coord, -labelMargin], transform);
var labelRotation = axisModel.getModel('axisLabel').get('rotate');
var labelRotation = axisModel.getModel('axisLabel').get('rotate') || 0;
var labelLayout = AxisBuilder.innerTextLayout(
axisAngle, labelRotation * Math.PI / 180, -1
);
......
define(function(require) {
'use strict';
var zrUtil = require('zrender/core/util');
var graphic = require('../../util/graphic');
var BaseAxisPointer = require('./BaseAxisPointer');
var viewHelper = require('./viewHelper');
var singleAxisHelper = require('../axis/singleAxisHelper');
var matrix = require('zrender/core/matrix');
var AxisBuilder = require('../axis/AxisBuilder');
var XY = ['x', 'y'];
var WH = ['width', 'height'];
......@@ -17,14 +14,11 @@ define(function(require) {
/**
* @override
*/
makeElOption: function (elOption, value, axisModel, axisPointerModel) {
makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
var axis = axisModel.axis;
var coordSys = axis.coordinateSystem;
var rect = coordSys.getRect();
var otherDimIndex = 1 - getPointDimIndex(axis);
var otherExtent = [rect[XY[otherDimIndex]], rect[XY[otherDimIndex]] + rect[WH[otherDimIndex]]];
var otherExtent = getGlobalExtent(coordSys, 1 - getPointDimIndex(axis));
var pixelValue = coordSys.dataToPoint(value)[0];
var elStyle = viewHelper.buildElStyle(axisPointerModel);
var pointerOption = pointerShapeBuilder[axisPointerModel.get('type')](
axis, pixelValue, otherExtent, elStyle
......@@ -34,39 +28,44 @@ define(function(require) {
elOption.graphicKey = pointerOption.type;
elOption.pointer = pointerOption;
var labelMargin = axisPointerModel.get('label.margin');
var labelPos = getLabelPosition(value, axisModel, axisPointerModel, labelMargin);
viewHelper.buildLabelElOption(
elOption, value, labelPos, axisModel, axisPointerModel
var layoutInfo = singleAxisHelper.layout(axisModel);
viewHelper.buildCartesianSingleLabelElOption(
value, elOption, layoutInfo, axisModel, axisPointerModel, api
);
}
});
function getLabelPosition(value, axisModel, axisPointerModel, labelMargin) {
var axis = axisModel.axis;
var layout = singleAxisHelper.layout(axisModel);
var transform = matrix.create();
matrix.rotate(transform, transform, layout.rotation);
matrix.translate(transform, transform, layout.position);
var position = graphic.applyTransform([
axis.dataToCoord(value),
0 + layout.labelDirection * labelMargin
], transform);
var labelRotation = zrUtil.retrieve(layout.labelRotation, axisPointerModel.get('label.rotate')) || 0;
labelRotation = labelRotation * Math.PI / 180;
},
var labelLayout = AxisBuilder.innerTextLayout(layout.rotation, labelRotation, layout.labelDirection);
/**
* @override
*/
getHandleTransform: function (value, axisModel, axisPointerModel) {
var layoutInfo = singleAxisHelper.layout(axisModel, {labelInside: false});
layoutInfo.labelMargin = axisPointerModel.get('handle.margin');
return {
position: viewHelper.getTransformedPosition(axisModel.axis, value, layoutInfo),
rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
};
},
return {
position: position,
align: labelLayout.textAlign,
verticalAlign: labelLayout.textVerticalAlign
};
}
/**
* @override
*/
updateHandleTransform: function (transform, delta, axisModel, axisPointerModel) {
var axis = axisModel.axis;
var coordSys = axis.coordinateSystem;
var dimIndex = getPointDimIndex(axis);
var axisExtent = getGlobalExtent(coordSys, dimIndex);
var currPosition = transform.position;
currPosition[dimIndex] += delta[dimIndex];
currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]);
currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]);
var otherExtent = getGlobalExtent(coordSys, 1 - dimIndex);
var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2;
var cursorPoint = [cursorOtherValue, cursorOtherValue];
cursorPoint[dimIndex] = currPosition[dimIndex];
return {position: currPosition, rotation: transform.rotation, cursorPoint: cursorPoint};
}
});
var pointerShapeBuilder = {
......@@ -104,5 +103,10 @@ define(function(require) {
return axis.isHorizontal() ? 0 : 1;
}
function getGlobalExtent(coordSys, dimIndex) {
var rect = coordSys.getRect();
return [rect[XY[dimIndex]], rect[XY[dimIndex]] + rect[WH[dimIndex]]];
}
return SingleAxisPointer;
});
\ No newline at end of file
......@@ -2,6 +2,7 @@ define(function(require) {
var zrUtil = require('zrender/core/util');
var modelUtil = require('../../util/model');
var viewHelper = require('./viewHelper');
var each = zrUtil.each;
var curry = zrUtil.curry;
......@@ -41,10 +42,10 @@ define(function(require) {
each(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function (axisInfo, key) {
var axis = axisInfo.axis;
var triggerOn = axisInfo.axisPointerModel.get('triggerOn');
var triggerOns = modelUtil.normalizeToArray(axisInfo.axisPointerModel.get('triggerOn'));
if ((!currTrigger || triggerOn === currTrigger)
&& (triggerOn === 'handle' || (!shouldHide && coordSysContainsPoint))
if ((!currTrigger || zrUtil.indexOf(triggerOns, currTrigger) >= 0)
&& (currTrigger === 'handle' || (!shouldHide && coordSysContainsPoint))
&& !notTargetAxis(finder, axis)
) {
processOnAxis(axisInfo, axis.pointToData(point), updaters);
......@@ -90,11 +91,11 @@ define(function(require) {
// Heavy calculation. So put it after axis.containData checking.
var payloadInfo = buildPayloadsBySeries(newValue, axisInfo);
var payloadBatch = payloadInfo.payloadBatch;
var snapToValue = payloadInfo.snapToValue;
// If no linkSource input, this process is for collecting link
// target, where snap should not be accepted.
if (!dontSnap && axisInfo.snap) {
var snapToValue = payloadInfo.snapToValue;
if (axis.containData(snapToValue) && snapToValue != null) {
newValue = snapToValue;
}
......@@ -102,48 +103,64 @@ define(function(require) {
updaters.highlight('highlight', payloadBatch);
updaters.showPointer(axisInfo, newValue, payloadBatch);
updaters.showTooltip(axisInfo, payloadInfo, newValue);
// Tooltip should always be snapToValue, otherwise there will be
// incorrect "axis value ~ series value" mapping displayed in tooltip.
updaters.showTooltip(axisInfo, payloadInfo, snapToValue);
}
function buildPayloadsBySeries(value, axisInfo) {
var axis = axisInfo.axis;
var dim = axis.dim;
var minDist = Infinity;
var snapToValue = value;
var payloadBatch = [];
var minDist = Number.MAX_VALUE;
var minDiff = -1;
each(axisInfo.seriesModels, function (series, idx) {
var dataDim = series.coordDimToDataDim(dim);
var dataIndex = series.getAxisTooltipDataIndex
? series.getAxisTooltipDataIndex(dataDim, value, axis)
: series.getData().indexOfNearest(
var seriesNestestValue;
var dataIndices;
if (series.getAxisTooltipData) {
var result = series.getAxisTooltipData(dataDim, value, axis);
dataIndices = result.dataIndices;
seriesNestestValue = result.nestestValue;
}
else {
dataIndices = series.getData().indexOfNearest(
dataDim[0],
value,
// Add a threshold to avoid find the wrong dataIndex
// when data length is not same.
false, axis.type === 'category' ? 0.5 : null
);
if (!dataIndices.length) {
return;
}
seriesNestestValue = series.getData().get(dataDim[0], dataIndices[0]);
}
if (dataIndex == null || dataIndex < 0) {
if (seriesNestestValue == null || !isFinite(seriesNestestValue)) {
return;
}
var seriesNestestValue = series.getData().get(dim, dataIndex);
if (seriesNestestValue != null && isFinite(seriesNestestValue)) {
var dist = Math.abs(value - seriesNestestValue);
// Consider category case
if (dist <= minDist) {
if (dist < minDist) {
minDist = dist;
snapToValue = seriesNestestValue;
payloadBatch.length = 0;
}
var diff = value - seriesNestestValue;
var dist = Math.abs(diff);
// Consider category case
if (dist <= minDist) {
if (dist < minDist || (diff >= 0 && minDiff < 0)) {
minDist = dist;
minDiff = diff;
snapToValue = seriesNestestValue;
payloadBatch.length = 0;
}
each(dataIndices, function (dataIndex) {
payloadBatch.push({
seriesIndex: series.seriesIndex,
dataIndexInside: dataIndex,
dataIndex: series.getData().getRawIndex(dataIndex)
});
}
});
}
});
......@@ -160,16 +177,16 @@ define(function(require) {
function showTooltip(seriesDataByAxis, axisInfo, payloadInfo, value) {
var payloadBatch = payloadInfo.payloadBatch;
var axis = axisInfo.axis;
var valueLabel = viewHelper.getValueLabel(
value, axisInfo.axis.model, axisInfo.axisPointerModel
);
axisInfo.triggerTooltip && payloadBatch.length && seriesDataByAxis.push({
axisDim: axis.dim,
axisIndex: axis.model.componentIndex,
axisId: axis.model.id,
value: value,
valueLabel: axis.scale.getLabel(
value,
{precision: axisInfo.axisPointerModel.get('label.precision'), pad: true}
),
valueLabel: valueLabel,
seriesDataIndices: payloadBatch.slice()
});
}
......
......@@ -11,13 +11,11 @@ define(function(require) {
/**
* @param {string} key
* @param {module:echarts/ExtensionAPI} api
* @param {Object} opt
* @param {number} [opt.delay=0]
* @param {Function} handler
* param: {string} currTrigger
* param: {Array.<number>} point
*/
globalListener.register = function (key, api, opt, handler) {
globalListener.register = function (key, api, handler) {
if (env.node) {
return;
}
......@@ -29,7 +27,6 @@ define(function(require) {
var record = get(zr).records[key] || (get(zr).records[key] = {});
record.handler = handler;
record.opt = zrUtil.extend({}, opt);
};
function initGlobalListeners(zr, api) {
......@@ -40,7 +37,7 @@ define(function(require) {
get(zr).initialized = true;
useHandler('click', zrUtil.curry(doEnter, 'click'));
useHandler('mousemove', onMouseMove);
useHandler('mousemove', zrUtil.curry(doEnter, 'mousemove'));
useHandler('mouseout', onLeave);
useHandler('globalout', onLeave);
......@@ -92,22 +89,7 @@ define(function(require) {
}
}
function onMouseMove(record, e, dispatchAction) {
clearTimeout(record._showTimeout);
var delay = record.opt.delay;
if (delay > 0) {
record._showTimeout = setTimeout(function () {
doEnter('mousemove', record, e, dispatchAction);
}, delay);
}
else {
doEnter('mousemove', record, e, dispatchAction);
}
}
function onLeave(record, e, dispatchAction) {
clearTimeout(record._showTimeout);
record.handler('leave', null, dispatchAction);
}
......@@ -126,8 +108,6 @@ define(function(require) {
var record = (get(zr).records || {})[key];
if (record) {
clearTimeout(record._showTimeout);
record._showTimeout = null;
record.handler('leave');
get(zr).records[key] = null;
}
......
......@@ -51,6 +51,11 @@ define(function(require) {
// Collect axes info.
each(api.getCoordinateSystems(), function (coordSys) {
// Some coordinate system do not support axes, like geo.
if (!coordSys.axisPointerEnabled) {
return;
}
var coordSysKey = makeKey(coordSys.model);
var axesInfoInCoordSys = result.coordSysAxesInfo[coordSysKey] = {};
result.coordSysMap[coordSysKey] = coordSys;
......@@ -60,7 +65,7 @@ define(function(require) {
var coordSysModel = coordSys.model;
var baseTooltipModel = coordSysModel.getModel('tooltip', globalTooltipModel);
each(coordSys.getAxes && coordSys.getAxes(), curry(saveTooltipAxisInfo, false, null));
each(coordSys.getAxes(), curry(saveTooltipAxisInfo, false, null));
// If axis tooltip used, choose tooltip axis for each coordSys.
// Notice this case: coordSys is `grid` but not `cartesian2D` here.
......@@ -156,6 +161,9 @@ define(function(require) {
}
);
// Consider tooltip.triggerOn: 'click'.
volatileOption.triggerOn = baseTooltipModel.get('triggerOn');
// category axis do not auto snap, otherwise some tick that do not
// has value can not be hovered. value/time/log axis default snap if
// triggered from tooltip and trigger tooltip.
......
......@@ -2,8 +2,11 @@ define(function(require) {
'use strict';
var zrUtil = require('zrender/core/util');
var graphic = require('../../util/graphic');
var textContain = require('zrender/contain/text');
var formatUtil = require('../../util/format');
var matrix = require('zrender/core/matrix');
var AxisBuilder = require('../axis/AxisBuilder');
var helper = {};
......@@ -29,11 +32,11 @@ define(function(require) {
* @param {Function} labelPos {align, verticalAlign, position}
*/
helper.buildLabelElOption = function (
elOption, value, labelPos, axisModel, axisPointerModel
elOption, axisModel, axisPointerModel, api, labelPos
) {
var value = axisPointerModel.get('value');
var text = helper.getValueLabel(value, axisModel, axisPointerModel);
var labelModel = axisPointerModel.getModel('label');
var text = getLabelText(value, axisModel, axisPointerModel, labelModel);
var textStyleModel = labelModel.getModel('textStyle');
var paddings = formatUtil.normalizeCssArray(labelModel.get('padding') || 0);
......@@ -46,6 +49,7 @@ define(function(require) {
var width = textRect.width + paddings[1] + paddings[3];
var height = textRect.height + paddings[0] + paddings[2];
// Adjust by align.
var align = labelPos.align;
align === 'right' && (position[0] -= width);
align === 'center' && (position[0] -= width / 2);
......@@ -53,6 +57,9 @@ define(function(require) {
verticalAlign === 'bottom' && (position[1] -= height);
verticalAlign === 'middle' && (position[1] -= height / 2);
// Not overflow ec container
confineInContainer(position, width, height, api);
var bgColor = labelModel.get('backgroundColor');
if (!bgColor || bgColor === 'auto') {
bgColor = axisModel.get('axisLine.lineStyle.color');
......@@ -77,10 +84,22 @@ define(function(require) {
};
};
function getLabelText(value, axisModel, axisPointerModel, labelModel) {
// Use 'pad' to debounce when when moving label.
var text = axisModel.axis.scale.getLabel(value, {precision: labelModel.get('precision'), pad: true});
var formatter = labelModel.get('formatter');
// Do not overflow ec container
function confineInContainer(position, width, height, api) {
var viewWidth = api.getWidth();
var viewHeight = api.getHeight();
position[0] = Math.min(position[0] + width, viewWidth) - width;
position[1] = Math.min(position[1] + height, viewHeight) - height;
position[0] = Math.max(position[0], 0);
position[1] = Math.max(position[1], 0);
}
helper.getValueLabel = function (value, axisModel, axisPointerModel) {
var text = axisModel.axis.scale.getLabel(
// Use 'pad' to try to fix width, which helps to debounce when when moving label.
value, {precision: axisPointerModel.get('label.precision'), pad: true}
);
var formatter = axisPointerModel.get('label.formatter');
if (formatter) {
var params = {value: value, seriesData: []};
......@@ -102,7 +121,40 @@ define(function(require) {
}
return text;
}
};
/**
* @param {module:echarts/coord/Axis} axis
* @param {number} value
* @param {Object} layoutInfo {
* rotation, position, labelOffset, labelDirection, labelMargin
* }
*/
helper.getTransformedPosition = function (axis, value, layoutInfo) {
var transform = matrix.create();
matrix.rotate(transform, transform, layoutInfo.rotation);
matrix.translate(transform, transform, layoutInfo.position);
return graphic.applyTransform([
axis.dataToCoord(value),
(layoutInfo.labelOffset || 0)
+ (layoutInfo.labelDirection || 1) * (layoutInfo.labelMargin || 0)
], transform);
};
helper.buildCartesianSingleLabelElOption = function (
value, elOption, layoutInfo, axisModel, axisPointerModel, api
) {
var textLayout = AxisBuilder.innerTextLayout(
layoutInfo.rotation, 0, layoutInfo.labelDirection
);
layoutInfo.labelMargin = axisPointerModel.get('label.margin');
helper.buildLabelElOption(elOption, axisModel, axisPointerModel, api, {
position: helper.getTransformedPosition(axisModel.axis, value, layoutInfo),
align: textLayout.textAlign,
verticalAlign: textLayout.textVerticalAlign
});
};
/**
* @param {Array.<number>} p1
......
......@@ -33,7 +33,7 @@ define(function (require) {
var coordArr = [];
var value = numCalculate(data, targetDataDim, mlType);
var dataIndex = data.indexOfNearest(targetDataDim, value, true);
var dataIndex = data.indexOfNearest(targetDataDim, value, true)[0];
coordArr[otherCoordIndex] = data.get(otherDataDim, dataIndex, true);
coordArr[targetCoordIndex] = data.get(targetDataDim, dataIndex, true);
......
......@@ -185,7 +185,7 @@ define(function (require) {
// this.hide();
},
show: function (tooltipModel) {
show: function (tooltipModel, delay) {
clearTimeout(this._hideTimeout);
var el = this.el;
......@@ -200,9 +200,7 @@ define(function (require) {
},
setContent: function (content) {
var el = this.el;
el.innerHTML = content;
el.style.display = content ? 'block' : 'none';
this.el.innerHTML = content;
},
setEnterable: function (enterable) {
......
......@@ -21,7 +21,7 @@ define(function (require) {
trigger: 'item',
// 'click' | 'mousemove' | 'none'
triggerOn: 'mousemove',
triggerOn: ['mousemove', 'click'],
alwaysShowContent: false,
......
......@@ -75,14 +75,13 @@ define(function (require) {
_initGlobalListener: function () {
var tooltipModel = this._tooltipModel;
var triggerOn = tooltipModel.get('triggerOn');
var triggerOns = modelUtil.normalizeToArray(tooltipModel.get('triggerOn'));
globalListener.register(
'itemTooltip',
this._api,
{delay: tooltipModel.get('showDelay')},
bind(function (currTrigger, e, dispatchAction) {
if (currTrigger === triggerOn) {
if (zrUtil.indexOf(triggerOns, currTrigger) >= 0) {
this._tryShow(e, dispatchAction);
}
else if (currTrigger === 'leave') {
......@@ -240,8 +239,7 @@ define(function (require) {
var seriesDataByAxis = e.seriesDataByAxis;
if (seriesDataByAxis && seriesDataByAxis.length) {
var contentNotChanged = this._updateContentNotChanged(seriesDataByAxis);
this._showAxisTooltip(seriesDataByAxis, e, contentNotChanged);
this._showAxisTooltip(seriesDataByAxis, e);
}
// Always show item tooltip if mouse is on the element with dataIndex
else if (el && el.dataIndex != null) {
......@@ -259,7 +257,20 @@ define(function (require) {
}
},
_showAxisTooltip: function (seriesDataByAxis, e, contentNotChanged) {
_showOrMove: function (tooltipModel, cb) {
// showDelay is used in this case: tooltip.enterable is set
// as true. User intent to move mouse into tooltip and click
// something. `showDelay` makes it easyer to enter the content
// but tooltip do not move immediately.
var delay = tooltipModel.get('showDelay');
cb = zrUtil.bind(cb, this);
clearTimeout(this._showTimout);
delay > 0
? (this._showTimout = setTimeout(cb, delay))
: cb();
},
_showAxisTooltip: function (seriesDataByAxis, e) {
var ecModel = this._ecModel;
var point = [e.offsetX, e.offsetY];
var defaultHtml = [];
......@@ -305,21 +316,23 @@ define(function (require) {
defaultHtml = defaultHtml.join('<br /><br />');
var positionExpr = e.position;
if (contentNotChanged) {
this._updatePosition(
tooltipModel,
positionExpr || tooltipModel.get('position'),
point[0], point[1],
this._tooltipContent,
paramsList
);
}
else {
this._showTooltipContent(
tooltipModel, defaultHtml, paramsList, Math.random(),
point[0], point[1], positionExpr
);
}
this._showOrMove(tooltipModel, function () {
if (this._updateContentNotChangedOnAxis(seriesDataByAxis)) {
this._updatePosition(
tooltipModel,
positionExpr,
point[0], point[1],
this._tooltipContent,
paramsList
);
}
else {
this._showTooltipContent(
tooltipModel, defaultHtml, paramsList, Math.random(),
point[0], point[1], positionExpr
);
}
});
},
_showSeriesItemTooltip: function (e, el, dispatchAction) {
......@@ -349,10 +362,12 @@ define(function (require) {
var defaultHtml = dataModel.formatTooltip(dataIndex, false, dataType);
var asyncTicket = 'item_' + dataModel.name + '_' + dataIndex;
this._showTooltipContent(
tooltipModel, defaultHtml, params, asyncTicket,
e.offsetX, e.offsetY, e.position, e.target
);
this._showOrMove(tooltipModel, function () {
this._showTooltipContent(
tooltipModel, defaultHtml, params, asyncTicket,
e.offsetX, e.offsetY, e.position, e.target
);
});
// FIXME
// duplicated showtip if manuallyShowTip is called from dispatchAction.
......@@ -383,10 +398,12 @@ define(function (require) {
// only works on cooridinate system. In fact, we have not found case
// that requires setting `trigger` nothing on component yet.
this._showTooltipContent(
subTooltipModel, defaultHtml, subTooltipModel.get('formatterParams') || {},
asyncTicket, e.offsetX, e.offsetY, e.position, el
);
this._showOrMove(subTooltipModel, function () {
this._showTooltipContent(
subTooltipModel, defaultHtml, subTooltipModel.get('formatterParams') || {},
asyncTicket, e.offsetX, e.offsetY, e.position, el
);
});
// If not dispatch showTip, tip may be hide triggered by axis.
dispatchAction({
......@@ -427,8 +444,8 @@ define(function (require) {
html = formatter(params, asyncTicket, callback);
}
tooltipContent.show(tooltipModel);
tooltipContent.setContent(html);
tooltipContent.show(tooltipModel);
this._updatePosition(
tooltipModel, positionExpr, x, y, tooltipContent, params, el
......@@ -448,6 +465,7 @@ define(function (require) {
_updatePosition: function (tooltipModel, positionExpr, x, y, content, params, el) {
var viewWidth = this._api.getWidth();
var viewHeight = this._api.getHeight();
positionExpr = positionExpr || tooltipModel.get('position');
var rect = el && el.getBoundingRect().clone();
el && rect.applyTransform(el.transform);
......@@ -496,7 +514,7 @@ define(function (require) {
// FIXME
// Should we remove this but leave this to user?
_updateContentNotChanged: function (seriesDataByAxis) {
_updateContentNotChangedOnAxis: function (seriesDataByAxis) {
var last = this._lastSeriesDataByAxis;
var contentNotChanged = !!last && last.length === seriesDataByAxis.length;
......
......@@ -13,19 +13,24 @@
*
* + model {module:echarts/model/Model}: mandatory
*
* + create:
* + create: mandatory
* @param {module:echarts/model/Global} ecModel
* @param {module:echarts/ExtensionAPI} api
* @return {Object} coordinate system instance
*
* + update:
* + update: mandatory
* @param {module:echarts/model/Global} ecModel
* @param {module:echarts/ExtensionAPI} api
*
* + getAxis {Function}
* + getAxis {Function}: mandatory
* @param {string} dim
* @return {module:echarts/coord/Axis}
*
* + getAxes: {Function}: optional
* @return {Array.<module:echarts/coord/Axis>}
*
* + axisPointerEnabled {boolean}
*
* + dataToPoint {Function}: mandatory
* @param {Array.<*>} data
* @param {boolean} [clamp=false]
......@@ -55,8 +60,5 @@
* @param {Array|number} value
* @return {Array|number} convert result.
*
* + prepareAxisPointers {Function}: optional
* If implemented, this coordinate system supports axis tooltip and axis pointer.
* @param {Array.<Object>} seriesGroup
* @return {Array}
*
*/
......@@ -83,6 +83,8 @@ define(function(require, factory) {
gridProto.type = 'grid';
gridProto.axisPointerEnabled = true;
gridProto.getRect = function () {
return this._rect;
};
......
......@@ -49,10 +49,12 @@ define(function(require) {
Polar.prototype = {
constructor: Polar,
type: 'polar',
axisPointerEnabled: true,
constructor: Polar,
/**
* @param {Array.<string>}
* @readOnly
......
......@@ -54,6 +54,8 @@ define(function (require) {
type: 'singleAxis',
axisPointerEnabled: true,
constructor: Single,
/**
......
......@@ -547,37 +547,39 @@ define(function (require) {
* @param {number} value
* @param {boolean} stack If given value is after stacked
* @param {number} [maxDistance=Infinity]
* @return {number}
* @return {Array.<number>} Considere multiple points has the same value.
*/
listProto.indexOfNearest = function (dim, value, stack, maxDistance) {
var storage = this._storage;
var dimData = storage[dim];
var nearestIndices = [];
if (!dimData) {
return nearestIndices;
}
if (maxDistance == null) {
maxDistance = Infinity;
}
var nearestIdx = -1;
if (dimData) {
var minDist = Number.MAX_VALUE;
for (var i = 0, len = this.count(); i < len; i++) {
var diff = value - this.get(dim, i, stack);
var dist = Math.abs(diff);
if (
diff <= maxDistance
&& (dist < minDist
// For the case of two data are same on xAxis, which has sequence data.
// Show the nearest index
// https://github.com/ecomfe/echarts/issues/2869
|| (dist === minDist && diff > 0)
)
) {
var minDist = Number.MAX_VALUE;
var minDiff = -1;
for (var i = 0, len = this.count(); i < len; i++) {
var diff = value - this.get(dim, i, stack);
var dist = Math.abs(diff);
if (diff <= maxDistance && dist <= minDist) {
// For the case of two data are same on xAxis, which has sequence data.
// Show the nearest index
// https://github.com/ecomfe/echarts/issues/2869
if (dist < minDist || (diff >= 0 && minDiff < 0)) {
minDist = dist;
nearestIdx = i;
minDiff = diff;
nearestIndices.length = 0;
}
nearestIndices.push(i);
}
}
return nearestIdx;
return nearestIndices;
};
/**
......
......@@ -309,9 +309,9 @@ define(function(require) {
* @param {Array.<string>|string} dim
* @param {Array.<number>} value
* @param {module:echarts/coord/single/SingleAxis} baseAxis
* @return {Array.<number>} data indices.
* @return {Object} {dataIndices, nestestValue}.
*/
getAxisTooltipDataIndex: null,
getAxisTooltipData: null,
/**
* See tooltip.
......
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<script src="esl.js"></script>
<script src="config.js"></script>
<script src="lib/jquery.min.js"></script>
<script src="lib/facePrint.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="reset.css">
</head>
<body>
<style>
h1 {
line-height: 60px;
height: 60px;
background: #360;
text-align: center;
font-weight: bold;
color: #eee;
font-size: 14px;
}
.chart {
height: 350px;
}
</style>
<h1>Check dataZoom sync on two category axes with DATA MISSING and STACK and without min/max set.</h1>
<div class="chart" id="sync"></div>
<script>
var echarts;
var colorTool;
var chart;
var myChart;
var groupCategories = [];
var groupColors = [];
require([
'echarts',
'zrender/tool/color',
'echarts/chart/line',
'echarts/chart/parallel',
'echarts/component/grid',
'echarts/component/legend',
'echarts/component/tooltip',
'echarts/component/toolbox',
'echarts/component/dataZoom'
], function (ec, ct) {
echarts = ec;
colorTool = ct;
chart = myChart = echarts.init(document.getElementById('sync'));
option = {
dataZoom:[
{type:'slider',show:'true',xAxisIndex: [0, 1] },
{type:'inside',show:'true',xAxisIndex: [0, 1] }
],
tooltip: {
trigger: 'axis'
},
toolbox: {
feature: {
dataView: {
show: true,
readOnly: false
},
restore: {
show: true
},
saveAsImage: {
show: true
}
}
},
grid: {
containLabel: true
},
legend: {
data: ['增速','销量']
},
xAxis: [{
type: 'category',
axisTick: {
alignWithLabel: true
},
data: ['2000','2001','2002','2003','2004','2005','2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016']
},
{
type: 'category',
axisTick: {
alignWithLabel: true
},
data: ['2000','2001','2002','2003','2004','2005','2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016']
}],
yAxis: [{
type: 'value',
name: '销量',
min: 0,
max: 100,
position: 'left'
}],
series: [{
name: '增速',
type: 'line',
stack: '总量',
label: {
normal: {
show: true,
position: 'top',
}
},
lineStyle: {
normal: {
width: 3,
shadowColor: 'rgba(0,0,0,0.4)',
shadowBlur: 10,
shadowOffsetY: 10
}
},
data: [['2000',1],['2001',13]
,['2002',37],['2003',35],['2004',15],
['2005',13],['2006',25],['2007',21],['2008',6],['2009',45]
,['2010',32],['2011',2],['2012',4],['2013',13],['2014',6],['2015',11],['2016',12]]
}, {
name: '销量',
type: 'line',
yAxisIndex: 0,
xAxisIndex:1,
stack: '总量',
label: {
normal: {
show: true,
position: 'top'
}
},
data: [['2000',1],['2001',13]
,['2002',37],['2003',35],['2004',15],
['2005',13],['2006',25],['2007',21],['2008',6],['2009',45]
,['2010',32],['2011',2],['2012',4],['2013',13],['2014',6]]
}]
};
chart.setOption(option);
});
</script>
</body>
</html>
\ No newline at end of file
......@@ -23,12 +23,9 @@
'echarts/component/legend',
'echarts/component/singleAxis',
'echarts/component/tooltip',
// 'echarts/component/axis'
], function (echarts) {
var chart = echarts.init(document.getElementById('main'), null, {
renderer: 'canvas'
});
var chart = echarts.init(document.getElementById('main'));
window.onresize = function () {
chart.resize();
......@@ -37,15 +34,7 @@
chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line',
lineStyle: {
color: 'rgba(0,0,0,0.2)',
width: 1,
type: 'solid'
}
}
trigger: 'axis'
},
legend: {
......
......@@ -30,6 +30,8 @@
<div class="chart" id="category-animation"></div>
<h1>time axis cross | x snap | label show | tooltip show</h1>
<div class="chart" id="time-cross"></div>
<h1>axis label too long | x axis label rotate | label should not overflow ec container</h1>
<div class="chart" id="label-rotate"></div>
<h1>two value axes | snap | grid.tooltip setting | snap has animation </h1>
<div class="chart" id="two-value-axes"></div>
<h1>label style and formatter</h1>
......@@ -44,6 +46,8 @@
<div class="chart" id="value-axis-as-base"></div>
<h1>polar category</h1>
<div class="chart" id="polar-category"></div>
<h1>multiple points with the same axis value | when not snap tooltip should be correct</h1>
<div class="chart" id="same-value"></div>
<h1>no tooltip</h1>
<div class="chart" id="no-tooltip"></div>
......@@ -129,7 +133,8 @@
var height = 250;
var gap = 30;
makeCategoryGrid(option, {
grid: {left: 100, top: baseTop, height: height}
grid: {left: 100, top: baseTop, height: height},
xAxis: {boundaryGap: true}
}, false, 100, 'bar');
baseTop += height + gap;
......@@ -180,6 +185,53 @@
<script>
require([
'echarts',
'echarts/chart/scatter',
'echarts/chart/line',
'echarts/component/legend',
'echarts/component/grid',
'echarts/component/tooltip',
'zrender/vml/vml'
], function (echarts) {
var option = {
tooltip: {
trigger: 'axis',
axisPointer: {type: 'cross'}
}
};
var baseTop = 90;
makeCategoryGrid(option, {
grid: {
containLabel: true, left: 5, right: 10, top: baseTop, height: 140
},
xAxis: {
axisLabel: {
rotate: 30,
formatter: function (value) {
return echarts.format.truncateText(value, 50);
}
}
}
}, null, null, null, 'toolonglonglonglonglonglonglong');
createChart('label-rotate', echarts, option, baseTop + 200);
})
</script>
<script>
require([
'echarts',
......@@ -634,6 +686,108 @@
<script>
require([
'echarts',
'echarts/chart/line',
'echarts/component/legend',
'echarts/component/grid',
'echarts/component/tooltip',
'zrender/vml/vml'
], function (echarts) {
var option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
xAxis: [{
nameLocation: 'middle',
nameGap: 30,
name: 'snap: show display both value'
}, {
gridIndex: 1,
nameLocation: 'middle',
nameGap: 30,
name: 'not snap: put axis on the middle of the two points, should display only one value.'
}, {
gridIndex: 2,
nameLocation: 'middle',
nameGap: 30,
name: 'step line not snap: should tooltip correct.',
axisPointer: {
snap: false
}
}],
yAxis: [{}, {gridIndex: 1}, {gridIndex: 2}],
grid: [{
top: 10,
height: 100
}, {
top: 200,
height: 100
}, {
top: 400,
height: 200
}],
series: [{
type: 'line',
data: [[10, 10], [10, 20], [20, 20]]
}, {
type: 'line',
xAxisIndex: 1,
yAxisIndex: 1,
data: [[10, 10], [30, 10]]
}, {
xAxisIndex: 2,
yAxisIndex: 2,
name:'Step Start',
type:'line',
step: 'start',
data: echarts.util.map([120, 132, 101, 134, 90, 230, 210], function (value, index) {
return [index * 100, value];
})
}, {
xAxisIndex: 2,
yAxisIndex: 2,
name:'Step Middle',
type:'line',
step: 'middle',
data: echarts.util.map([220, 282, 201, 234, 290, 430, 410], function (value, index) {
return [index * 100, value];
})
}, {
xAxisIndex: 2,
yAxisIndex: 2,
name:'Step End',
type:'line',
step: 'end',
data: echarts.util.map([450, 432, 401, 454, 590, 530, 510], function (value, index) {
return [index * 100, value];
})
}]
};
createChart('same-value', echarts, option, 700);
})
</script>
<script>
require([
......
......@@ -30,10 +30,8 @@
<div class="chart" id="handle-category"></div>
<h1>handle | value axis | x snap, y not-snap | has init handle value | tooltip.alwaysShowContent</h1>
<div class="chart" id="handle-value-init"></div>
<h1>single coordinate system handle | tooltip time label should be consistent with axisPinter.label.formatter</h1>
<div class="chart" id="themeRiver"></div>
......@@ -166,10 +164,30 @@
};
var baseTop = 90;
var height = 150;
var gap = 50;
var gap = 160;
makeValueGrid(option, {
grid: {left: 100, top: baseTop, height: height},
grid: {left: 100, top: baseTop, height: height, left: 120, right: 120},
xAxis: {
axisPointer: {
triggerOn: 'handle',
snap: true,
value: 600 // init value
}
},
yAxis: {
axisPointer: {
triggerOn: 'handle',
handle: {
margin: 70
}
}
}
});
baseTop += height + gap;
makeValueGrid(option, {
grid: {left: 100, top: baseTop, height: height, left: 120, right: 120},
xAxis: {
position: 'top',
axisPointer: {
triggerOn: 'handle',
snap: true,
......@@ -177,6 +195,11 @@
}
},
yAxis: {
inverse: true,
position: 'right',
axisLine: {
onZero: false
},
axisPointer: {
triggerOn: 'handle',
handle: {
......@@ -199,6 +222,112 @@
<script>
require([
'echarts',
'echarts/chart/themeRiver',
'echarts/component/legend',
'echarts/component/singleAxis',
'echarts/component/tooltip',
], function (echarts) {
var chart = echarts.init(document.getElementById('themeRiver'));
var option = {
tooltip: {
triggerOn: 'none',
alwaysShowContent: true
},
legend: {
data: ['DQ', 'TY', 'SS', 'QG', 'SY', 'DD']
},
singleAxis: {
axisTick: {},
axisLabel: {},
top: 100,
bottom: 100,
// position: 'top',
type: 'time',
axisPointer: {
triggerOn: 'handle',
label: {
formatter: function (params) {
return echarts.format.formatTime('yyyy-MM-dd', params.value);
}
}
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
opacity: 0.2
}
}
},
series: [
{
type: 'themeRiver',
itemStyle: {
emphasis: {
shadowBlur: 20,
shadowColor: 'rgba(0, 0, 0, 0.8)'
}
},
data: [['2015/11/08',10,'DQ'],['2015/11/09',15,'DQ'],['2015/11/10',35,'DQ'],
// ['2015/11/11',38,'DQ'],['2015/11/12',22,'DQ'],['2015/11/13',16,'DQ'],
['2015/11/14',7,'DQ'],['2015/11/15',2,'DQ'],['2015/11/16',17,'DQ'],
['2015/11/17',33,'DQ'],['2015/11/18',40,'DQ'],['2015/11/19',32,'DQ'],
['2015/11/20',26,'DQ'],['2015/11/21',35,'DQ'],['2015/11/22',40,'DQ'],
['2015/11/23',32,'DQ'],['2015/11/24',26,'DQ'],['2015/11/25',22,'DQ'],
// ['2015/11/26',16,'DQ'],['2015/11/27',22,'DQ'],['2015/11/28',10,'DQ'],
['2015/11/08',35,'TY'],['2015/11/09',36,'TY'],['2015/11/10',37,'TY'],
['2015/11/11',22,'TY'],['2015/11/12',24,'TY'],['2015/11/13',26,'TY'],
['2015/11/14',34,'TY'],['2015/11/15',21,'TY'],['2015/11/16',18,'TY'],
['2015/11/17',45,'TY'],['2015/11/18',32,'TY'],['2015/11/19',35,'TY'],
['2015/11/20',30,'TY'],['2015/11/21',28,'TY'],['2015/11/22',27,'TY'],
['2015/11/23',26,'TY'],['2015/11/24',15,'TY'],['2015/11/25',30,'TY'],
['2015/11/26',35,'TY'],['2015/11/27',42,'TY'],['2015/11/28',42,'TY'],
['2015/11/08',21,'SS'],['2015/11/09',25,'SS'],['2015/11/10',27,'SS'],
['2015/11/11',23,'SS'],['2015/11/12',24,'SS'],['2015/11/13',21,'SS'],
['2015/11/14',35,'SS'],['2015/11/15',39,'SS'],['2015/11/16',40,'SS'],
['2015/11/17',36,'SS'],['2015/11/18',33,'SS'],['2015/11/19',43,'SS'],
['2015/11/20',40,'SS'],['2015/11/21',34,'SS'],['2015/11/22',28,'SS'],
// ['2015/11/23',26,'SS'],['2015/11/24',37,'SS'],['2015/11/25',41,'SS'],
// ['2015/11/26',46,'SS'],['2015/11/27',47,'SS'],['2015/11/28',41,'SS'],
// ['2015/11/08',10,'QG'],['2015/11/09',15,'QG'],['2015/11/10',35,'QG'],
// ['2015/11/11',38,'QG'],['2015/11/12',22,'QG'],['2015/11/13',16,'QG'],
['2015/11/14',7,'QG'],['2015/11/15',2,'QG'],['2015/11/16',17,'QG'],
['2015/11/17',33,'QG'],['2015/11/18',40,'QG'],['2015/11/19',32,'QG'],
['2015/11/20',26,'QG'],['2015/11/21',35,'QG'],['2015/11/22',40,'QG'],
['2015/11/23',32,'QG'],['2015/11/24',26,'QG'],['2015/11/25',22,'QG'],
['2015/11/26',16,'QG'],['2015/11/27',22,'QG'],['2015/11/28',10,'QG'],
['2015/11/08',10,'SY'],['2015/11/09',15,'SY'],['2015/11/10',35,'SY'],
['2015/11/11',38,'SY'],['2015/11/12',22,'SY'],['2015/11/13',16,'SY'],
['2015/11/14',7,'SY'],['2015/11/15',2,'SY'],['2015/11/16',17,'SY'],
['2015/11/17',33,'SY'],['2015/11/18',40,'SY'],['2015/11/19',32,'SY'],
['2015/11/20',26,'SY'],['2015/11/21',35,'SY'],['2015/11/22',4,'SY'],
['2015/11/23',32,'SY'],['2015/11/24',26,'SY'],['2015/11/25',22,'SY'],
['2015/11/26',16,'SY'],['2015/11/27',22,'SY'],['2015/11/28',10,'SY'],
['2015/11/08',10,'DD'],['2015/11/09',15,'DD'],['2015/11/10',35,'DD'],
['2015/11/11',38,'DD'],['2015/11/12',22,'DD'],['2015/11/13',16,'DD'],
['2015/11/14',7,'DD'],['2015/11/15',2,'DD'],['2015/11/16',17,'DD'],
['2015/11/17',33,'DD'],['2015/11/18',4,'DD'],['2015/11/19',32,'DD'],
['2015/11/20',26,'DD'],['2015/11/21',35,'DD'],['2015/11/22',40,'DD'],
['2015/11/23',32,'DD'],['2015/11/24',26,'DD'],['2015/11/25',22,'DD'],
['2015/11/26',16,'DD'],['2015/11/27',22,'DD'],['2015/11/28',10,'DD']]
}
]
};
createChart('themeRiver', echarts, option, 500);
});
</script>
</body>
</html>
\ No newline at end of file
......@@ -33,17 +33,12 @@
<div class="chart" id="cross-axis"></div>
<h1>tooltip.axisPointer.axis is 'y' | auto snap | auto animation when snap</h1>
<div class="chart" id="tooltip.axisPointer.axis"></div>
<h1>showDelay: 50 | dynamic callback</h1>
<h1>showDelay: 50 | enterable | dynamic callback</h1>
<div class="chart" id="main"></div>
tooltip 动态回调
tooltip 固定位置
tooltip enterable
triggerOn click
http://echarts.baidu.com/option.html#tooltip.position 每个配置项都试验一下。
<h1>set position</h1>
<div class="chart" id="position"></div>
<h1>triggerOn click</h1>
<div class="chart" id="click"></div>
......@@ -389,44 +384,46 @@ http://echarts.baidu.com/option.html#tooltip.position 每个配置项都试验
trigger: 'axis',
//show: true, //default true
showDelay: 50,
// hideDelay: 200,
// transitionDuration:0.2,
// backgroundColor : 'rgba(255,0,255,0.7)',
// borderColor : '#f50',
// borderRadius : 8,
// borderWidth: 2,
// padding: 10, // [5, 10, 15, 20]
// axisPointer: {
// type: 'shadow'
// },
// position : function(p) {
// // 位置回调
// // console.log && console.log(p);
// return [p[0] + 10, p[1] - 10];
// },
// textStyle : {
// color: 'yellow',
// decoration: 'none',
// fontFamily: 'Verdana, sans-serif',
// fontSize: 15,
// fontStyle: 'italic',
// fontWeight: 'bold'
// },
// formatter: function (params,ticket,callback) {
// if (params.componentType === 'legend') {
// return params.name;
// }
// var res = 'Function formatter : <br/>' + params[0].name;
// for (var i = 0, l = params.length; i < l; i++) {
// res += '<br/>' + params[i].seriesName + ' : ' + params[i].value;
// }
// setTimeout(function (){
// // 仅为了模拟异步回调
// callback(ticket, res);
// }, 1000);
// return 'loading';
// }
//formatter: "Template formatter: <br/>{b}<br/>{a}:{c}<br/>{a1}:{c1}"
hideDelay: 200,
transitionDuration:0.2,
backgroundColor : 'rgba(255,0,255,0.7)',
borderColor : '#f50',
borderRadius : 8,
borderWidth: 2,
enterable: true,
padding: 10, // [5, 10, 15, 20]
axisPointer: {
type: 'shadow'
},
position : function(p) {
// 位置回调
// console.log && console.log(p);
return [p[0] + 10, p[1] - 10];
},
textStyle : {
color: 'yellow',
decoration: 'none',
fontFamily: 'Verdana, sans-serif',
fontSize: 15,
fontStyle: 'italic',
fontWeight: 'bold'
},
formatter: function (params,ticket,callback) {
if (params.componentType === 'legend') {
return params.name;
}
var res = 'Function formatter : <br/>' + params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
res += '<br/>' + params[i].seriesName + ' : ' + params[i].value;
}
res += '<br /><a target="_blank" href="http://www.baidu.com">搜索</a>';
setTimeout(function (){
// 仅为了模拟异步回调
callback(ticket, res);
}, 1000);
return 'loading';
}
// ,formatter: "Template formatter: <br/>{b}<br/>{a}:{c}<br/>{a1}:{c1}"
},
toolbox: {
show : true,
......@@ -472,7 +469,10 @@ http://echarts.baidu.com/option.html#tooltip.position 每个配置项都试验
data:[
{
value: 120,
tooltip: '我是一个简单的字符串'
tooltip: '我是一个简单的字符串',
label: {
normal: {show: true, formatter: 'formatter is string', textStyle: {color: '#222'}}
}
}, 132,
{
value: 301,
......@@ -510,5 +510,132 @@ http://echarts.baidu.com/option.html#tooltip.position 每个配置项都试验
});
});
</script>
<script>
require([
'echarts',
'echarts/chart/pie',
'echarts/component/legend',
'echarts/component/grid',
'echarts/component/tooltip',
'zrender/vml/vml'
], function (echarts) {
var option = {
tooltip: {
},
series: {
name: '访问来源',
type: 'pie',
radius : 80,
tooltip: {
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
data:[
{
value:335, name:'position: [300, 100]',
tooltip: {
position: [300, 100]
}
},
{
value:310, name:'position: function [p[0] + 10, p[1] - 50]',
tooltip: {
position : function(p) {
return [p[0] + 10, p[1] - 50];
}
}
},
{
value:234, name:'position: inside',
tooltip: {
position : 'inside'
}
},
{
value:135, name:'align: right; verticalAlign: bottom',
tooltip: {
align: 'right',
verticalAlign: 'bottom'
}
},
{
value:548, name:'position: [30, 140], verticalAlign: bottom',
tooltip: {
position: [30, 140],
verticalAlign: 'bottom'
}
}
],
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
};
createChart('position', echarts, option, 500);
})
</script>
<script>
require([
'echarts',
'echarts/chart/line',
'echarts/component/legend',
'echarts/component/grid',
'echarts/component/tooltip',
'zrender/vml/vml'
], function (echarts) {
var option = {
tooltip: {
trigger: 'axis',
triggerOn: 'click',
axisPointer: {
type: 'cross'
}
}
};
var baseTop = 90;
var height = 150;
var gap = 50;
makeCategoryGrid(option, {
grid: {top: baseTop, height: height},
yAxis: {
name: 'click show tip',
tooltip: {
show: true
}
}
});
baseTop += height + gap;
createChart('click', echarts, option, baseTop);
})
</script>
</body>
</html>
\ No newline at end of file
......@@ -77,8 +77,8 @@ function makeValueData() {
data3.push(['-', '-']);
for (var i = 0; i < 5; i++) {
data1.push([(Math.random() * 1000).toFixed(2), (-Math.random() - 0.2).toFixed(3)]);
data2.push([(Math.random() * 1000).toFixed(2), (Math.random() + 0.3).toFixed(3)]);
data1.push([(Math.random() * 1000).toFixed(2), (-Math.random() - 0.4).toFixed(3)]);
data2.push([(Math.random() * 1000).toFixed(2), (Math.random() + 1.8).toFixed(3)]);
data3.push([(Math.random() * 1000).toFixed(2), (Math.random() + 0.2).toFixed(3)]);
}
......@@ -206,8 +206,8 @@ function makeCategoryPolar(option, patterns, inV) {
);
}
function makeCategoryGrid(option, patterns, inV, dataCount, seriesType) {
var data = makeCategoryData(null, null, dataCount);
function makeCategoryGrid(option, patterns, inV, dataCount, seriesType, catePrefix) {
var data = makeCategoryData(null, catePrefix, dataCount);
var key = Math.random().toFixed(5);
seriesType = seriesType || 'line';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册