빠르고 반응이 빠른 대화 형 차트 / 그래프 : SVG, Canvas, 기타?


114

기본적으로 확대 / 축소 및 이동 가능한 그래프에서 수천 개의 포인트를 렌더링하는 프로젝트를 업데이트하는 데 사용할 올바른 기술을 선택하려고합니다. Protovis를 사용하는 현재 구현은 성능이 저조합니다. 여기에서 확인하세요 :

http://www.planethunters.org/classify

완전히 축소하면 약 2000 개의 포인트가 있습니다. 하단의 핸들을 사용하여 약간 확대하고 드래그하여 이동해보세요. 컴퓨터가 정말 빠르지 않으면 매우 고르지 않고 CPU 사용량이 한 코어에서 100 %까지 올라간다는 것을 알게 될 것입니다. 초점 영역이 변경 될 때마다 프로 토비스에 다시 그리기가 필요합니다.이 작업은 상당히 느리고 더 많은 포인트를 그릴수록 더 나빠집니다.

인터페이스를 일부 업데이트하고 기본 시각화 기술을 애니메이션 및 상호 작용에 더 잘 반응하도록 변경하고 싶습니다. 다음 기사에서 다른 SVG 기반 라이브러리 또는 캔버스 기반 라이브러리 중에서 선택하는 것으로 보입니다.

http://www.sitepoint.com/how-to-choose-between-canvas-and-svg/

Protovis 에서 성장한 d3.js는 SVG 기반이며 애니메이션 렌더링에 더 적합합니다 . 그러나 나는 얼마나 더 나은지 그리고 그 성능 상한선이 무엇인지에 대해서는 모호합니다. 그런 이유로 KineticJS 와 같은 캔버스 기반 라이브러리를 사용하여보다 완전한 점검을 고려하고 있습니다 . 그러나 한 가지 접근 방식을 너무 많이 사용하기 전에이 정도의 데이터로 유사한 웹 응용 프로그램을 수행 한 사람의 의견을 듣고 의견을 듣고 싶습니다.

가장 중요한 것은 성능이며, 다른 상호 작용 기능을 쉽게 추가하고 애니메이션을 프로그래밍하는 데 중점을 둡니다. 한 번에 2,000 개 이하의 지점이있을 수 있으며 각 지점에 작은 오차 막대가 있습니다. 확대, 축소 및 이동이 부드러워 야합니다. 최신 SVG 라이브러리가 괜찮다면 d3 사용의 용이성이 KineticJS 등의 증가 된 설정보다 중요 할 것입니다. 그러나 캔버스를 사용하는 것, 특히 느린 컴퓨터를 사용하는 사람들에게 큰 성능 이점이 있다면, 저는 확실히 그런 식으로 가고 싶을 것입니다.

SVG를 사용하지만 여전히 원활하게 애니메이션되는 NYTimes에서 만든 앱의 예 : http://www.nytimes.com/interactive/2012/05/17/business/dealbook/how-the-facebook-offering-compares.html . 그 성능을 얻을 수 있고 캔버스 그리기 코드를 직접 작성할 필요가 없다면 아마도 SVG로 갈 것입니다.

일부 사용자는 캔버스 렌더링과 결합 된 d3.js 조작 의 하이브리드를 사용했습니다 . 그러나 온라인에서 이에 대한 많은 문서를 찾거나 해당 게시물의 OP에 문의 할 수 없습니다. 누구든지 이런 종류의 DOM-to-Canvas ( demo , code ) 구현에 대한 경험이 있다면 여러분의 의견도 듣고 싶습니다. 데이터를 조작 할 수 있고이를 렌더링하는 방법 (및 성능)에 대한 사용자 정의 제어를 갖는 좋은 하이브리드로 보이지만 모든 것을 DOM에로드해야하는 것이 여전히 속도를 늦출 수 있는지 궁금합니다.

이 질문과 유사한 기존 질문이 있지만 정확히 같은 질문을하는 질문은 없습니다. 당신의 도움을 주셔서 감사합니다.

