Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] animation: introduce universal transition to all series. #15208

Merged
merged 76 commits into from Jun 25, 2021

Conversation

pissang
Copy link
Contributor

@pissang pissang commented Jun 22, 2021

Brief Information

This pull request is in the type of:

  • bug fixing
  • new feature
  • others

What does this PR do?

We add shape morphing feature for custom series since 5.0 and it brings us lots of possibilities to have complex and attractive animations.
In this PR we try to take a further step to bring this feature to all type of series, not only custom series can use it now.

To enable it, we only need to add the following code to the series:

universalTransition: true

The series with the same id will have a smooth transition after setOption. We can now animate between pie, bar, funnel, scatter, etc:

basic.mp4

And the code can be as simple as

// bar chart.
chart.setOption({
  dataset: {...}
  xAxis: {},
  yAxis: {},
  series: { type: 'bar', id: 'main' }
});
// line chart.
chart.setOption({
  series: {
     type: 'line',
     // Needs id to map from old series.
     id: 'main',
     universalTransition: true
   }
});
// pie chart.
chart.setOption({
  series: {
     type: 'pie',
     // Needs id to map from old series.
     id: 'main',
     universalTransition: true
   }
}, { replaceMerge: ['xAxis', 'yAxis'] }); // Needs remove xAxis, yAxis

Multiple to multiple transitions

We can have smooth transitions when doing some data manipulate like drill-down, cluster:

Drilldown
drilldown.mp4
Cluster
cluster.mp4

I will introduce how to do multiple to multiple transitions in these drill-down, cluster cases in the next section.

Details

Install this feature

We need to import this feature manually if we do not import the whole package.

import * as echarts from 'echarts/core';
import { UniversalTransition } from 'echarts/features';
echarts.use(UniversalTransition);

Option design of universalTransition

A major new option introduced in this PR is universalTransition:

It can be a simple boolean value:

universalTransition: true

Or be an object containing more detailed configurations.

universalTransition: {
  enabled: true
  seriesKey: 'foo'
}

Full configuration interface of universalTransition:

interface UniversalTransitionOption {
    enabled?: boolean
    divideShape?: 'clone' | 'split'
    /**
     * Series will have a transition between if they have the same seriesKey.
     * Default to use series id.
     */
    seriesKey?: string | string[]
    delay: (idx: number, total: number) => number
}

Here are more detailed explanation of each item:

delay

Delay is used in combine/split animation. It can provide staggered animation.

universalTransition: {
  delay(idx, total) {
     // sequentially
     return (idx / total) * 1000; 
  }

  delay(idx, total) {
     // randomly
     return Math.random() * 1000; 
  }
}
delay.mp4

divideShape

divideShape determines how to divide the shape in the combine and split animation. For most series, it's split by default and will divide the shapes into several parts(see the previous drill-down example). But if the element is small, like in the scatter chart, we set it to 'clone'(see the previous cluster example)

seriesKey

Series with the same seriesKey will have the transition. Usually, it is a string. It can also be an array, which means it can be transit from or to multiple series with each key in this array item. For example:

If we have two set of distribution data and displayed it in male, female series respectively.

chart.setOption({
  series: [{
     type: 'bar',
     id: 'male',
     // groupId of this series is male.
     dataGroupId: 'male',
     data: ...
   }, {
     type: 'bar',
     id: 'female',
     // groupId of this series is female.
     dataGroupId: 'female',
     data: ...
   }]
});

Now if we wan't to display the percent of each gender in a pie series.

chart.setOption({
  series: [{
     type: 'pie',
     id: 'sum',
     data: [{
        // groupId of this data item is male 
        groupId: 'male',
        value: 100
     }, {
        // groupId of this data item is female
        groupId: 'female',
        value: 200
     }],
     universalTransition: {
        enabled: true,
        seriesKey: ['male', 'female']
     }
   }]
});

In this case, seriesKey use an array that means it can be transit from both male and female series.

Note:
If two series have both array seriesKey. They will be compared after concated to a string(which is order-independent). The transition between string key has higher priority.

How to use groupId.

We also introduce a new concept groupId, which is similar to id but can be shared between different data. It means which group each data item belongs to. We use it to determine how to perform combine/split transition.

We already see it's used in the above example. All bars in the male series in first option will be merged into the pie sector with the same groupId of the next option.

Besides specifying groupId in each series and data. More general usage is to specify one dimension from data to be group id:

encode: {
  itemGroupId: 'gender'
}

In this way, we can use the dimension that will be aggregated or clustered.

Breaking change between the previous API

Previously we specify transition in the setOption parameters:

setOption(option, {
    transition: {
        from: { seriesIndex, dimension },
        to: { seriesIndex, dimension }
    }
})

It can control the transition more precisely and it's more complex to use. We still keep this kind of API. But dividingMethods is dropped, use universalTransition.divideShape instead.

Also, we have morph configuration in the returned shape defines of custom series. It defaults to be true now if universalTransition is enabled. We can still disable it by setting it to false explicitly.

Other internal changes

Custom series is refactored.

Misc

Related test cases or examples to use the new APIs

More videos to show transition between different series:

Transition between heatmap, scatter with different symbols

heatmap.mp4

Transition between different hierarchy charts

Treemap, sunburst, and circle packing by custom series.

treemap.mp4

Transition between bar chart and pictorial bar chart

This one also use universalTransition.delay

pictorial.mp4

Transition between bar chart and choropleth map

map.mp4

A more real-world use case

complex.mp4

Others

Merging options

  • Please squash the commits into a single one when merge.

label layout module is included by default. it can be removed further
@echarts-bot
Copy link

echarts-bot bot commented Jun 22, 2021

Thanks for your contribution!
The community will review it ASAP. In the meanwhile, please checkout the coding standard and Wiki about How to make a pull request.

The pull request is marked to be PR: author is committer because you are a committer of this project.

Document changes are required in this PR. Please also make a PR to apache/echarts-doc for document changes and update the issue id in the PR description. When the doc PR is merged, the maintainers will remove the PR: awaiting doc label.

This PR depends on ZRender changes. Please update the ZRender dependency to the latest nightly version including this change, which takes place everyday at 8:00 UTC (16:00 Beijing Time).
You can use npm i zrender@npm:zrender-nightly to update package.json.
If you have any question about this, please leave a comment and we will give you extra help on this.

@echarts-bot echarts-bot bot added PR: author is committer PR: awaiting doc Document changes is required for this PR. PR: awaiting review labels Jun 22, 2021
@pissang pissang changed the title [feature] animation: introduce universal transition to all charts. [feature] animation: introduce universal transition to all series. Jun 22, 2021
@pissang pissang requested a review from 100pah June 22, 2021 06:02
100pah
100pah previously approved these changes Jun 24, 2021
@pissang pissang merged commit 95b549d into master Jun 25, 2021
@echarts-bot
Copy link

echarts-bot bot commented Jun 25, 2021

Congratulations! Your PR has been merged. Thanks for your contribution! 👍

@tyn1998
Copy link
Contributor

tyn1998 commented May 23, 2022

niubi! amazing!

@plainheart plainheart removed the PR: awaiting doc Document changes is required for this PR. label Jun 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants