shop/echarts-master/test/universalTransition-multiLevelDrillDown.html
2025-05-03 23:48:15 +08:00

477 lines
19 KiB
HTML
Generated

<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="lib/simpleRequire.js"></script>
<script src="lib/config.js"></script>
<script src="lib/jquery.min.js"></script>
<script src="lib/facePrint.js"></script>
<script src="lib/testHelper.js"></script>
<!-- <script src="ut/lib/canteen.js"></script> -->
<link rel="stylesheet" href="lib/reset.css" />
</head>
<body>
<style></style>
<div id="main0"></div>
<div id="main1"></div>
<script>
window.ANIMATION_DURATION_UPDATE = 1000;
</script>
<script>
require(['echarts'], function (echarts) {
var myChart = testHelper.create(echarts, 'main0', {
title: [
'Test Case 1',
'(1) 3 levels: bar <--> bar <--> bar',
'(2) only one-series-to-one-series transitions',
'(3) groupId and childGroupID are read from encode (by dimension)'
],
height: 300
});
// level 1 (root)
const data_things = [
['Animals', 3, 'things', 'animals'],
['Fruits', 3, 'things', 'fruits'],
['Cars', 2, 'things', 'cars']
];
// level 2
const data_animals = [
['Dogs', 3, 'animals', 'dogs'],
['Cats', 4, 'animals', 'cats'],
['Birds', 3, 'animals', 'birds']
];
const data_fruits = [
['Pomes', 3, 'fruits', 'pomes'],
['Berries', 4, 'fruits', 'berries'],
['Citrus', 9, 'fruits', 'citrus']
];
const data_cars = [
['SUV', 5, 'cars', 'suv'],
['Sports', 3, 'cars', 'sports']
];
// level 3
const data_dogs = [
['Corgi', 5, 'dogs'], // the "childest" data need not to be specified a `childGroupId`
['Bulldog', 6, 'dogs'],
['Shiba Inu', 7, 'dogs']
];
const data_cats = [
['American Shorthair', 2, 'cats'],
['British Shorthair', 9, 'cats'],
['Bengal', 2, 'cats'],
['Birman', 2, 'cats']
];
const data_birds = [
['Goose', 1, 'birds'],
['Owl', 2, 'birds'],
['Eagle', 8, 'birds']
];
const data_pomes = [
['Apple', 9, 'pomes'],
['Pear', 2, 'pomes'],
['Kiwi', 1, 'pomes']
];
const data_berries = [
['Blackberries', 7, 'berries'],
['Cranberries', 2, 'berries'],
['Strawberries', 9, 'berries'],
['Grapes', 4, 'berries']
];
const data_citrus = [
['Oranges', 3, 'citrus'],
['Grapefruits', 7, 'citrus'],
['Tangerines', 8, 'citrus'],
['Lemons', 7, 'citrus'],
['Limes', 3, 'citrus'],
['Kumquats', 2, 'citrus'],
['Citrons', 3, 'citrus'],
['Tengelows', 3, 'citrus'],
['Uglifruit', 1, 'citrus']
];
const data_suv = [
['Mazda CX-30', 7, 'suv'],
['BMW X2', 7, 'suv'],
['Ford Bronco Sport', 2, 'suv'],
['Toyota RAV4', 9, 'suv'],
['Porsche Macan', 4, 'suv']
];
const data_sports = [
['Porsche 718 Cayman', 2, 'sports'],
['Porsche 911 Turbo', 2, 'sports'],
['Ferrari F8', 4, 'sports']
];
const allLevelData = [
data_things,
data_animals,
data_fruits,
data_cars,
data_dogs,
data_cats,
data_birds,
data_pomes,
data_berries,
data_citrus,
data_suv,
data_sports
];
const allOptions = {};
allLevelData.forEach((data, index) => {
// since dataItems of each data have same groupId in this
// example, we can use groupId as optionId for optionStack.
const optionId = data[0][2];
const option = {
id: optionId, // option.id is not a property of emyCharts option model, but can be accessed if we provide it
xAxis: {
type: 'category'
},
yAxis: {
minInterval: 1
},
animationDurationUpdate: ANIMATION_DURATION_UPDATE,
series: {
type: 'bar',
dimensions: ['x', 'y', 'groupId', 'childGroupId'],
encode: {
x: 'x',
y: 'y',
itemGroupId: 'groupId',
itemChildGroupId: 'childGroupId'
},
data,
universalTransition: {
enabled: true,
divideShape: 'clone'
}
},
graphic: [
{
type: 'text',
left: 50,
top: 20,
style: {
text: 'Back',
fontSize: 18,
fill: 'grey'
},
onclick: function () {
goBack();
}
}
]
};
allOptions[optionId] = option;
});
// A stack to remember previous option id
const optionStack = [];
const goForward = (optionId) => {
optionStack.push(myChart.getOption().id); // push current option id into stack.
myChart.setOption(allOptions[optionId]);
};
const goBack = () => {
if (optionStack.length === 0) {
console.log('Already in root level!');
} else {
console.log('Go back to previous level.');
myChart.setOption(allOptions[optionStack.pop()]);
}
};
option = allOptions['things']; // The initial option is the root data option
myChart.on('click', 'series', (params) => {
const dataItem = params.data;
if (dataItem[3]) {
// If current params is not belong to the "childest" data, it has data[3]
const childGroupId = dataItem[3];
// since we use groupId as optionId in this example,
// we use childGroupId as the next level optionId.
const nextOptionId = childGroupId;
goForward(nextOptionId);
}
});
option && myChart.setOption(option);
window.onresize = myChart.resize;
});
</script>
<script>
require(['echarts'], function (echarts) {
var myChart = testHelper.create(echarts, 'main1', {
title: [
'Test Case 2',
'(1) 3 levels: bar <--> pie <--> line',
'(2) only one-series-to-one-series transitions',
'(3) groupId and childGroupID are read from raw dataItem'
],
height: 300
});
// level 1 (root)
const data_orgs = [
['Org X', 15000, 'orgs', 'org_x'],
['Org Y', 10000, 'orgs', 'org_y']
];
// level 2
const data_org_x = [
['Repo X1', 8000, 'org_x', 'repo_x1'],
['Repo X2', 5000, 'org_x', 'repo_x2'],
['Repo X3', 2000, 'org_x', 'repo_x3']
];
const data_org_y = [
['Repo Y1', 7000, 'org_y', 'repo_y1'],
['Repo Y2', 3000, 'org_y', 'repo_y2']
];
// level 3
const data_repo_x1 = [
['Q1', 1500, 'repo_x1'], // the "childest" data need not to be specified a `childGroupId`
['Q2', 2000, 'repo_x1'],
['Q3', 2000, 'repo_x1'],
['Q4', 2500, 'repo_x1']
];
const data_repo_x2 = [
['Q1', 700, 'repo_x2'],
['Q2', 1000, 'repo_x2'],
['Q3', 1300, 'repo_x2'],
['Q4', 2000, 'repo_x2']
];
const data_repo_x3 = [
['Q1', 500, 'repo_x3'],
['Q2', 400, 'repo_x3'],
['Q3', 500, 'repo_x3'],
['Q4', 600, 'repo_x3']
];
const data_repo_y1 = [
['Q1', 1500, 'repo_y1'],
['Q2', 2000, 'repo_y1'],
['Q3', 2000, 'repo_y1'],
['Q4', 1500, 'repo_y1']
];
const data_repo_y2 = [
['Q1', 1000, 'repo_y2'],
['Q2', 500, 'repo_y2'],
['Q3', 900, 'repo_y2'],
['Q4', 600, 'repo_y2']
];
const barData = [data_orgs];
const pieData = [data_org_x, data_org_y];
const lineData = [data_repo_x1, data_repo_x2, data_repo_x3, data_repo_y1, data_repo_y2];
const allOptions = {};
barData.forEach((data) => {
// since dataItems of each data have same groupId in this
// example, we can use groupId as optionId for optionStack.
const optionId = data[0][2];
const option = {
id: optionId, // option.id is not a property of emyCharts option model, but can be accessed if we provide it
xAxis: {
show: true,
name: '',
type: 'category',
data: data.map((item) => item[0])
},
yAxis: {
show: true,
name: 'Git Commits',
nameLocation: 'center',
nameGap: 50,
minInterval: 1
},
tooltip: {},
animationDurationUpdate: ANIMATION_DURATION_UPDATE,
series: {
type: 'bar',
data: data.map((item) => {
return {
value: item[1],
groupId: item[2],
childGroupId: item[3]
};
}),
universalTransition: {
enabled: true,
divideShape: 'split'
}
},
graphic: [
{
type: 'text',
left: 50,
top: 20,
style: {
text: 'Back',
fontSize: 18,
fill: 'grey'
},
onclick: function () {
goBack();
}
}
]
};
allOptions[optionId] = option;
});
pieData.forEach((data) => {
// since dataItems of each data have same groupId in this
// example, we can use groupId as optionId for optionStack.
const optionId = data[0][2];
const option = {
id: optionId, // option.id is not a property of emyCharts option model, but can be accessed if we provide it
xAxis: { show: false },
yAxis: { show: false },
tooltip: {},
animationDurationUpdate: ANIMATION_DURATION_UPDATE,
series: {
type: 'pie',
data: data.map((item) => {
return {
name: item[0],
value: item[1],
groupId: item[2],
childGroupId: item[3]
};
}),
universalTransition: {
enabled: true,
divideShape: 'split'
}
},
graphic: [
{
type: 'text',
left: 50,
top: 20,
style: {
text: 'Back',
fontSize: 18,
fill: 'grey'
},
onclick: function () {
goBack();
}
}
]
};
allOptions[optionId] = option;
});
lineData.forEach((data) => {
// since dataItems of each data have same groupId in this
// example, we can use groupId as optionId for optionStack.
const optionId = data[0][2];
const option = {
id: optionId, // option.id is not a property of emyCharts option model, but can be accessed if we provide it
xAxis: {
show: true,
type: 'category',
name: optionId,
data: data.map((item) => item[0])
},
yAxis: {
show: true,
minInterval: 1
},
tooltip: {},
animationDurationUpdate: ANIMATION_DURATION_UPDATE,
series: {
type: 'line',
data: data.map((item) => {
return {
value: item[1],
groupId: item[2]
};
}),
universalTransition: {
enabled: true,
divideShape: 'split'
}
},
graphic: [
{
type: 'text',
left: 50,
top: 20,
style: {
text: 'Back',
fontSize: 18,
fill: 'grey'
},
onclick: function () {
goBack();
}
}
]
};
allOptions[optionId] = option;
});
// A stack to remember previous option id
const optionStack = [];
const goForward = (optionId) => {
optionStack.push(myChart.getOption().id); // push current option id into stack.
myChart.setOption(allOptions[optionId]);
};
const goBack = () => {
if (optionStack.length === 0) {
console.log('Already in root level!');
} else {
console.log('Go back to previous level.');
myChart.setOption(allOptions[optionStack.pop()]);
}
};
option = allOptions['orgs']; // The initial option is the root data option
myChart.on('click', 'series', (params) => {
const dataItem = params.data;
if (dataItem.childGroupId) {
const nextOptionId = dataItem.childGroupId;
goForward(nextOptionId);
}
});
option && myChart.setOption(option);
window.onresize = myChart.resize;
});
</script>
</body>
</html>