提交 099367a2 编写于 作者: D deqingli
......@@ -51,6 +51,14 @@ export default echarts.extendComponentView({
* @type {module:zrender/Element}
*/
this._backgroundEl;
/**
* If first rendering, `contentGroup.position` is [0, 0], which
* does not make sense and may cause unexepcted animation if adopted.
* @private
* @type {boolean}
*/
this._isFirstRender = true;
},
/**
......@@ -64,6 +72,8 @@ export default echarts.extendComponentView({
* @override
*/
render: function (legendModel, ecModel, api) {
var isFirstRender = this._isFirstRender;
this._isFirstRender = false;
this.resetInner();
......@@ -87,7 +97,8 @@ export default echarts.extendComponentView({
var padding = legendModel.get('padding');
var maxSize = layoutUtil.getLayoutRect(positionInfo, viewportSize, padding);
var mainRect = this.layoutInner(legendModel, itemAlign, maxSize);
var mainRect = this.layoutInner(legendModel, itemAlign, maxSize, isFirstRender);
// Place mainGroup, based on the calculated `mainRect`.
var layoutRect = layoutUtil.getLayoutRect(
......@@ -353,6 +364,14 @@ export default echarts.extendComponentView({
contentGroup.attr('position', [-contentRect.x, -contentRect.y]);
return this.group.getBoundingRect();
},
/**
* @protected
*/
remove: function () {
this.getContentGroup().removeAll();
this._isFirstRender = true;
}
});
......
......@@ -89,6 +89,8 @@ var ScrollableLegendView = LegendView.extend({
var controllerGroup = this._controllerGroup;
// FIXME: support be 'auto' adapt to size number text length,
// e.g., '3/12345' should not overlap with the control arrow button.
var pageIconSize = legendModel.get('pageIconSize', true);
if (!zrUtil.isArray(pageIconSize)) {
pageIconSize = [pageIconSize, pageIconSize];
......@@ -136,7 +138,7 @@ var ScrollableLegendView = LegendView.extend({
/**
* @override
*/
layoutInner: function (legendModel, itemAlign, maxSize) {
layoutInner: function (legendModel, itemAlign, maxSize, isFirstRender) {
var contentGroup = this.getContentGroup();
var containerGroup = this._containerGroup;
var controllerGroup = this._controllerGroup;
......@@ -168,7 +170,11 @@ var ScrollableLegendView = LegendView.extend({
var contentPos = [-contentRect.x, -contentRect.y];
// Remain contentPos when scroll animation perfroming.
contentPos[orientIdx] = contentGroup.position[orientIdx];
// If first rendering, `contentGroup.position` is [0, 0], which
// does not make sense and may cause unexepcted animation if adopted.
if (!isFirstRender) {
contentPos[orientIdx] = contentGroup.position[orientIdx];
}
// Layout container group based on 0.
var containerPos = [0, 0];
......@@ -292,106 +298,134 @@ var ScrollableLegendView = LegendView.extend({
* }
*/
_getPageInfo: function (legendModel) {
// Align left or top by the current dataIndex.
var currDataIndex = legendModel.get('scrollDataIndex', true);
var scrollDataIndex = legendModel.get('scrollDataIndex', true);
var contentGroup = this.getContentGroup();
var contentRect = contentGroup.getBoundingRect();
var containerRectSize = this._containerGroup.__rectSize;
var orientIdx = legendModel.getOrient().index;
var wh = WH[orientIdx];
var hw = WH[1 - orientIdx];
var xy = XY[orientIdx];
var contentPos = contentGroup.position.slice();
var pageIndex;
var pagePrevDataIndex;
var pageNextDataIndex;
var targetItemIndex = this._findTargetItemIndex(scrollDataIndex);
var children = contentGroup.children();
var targetItem = children[targetItemIndex];
var itemCount = children.length;
var pCount = !itemCount ? 0 : 1;
var result = {
contentPosition: contentGroup.position.slice(),
pageCount: pCount,
pageIndex: pCount - 1,
pagePrevDataIndex: null,
pageNextDataIndex: null
};
var targetItemGroup;
if (this._showController) {
contentGroup.eachChild(function (child) {
if (child.__legendDataIndex === currDataIndex) {
targetItemGroup = child;
}
});
if (!targetItem) {
return result;
}
else {
targetItemGroup = contentGroup.childAt(0);
}
var pageCount = containerRectSize ? Math.ceil(contentRect[wh] / containerRectSize) : 0;
if (targetItemGroup) {
var itemRect = targetItemGroup.getBoundingRect();
var itemLoc = targetItemGroup.position[orientIdx];
contentPos[orientIdx] = -itemLoc - contentRect[xy];
pageIndex = Math.floor(
pageCount * (itemLoc + itemRect[xy] + containerRectSize / 2) / contentRect[wh]
);
pageIndex = (contentRect[wh] && pageCount)
? Math.max(0, Math.min(pageCount - 1, pageIndex))
: -1;
var winRect = {x: 0, y: 0};
winRect[wh] = containerRectSize;
winRect[hw] = contentRect[hw];
winRect[xy] = -contentPos[orientIdx] - contentRect[xy];
var startIdx;
var children = contentGroup.children();
contentGroup.eachChild(function (child, index) {
var itemRect = getItemRect(child);
if (itemRect.intersect(winRect)) {
startIdx == null && (startIdx = index);
// It is user-friendly that the last item shown in the
// current window is shown at the begining of next window.
pageNextDataIndex = child.__legendDataIndex;
}
// If the last item is shown entirely, no next page.
if (index === children.length - 1
&& itemRect[xy] + itemRect[wh] <= winRect[xy] + winRect[wh]
) {
pageNextDataIndex = null;
var targetItemInfo = getItemInfo(targetItem);
result.contentPosition[orientIdx] = -targetItemInfo.s;
// Strategy:
// (1) Always align based on the left/top most item.
// (2) It is user-friendly that the last item shown in the
// current window is shown at the begining of next window.
// Otherwise if half of the last item is cut by the window,
// it will have no chance to display entirely.
// (3) Consider that item size probably be different, we
// have calculate pageIndex by size rather than item index,
// and we can not get page index directly by division.
// (4) The window is to narrow to contain more than
// one item, we should make sure that the page can be fliped.
for (var i = targetItemIndex + 1,
winStartItemInfo = targetItemInfo,
winEndItemInfo = targetItemInfo,
currItemInfo = null;
i <= itemCount;
++i
) {
currItemInfo = getItemInfo(children[i]);
if (
// Half of the last item is out of the window.
(!currItemInfo && winEndItemInfo.e > winStartItemInfo.s + containerRectSize)
// If the current item does not intersect with the window, the new page
// can be started at the current item or the last item.
|| (currItemInfo && !intersect(currItemInfo, winStartItemInfo.s))
) {
if (winEndItemInfo.i > winStartItemInfo.i) {
winStartItemInfo = winEndItemInfo;
}
});
// Always align based on the left/top most item, so the left/top most
// item in the previous window is needed to be found here.
if (startIdx != null) {
var startItem = children[startIdx];
var startRect = getItemRect(startItem);
winRect[xy] = startRect[xy] + startRect[wh] - winRect[wh];
// If the first item is shown entirely, no previous page.
if (startIdx <= 0 && startRect[xy] >= winRect[xy]) {
pagePrevDataIndex = null;
else { // e.g., when page size is smaller than item size.
winStartItemInfo = currItemInfo;
}
else {
while (startIdx > 0 && getItemRect(children[startIdx - 1]).intersect(winRect)) {
startIdx--;
if (winStartItemInfo) {
if (result.pageNextDataIndex == null) {
result.pageNextDataIndex = winStartItemInfo.i;
}
pagePrevDataIndex = children[startIdx].__legendDataIndex;
++result.pageCount;
}
}
winEndItemInfo = currItemInfo;
}
return {
contentPosition: contentPos,
pageIndex: pageIndex,
pageCount: pageCount,
pagePrevDataIndex: pagePrevDataIndex,
pageNextDataIndex: pageNextDataIndex
};
for (var i = targetItemIndex - 1,
winStartItemInfo = targetItemInfo,
winEndItemInfo = targetItemInfo,
currItemInfo = null;
i >= -1;
--i
) {
currItemInfo = getItemInfo(children[i]);
if (
// If the the end item does not intersect with the window started
// from the current item, a page can be settled.
(!currItemInfo || !intersect(winEndItemInfo, currItemInfo.s))
// e.g., when page size is smaller than item size.
&& winStartItemInfo.i < winEndItemInfo.i
) {
winEndItemInfo = winStartItemInfo;
if (result.pagePrevDataIndex == null) {
result.pagePrevDataIndex = winStartItemInfo.i;
}
++result.pageCount;
++result.pageIndex;
}
winStartItemInfo = currItemInfo;
}
function getItemRect(el) {
var itemRect = el.getBoundingRect().clone();
itemRect[xy] += el.position[orientIdx];
return itemRect;
return result;
function getItemInfo(el) {
if (el) {
var itemRect = el.getBoundingRect();
var start = itemRect[xy] + el.position[orientIdx];
return {
s: start,
e: start + itemRect[wh],
i: el.__legendDataIndex
};
}
}
function intersect(itemInfo, winStart) {
return itemInfo.e >= winStart && itemInfo.s <= winStart + containerRectSize;
}
},
_findTargetItemIndex: function (targetDataIndex) {
var index;
var contentGroup = this.getContentGroup();
if (this._showController) {
contentGroup.eachChild(function (child, idx) {
if (child.__legendDataIndex === targetDataIndex) {
index = idx;
}
});
}
else {
index = 0;
}
return index;
}
});
......
......@@ -422,16 +422,14 @@ gridProto._initCartesian = function (gridModel, ecModel, api) {
// Fix position
if (axisPosition !== 'top' && axisPosition !== 'bottom') {
// Default bottom of X
axisPosition = 'bottom';
axisPosition = axisPositionUsed[axisPosition] ? 'top' : 'bottom';
axisPosition = axisPositionUsed.bottom ? 'top' : 'bottom';
}
}
else {
// Fix position
if (axisPosition !== 'left' && axisPosition !== 'right') {
// Default left of Y
axisPosition = 'left';
axisPosition = axisPositionUsed[axisPosition] ? 'right' : 'left';
axisPosition = axisPositionUsed.left ? 'right' : 'left';
}
}
axisPositionUsed[axisPosition] = true;
......
......@@ -68,8 +68,10 @@ under the License.
<div class="chart" id="scroll-v2"></div>
<div id="legendHoverLink"></div>
<div id="multi-pie"></div>
<div id="icon-circle"></div>
<div id="only-single-item"></div>
<div id="vary-size"></div>
<script>
......@@ -932,5 +934,169 @@ under the License.
});
</script>
<script>
var chart;
var myChart;
var option;
require([
'echarts'/*, 'map/js/china' */
], function (echarts) {
var data = [];
for (var i = 0; i < 30; i++) {
data.push({name: i + '', value: Math.random()});
}
var option = {
tooltip: {
},
legend: {
type: 'scroll',
top: 10,
left: 0,
data: echarts.util.map(data, function (item) {
return {
name: item.name,
icon: 'circle'
};
})
},
series: [{
type: 'pie',
data: data
}]
};
testHelper.create(echarts, 'icon-circle', {
title: 'The first icon should not be overflow',
option: option
});
});
</script>
<script>
var chart;
var myChart;
var option;
require([
'echarts'/*, 'map/js/china' */
], function (echarts) {
var data = [];
for (var i = 0; i < 6; i++) {
data.push({name: i + '哈哈哈嘿嘿嘿', value: Math.random()});
}
var option = {
tooltip: {
},
legend: {
type: 'scroll',
top: 10,
left: 50,
width: 105,
data: echarts.util.map(data, function (item) {
return {
name: item.name,
icon: 'circle'
};
})
},
series: [{
type: 'pie',
radius: 20,
label: {show: false},
labelLine: {show: false},
data: data
}]
};
testHelper.create(echarts, 'only-single-item', {
title: 'Page up/down should be normal when only single item displayed',
option: option,
draggable: true
});
});
</script>
<script>
require([
'echarts',
], function (echarts) {
var data = [];
for (var i = 0; i < 26; i++) {
var name = '';
var nameNumber = Math.floor(Math.random() * 10);
for (var j = 0; j < nameNumber; j++) {
name += j;
}
data.push({
name: name,
value: Math.random()
});
}
var seriesInfo = makeSeries(50, 3);
var option = {
legend: [{
type: 'scroll',
itemGap: 30,
backgroundColor: 'rgba(0,100,50,0.2)'
}],
tooltip: {
},
grid: {
left: 280
},
series: {
type: 'pie',
label: {show: false},
labelLine: {show: false},
radius: 30,
data: data
}
};
testHelper.create(echarts, 'vary-size', {
option: option,
draggable: true
});
})
</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.
先完成此消息的编辑!
想要评论请 注册