후속 조치 : 내가 사용한 구현은 https://github.com/zooniverse/LightCurves에 있습니다.


"가장 중요한 것은 성능이며, 다른 상호 작용을 쉽게 추가하는 데 이차적으로 중점을 둡니다."캔버스 용 +1
philipp

문제는 대부분의 브라우저에서 2k 포인트 + 기타 차트 요소에 대해 SVG로 충분합니까? 그렇다면 속도가 느린 것은 protovis의 약점 때문이라면 SVG를 고수하고 싶습니다.
Andrew Mao

1
Mike Bostock은 이미 좋은 대답을했습니다. 몇 가지 추가 정보를 보려면 다음 두 리소스를 확인하십시오. stackoverflow.com/questions/5882716/html5-canvas-vs-svg-vs-div/… blogs.msdn.com/b/ie/archive/2011/04/22 /…
Ümit

8
후속 조치 : SVG가 축과 격자 선을 처리하고 캔버스가 점을 매우 빠르게 렌더링 할 수있는 하이브리드 SVG / 캔버스 접근 방식으로이를 구현했습니다. 초고속입니다!
Andrew Mao

답변:


183

다행히도 2,000 개의 원을 그리는 것은 테스트하기 매우 쉬운 예입니다. 따라서 가능한 네 가지 구현이 있습니다. Canvas와 SVG는 각각 두 가지입니다.

이 예제에서는 D3의 확대 / 축소 동작 을 사용하여 확대 / 축소 및 이동을 구현합니다. 이외에도 원은 캔버스 나 SVG 렌더링 여부에서, 다른 주요 차이점은 사용 여부 기하학적 또는 의미 줌.

기하학적 확대 / 축소는 전체 뷰포트에 단일 변환을 적용하는 것을 의미합니다. 확대하면 원이 더 커집니다. 의미 론적 대비 확대는 각 원에 개별적으로 변환을 적용하는 것을 의미합니다. 확대하면 원은 동일한 크기로 유지되지만 펼쳐집니다. Planethunters.org는 현재 의미 론적 확대 / 축소를 사용하지만 다른 경우를 고려하는 것이 유용 할 수 있습니다.

기하학적 확대 / 축소는 구현을 단순화합니다. 번역 및 크기 조정을 한 번 적용하면 모든 원이 다시 렌더링됩니다. SVG 구현은 특히 단순하며 단일 "transform"속성을 업데이트합니다. 두 기하학적 확대 / 축소 예제의 성능이 적절하다고 느낍니다. 시맨틱 확대 / 축소의 경우 D3가 Protovis보다 훨씬 빠르다는 것을 알 수 있습니다. 이는 각 확대 / 축소 이벤트에 대해 훨씬 적은 작업을 수행하기 때문입니다. (Protovis 버전은 모든 요소의 모든 속성을 다시 계산해야합니다.) Canvas 기반 시맨틱 확대 / 축소는 SVG보다 좀 더 기민하지만 SVG 시맨틱 확대 / 축소는 여전히 반응하는 느낌입니다.

그러나 성능에 대한 마법의 총알은 없으며이 네 가지 가능한 접근 방식이 가능성의 전체 공간을 다루기 시작하지 않습니다. 예를 들어, 패닝 ( "transform"속성 업데이트)을위한 기하학적 접근 방식을 사용하고 확대 / 축소하는 동안 개별 원만 다시 그리면 기하학적 확대 / 축소와 의미 확대를 결합 할 수 있습니다. 이러한 기술 중 하나 이상을 CSS3 변환과 결합하여 일부 하드웨어 가속을 추가 할 수도 있습니다 ( 계층 적 에지 번들링 예제에서와 같이 ). 구현하기가 까다로울 수 있고 시각적 아티팩트가 발생할 수 있습니다.

