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

feat(dirty-rect): Using dirty rectangles to render charts #13170

Merged
merged 4 commits into from
Oct 16, 2020
Merged

Conversation

Ovilia
Copy link
Contributor

@Ovilia Ovilia commented Aug 21, 2020

Background

With Apache ECharts (incubating), it happens that sometimes only a small part of the chart has changed (e.g. when mouse hovers on a data point in a line chart, only the circle representing the data enlarges) but the canvas has to re-paint entirely. This usually has no big problem when the data amount is not large enough (like a few hundreds of graphic elements).

But for big-data, we have to consider the frame rate if we wish to draw hundreds of thousands of elements in a single frame. This is why ECharts introduced hover layer. But hover layer has some limitations.

Problems Before

  • Layering: The hovered element isn't necessarily on top of everything else, but hover layer is always at top so the hovered element may be placed upper than some other elements by mistake.
  • Translucency: If the hovered element is translucent, the hovering style is rendered in the hover layer, while the old normal style was not cleared in the normal layer, so they are overlaid in an unexpected way.
  • Memory: It uses an extra canvas which takes extra member cost and may not be acceptable in some cases (like low priced mobile devices or when there are already many chart instances in a single page).
  • Multiple Canvases: Some platforms don't support multiple canvases, like NodeJS (on which a single image is expected to be generated) or Wechat Mini Programs.

These problems cannot be solved by hover layers due to its born nature with an extra canvas.

Dirty Rectangle

Dirty Rectangles are used extensively in computer/video game programming for fast, flicker-free double-buffer graphic updating.
From https://wiki.c2.com/?DirtyRectangles

To solve the problem hover layer brings and ensure only necessary elements are repainted each frame, we introduced the dirty rectangle technique from game programming.

The basic idea is to calculate the bounding boxes of each elements changed in a frame and clear the changed area and render elements who have intersection with those bounding boxes.

dirty-rect (1)

The rect rectangles in the above example shows the positions of calculated dirty rectangles. Only elements with intersection with those rectangles will be repainted.

Pros & Cons

This method helps most when most part of the elements are not changing in between frames while only a small part of them have changed. Typical examples that you SHOULD employ dirty-rectangle rendering are:

  • Elements style changes on hovering and there are more than thousands of graphic elements in a chart
  • A text/circle/rect/... element keeps changing color/position/opacity/... while most other elements are not changing

On the other side, if most of the elements are almost all changing overtime, it may take extra time calculating bounding box and rendering multiple times if there are multiple non-intersecting bounding boxes. So you SHOULD NOT use dirty-rectangle in those cases.

For charts with limited graphic elements, there shouldn't be noticable changes between using dirty-rectangle or not.

How to Use

The dirty-rectangle rendering is off by default. It can be enabled on init and is only useful when use 'canvas' as renderer:

var chart = echarts.init(dom, {
    useDirtyRect: true
});

Implementation

Most of the code changes happen in ZRender. So please checkout ecomfe/zrender#570 for more information.

ZRender supporting dirty rect can be found at ecomfe/zrender#570
@echarts-bot
Copy link

echarts-bot bot commented Aug 21, 2020

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.

@Ovilia Ovilia added this to the 5.0.0 milestone Aug 21, 2020
@Ovilia Ovilia changed the title feat: dirty rect feat(dirty-rect): Using dirty rectangles to render charts Aug 21, 2020
src/echarts.ts Show resolved Hide resolved
@pissang pissang merged commit 8a17180 into next Oct 16, 2020
@echarts-bot
Copy link

echarts-bot bot commented Oct 16, 2020

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

@pissang pissang deleted the dirty-rect branch October 16, 2020 08:46
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

2 participants