| <!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> |