그래도 개인적으로 선호하는 것은 SVG를 최대한 많이 유지하고 렌더링이 병목 일 때 "내부 루프"에만 Canvas를 사용하는 것 입니다. SVG에는 CSS, 데이터 조인 및 요소 검사기와 같은 개발 편의성이 너무 많아 Canvas로 시작하는 것이 너무 이른 최적화 인 경우가 많습니다. 링크 한 Facebook IPO 시각화에서와 같이 Canvas와 SVG를 결합하면 이러한 편의성을 대부분 유지하면서 최상의 성능을 발휘할 수있는 유연한 방법입니다. 나는 또한 시계열 시각화의 특별한 경우가 비트 맵 캐싱에 잘 맞는 Cubism.js 에서이 기술을 사용했습니다 .

이 예제에서 알 수 있듯이 D3의 일부가 SVG에 한정되어 있더라도 Canvas와 함께 D3를 사용할 수 있습니다. 이 힘 지향 그래프충돌 감지 예제를 참조하십시오 .


와우, 그것은 멋진 대답이었습니다. 시맨틱 확대 / 축소를 고수해야한다고 생각하고 내 컴퓨터에서 캔버스 기반 렌더러는 패닝 / 확대 / 축소 할 때 SVG 버전보다 훨씬 빠릅니다 (브라우저 구현과 관련이있을 수 있습니까?). 캔버스와 함께 SVG를 내부 루프로 사용하는 것에 대해 말씀하신 내용은 정확히 제가 확인하고자했던 내용이며 코드 예제는 달콤한 보너스 일뿐입니다. 정말 고마워!
Andrew Mao

다른 브라우저에서 의미 론적 축소 예제를 시도해 보겠다고 생각했습니다. Chrome, 둘 다 꽤 빠르기 때문에 차이점을 알 수 없습니다. IE : SVG가 약간 느립니다. Firefox (마지막 의견) : SVG는 캔버스에 비해 느립니다. 나는 또한 결정을 약간 복잡하게 만들지 만 캔버스 렌더링을 안전한 선택으로 만듭니다. 한 가지 더 질문 : 캔버스 대신 KineticJS를 사용하면 성능에 직접적인 영향을 미칠까요?
Andrew Mao

1
Andrew, 조금 늦었지만 여기에 FF에 대한 나의 경험이 있습니다. 따라 잡고 있습니다. 저는 FF 15를 실행했고 D3 SVG 전환이 빠르게 느려지기 시작했습니다. 그러나 각각의 새 버전은 상당히 빨라졌습니다. 이제 저는 FF 18 베타를 사용하고 있으며 17에 비해 빠릅니다. 그래도 크롬만큼 매끄럽지 않은지 확실하지 않습니다.
user2503795 dec.

@AndrewMao 안녕하세요 Andrew, 렌더링이 병목 현상 인 것처럼 보이는 상황에 처했습니다. 일부 점과 약 6000 개의 곡선 경로를 이동 및 확대 / 축소해야합니다. stackoverflow.com/questions/17907769/svg-path-rendering-speed/… 하지만 Bostock이 "가능한 한 SVG로 유지하고"내부 루프 "에만 Canvas를 사용하십시오"라고 말했을 때 이해가되지 않습니다. 네 가지 예를 봤는데 .. 좀 알려 줄래?
kakacii jul.

@kakacii는 모든 브라우저에서 똑같이 변환이 느립니까? 그렇다면 잘못된 코드를 사용하고 있거나 브라우저 렌더링의 한계에 도달했다고 말할 수 있습니다. 코드를 게시 할 수 있다면 도움을 드릴 수 있습니다. mbostock은 조작의 단순성을 위해 SVG를 사용하고 코딩이 더 복잡하기 때문에 필요한 경우에만 캔버스를 사용하는 것을 언급했습니다. 그러나 KineticJS와 같은 라이브러리는이를 어느 정도 단순화해야합니다.
Andrew Mao

8

나는 당신의 경우 에 캔버스와 svg 사이의 결정은»말 타기«또는»포르쉐 운전»사이의 결정과 같지 않다고 생각합니다. 나에게 그것은 자동차 색상에 대한 결정과 더 비슷합니다.

설명하겠습니다 : 프레임 워크를 기반으로 운영

  • 별을 그리고
  • 별을 추가하고
  • 별을 제거하다

선형 시간이 걸립니다. 따라서 프레임 워크에 대한 결정이 좋았다면 조금 더 빠르며 그렇지 않으면 조금 더 느립니다.

계속해서 프레임 워크가 빠르다고 가정하면 성능 부족이 별의 양이 많기 때문에 발생한다는 것이 완전히 명백 해지고 프레임 워크가 여러분을 위해 할 수없는 일입니다. 적어도 저는 모르겠습니다. 이것에 대해서.

제가 말하고 싶은 것은 문제의 근원이 계산 기하학의 기본적인 문제, 즉 범위 검색 과 컴퓨터 그래픽의 또 다른 하나 인 세부 수준으로 이어진다는 것입니다 .

성능 문제를 해결하려면 표시 할 별을 매우 빠르게 찾을 수 있고 확대 / 축소에 따라 서로 가까운 별을 모을 수있는 우수한 전처리기를 구현해야합니다. 당신의 시야를 생생하고 빠르게 유지하는 유일한 방법은 그릴 별의 수를 가능한 한 적게 유지하는 것입니다.

언급했듯이 가장 중요한 것은 DOM 작업없이 작동하기 때문에 캔버스를 사용하는 경향보다 성능입니다. 또한 그래픽 성능을 크게 향상시키는 webGL을 사용할 수있는 기회를 제공합니다.

BTW : paper.js 를 확인 하셨습니까 ? 캔버스를 사용하지만 벡터 그래픽을 에뮬레이트합니다.

추신 : 이 책에서는 웹 그래픽, 캔버스의 기술, 장단점, SVG 및 DHTML에 대한 매우 상세한 논의를 찾을 수 있습니다.


7

최근에 거의 실시간 대시 보드 (5 초마다 새로 고침)에서 작업했으며 캔버스를 사용하여 렌더링하는 차트를 사용하기로 결정했습니다.

Highcharts (SVG 기반 JavaScript Charting 라이브러리)와 CanvasJS (Canvas 기반 JavaScript Charting 라이브러리)를 시도했습니다. Highcharts는 환상적인 차트 API이며 더 많은 기능을 제공하지만 CanvasJS를 사용하기로 결정했습니다.

차트 당 최소 15 분의 데이터를 표시해야했습니다 (최대 2 시간 범위 선택 옵션 포함).

따라서 15 분 동안 : 900 포인트 (초당 데이터 포인트) x2 (선 및 막대 조합 차트) x4 차트 = 총 7200 포인트.

Chrome 프로파일 러를 사용하면 CanvasJS에서는 메모리가 30MB를 넘지 않았고 Highcharts에서는 메모리 사용량이 600MB를 초과했습니다.

또한 5 초의 새로 고침 시간으로 CanvasJS 렌더링은 Highcharts보다 응답 성이 더 높습니다.

하나의 타이머 (setInterval 5 초)를 사용하여 4 개의 REST API 호출을 수행하여 Elasticsearch에 연결된 백엔드 서버에서 데이터를 가져 왔습니다. 데이터로 업데이트 된 각 차트는 JQuery.post ()에 의해 수신됩니다.

오프라인 보고서의 경우 더 유연한 API이기 때문에 Highcharts를 사용할 것입니다.

SVG 나 Canvas를 사용한다고 주장하지만 아직 보지 않은 Zing 차트도 있습니다.

성능이 정말 중요 할 때 캔버스를 고려해야합니다. 유연성을위한 SVG. 캔버스 프레임 워크가 유연하지 않다는 것은 아니지만, SVG 프레임 워크와 동일한 기능을 얻으려면 캔버스 프레임 워크에 더 많은 작업이 필요합니다.



0

또한 SVG 그래픽이있는 페이지를 PDF로 인쇄 할 때 결과 PDF에는 여전히 벡터 기반 이미지가 포함되어있는 반면 Canvas 그래픽이있는 페이지를 인쇄하면 결과 PDF 파일의 이미지가 래스터 화된다는 것을 발견했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.