2010-07-02 9 views
46

내가 개발중인 웹 애플리케이션의 일부에는 막대 그래프를 만들어 다양한 정보를 표시해야합니다. 사용자의 브라우저가 가능한 경우 HTML5 canvas 요소를 사용하여 브라우저를 그릴 것이라고 생각했습니다. 그래프에는 선과 막대를 그리는 데 아무런 문제가 없지만 축, 막대 또는 선에 라벨을 붙일 때 나는 걸렸습니다. 회전 된 텍스트를 캔바스 요소 위에 그려서 레이블을 붙이는 항목과 정렬되도록하려면 어떻게해야합니까? 몇 예는 :HTML5 캔버스에서 회전 된 텍스트 그리기

  • 회전 텍스트 90도 카운터를 시계 방향
  • 회전 텍스트 90도 카운터를 Y 축 연직 막대 그래프
  • 회전 텍스트 임의 바 라벨을 시계 방향 라벨 금액은 라인 그래프의 레이블 라인

모든 포인터가 인정 될 것입니다. http://www.rgraph.net/ 당신은 자신의 방법을 리버스 엔지니어링 할 수 있습니다 .... 또한 FLOT (http://code.google.com/p/flot/) 또는 GCharts 같은 것을 고려해 볼 수 있습니다

: (http://www.maxb.net/scripts/jgcharts/include/demo/#1를) 그것은 꽤 멋진 아니다

+0

당신이 오히려 자신을 구축하는 것보다 기존의 그래프 솔루션에보고 깊이 생각 가지고, 기본적으로 0, 0입니다 ? flot (http://code.google.com/p/flot/)은 캔버스를 사용하는 한 가지 예입니다. – Bartek

답변

29

다른 사람들도 언급했듯이 기존의 그래프 솔루션을 재사용 할 수는 있지만 회전 텍스트는 그리 어렵지 않습니다.

ctx.rotate(Math.PI*2/(i*6)); 

angle is in radians을 : (나에게) 다소 혼란 비트는 전체 컨텍스트를 회전 한 다음에 그릴 수 있다는 것입니다. 코드는 taken from this example입니다. 나는 transformations part of the MDC canvas tutorial을 만들었습니다.

더 완벽한 해결 방법은 the answer below을 참조하십시오.

0

여기 사제에 HTML5 대안이다 , 완전히 후방 호환성 및 무서운 쉬운 구현.

98

유사한 문제가있는 다른 사용자를 돕기 위해 게시하는 중입니다. 컨텍스트를 저장하고, 컨텍스트를 변환하고, 컨텍스트를 회전하고, 텍스트를 그린 다음 컨텍스트를 저장된 상태로 복원하는 5 단계 접근 방식으로이 문제를 해결했습니다.

캔버스에 중첩 된 좌표 격자를 조작하는 것으로 컨텍스트로의 변환과 변환을 생각합니다. 기본적으로 원점 (0,0)은 캔버스의 왼쪽 상단 모서리에서 시작됩니다. X는 왼쪽에서 오른쪽으로 증가하고 Y는 위에서 아래로 증가합니다. 왼손에 검지와 엄지 손가락으로 "L"을 잡고 엄지 손가락을 아래로 잡고 있으면 엄지 손가락이 Y 방향으로 향하고 집게 손가락이 방향을 가리 킵니다. X가 증가했다. 나는 초등학생이라는 것을 알고 있지만, 번역과 회전을 생각할 때 도움이된다. 이유는 다음과 같습니다.

컨텍스트를 변환 할 때 좌표 격자의 원점을 캔버스의 새 위치로 이동합니다. 컨텍스트를 회전 할 때 왼손으로 만든 "L"을 원점에 대한 라디안 단위로 지정한 각도로 표시된 양만큼 시계 방향으로 회전시키는 것을 고려하십시오. strokeText 또는 fillText를 사용하는 경우 새로 정렬 된 축을 기준으로 좌표를 지정하십시오. 아래에서 위로 읽을 수 있도록 텍스트의 방향을 지정하려면 레이블을 시작하려는 위치 아래에서 -90 도로 회전하고 텍스트를 채우거나 획으로 칠하고 회전 된 x 축을 따라 각 레이블을 오프셋하는 위치로 변환하십시오.()

context.save(); 
context.translate(newx, newy); 
context.rotate(-Math.PI/2); 
context.textAlign = "center"; 
context.fillText("Your Label Here", labelXposition, 0); 
context.restore(); 

.restore을 다시는() .save를 호출 할 때이 있던 상태로 컨텍스트를 재설정 - 다시 "정상"물건을 반환 편리 : 이런 식으로 뭔가 작업을해야합니다.


+2

훌륭한 번역/회전 설명. +1 –

+6

특정 각도로 각도를 설정하려면 다음을 할 수 있습니다. 'context.rotate (angle * (Math.PI/180)); ' – PaulBGD

+0

코드 이상으로, 나는 당신의 설명을 좋아합니다. – Sorter

21

위의 답변은 이전 답변에 대한 일종의 내용이지만 약간 (희망 사항)을 추가합니다.

주로 내가 분명히 밝히고 싶은 것은 대개 draw a rectangle at 10, 3과 같은 그림을 그리는 것입니다.

이렇게 생각하면 다음과 같습니다. move origin to 10, 3, draw rectangle at 0, 0. 그 다음에 회전을 추가하면됩니다.

또 다른 중요한 점은 텍스트 정렬입니다. 0, 0에 텍스트를 그리는 것이 가장 쉽습니다. 올바른 맞춤을 사용하면 텍스트 너비를 측정하지 않고도 텍스트를 그릴 수 있습니다.

텍스트를 세로로 가운데로 가져 가려면 텍스트를 여전히 움직여야합니다. 불행히도 캔버스는 큰 선 높이를 지원하지 않으므로 짐작할 수 있습니다.

저는 포인트와 텍스트에 3 가지 맞춤을 제공하는 3 가지 예제를 작성하여 화면상의 실제 지점이 글꼴의 위치를 ​​보여줍니다. 우리가 지점 근처를 중심으로 할 텍스트를 약간 이동을 제외하고

enter image description here

var font, lineHeight, x, y; 

x = 100; 
y = 100; 
font = 20; 
lineHeight = 15; // this is guess and check as far as I know 
this.context.font = font + 'px Arial'; 


// Right Aligned 
this.context.save(); 
this.context.translate(x, y); 
this.context.rotate(-Math.PI/4); 

this.context.textAlign = 'right'; 
this.context.fillText('right', 0, lineHeight/2); 

this.context.restore(); 

this.context.fillStyle = 'red'; 
this.context.fillRect(x, y, 2, 2); 


// Center 
this.context.fillStyle = 'black'; 
x = 150; 
y = 100; 

this.context.save(); 
this.context.translate(x, y); 
this.context.rotate(-Math.PI/4); 

this.context.textAlign = 'center'; 
this.context.fillText('center', 0, lineHeight/2); 

this.context.restore(); 

this.context.fillStyle = 'red'; 
this.context.fillRect(x, y, 2, 2); 


// Left 
this.context.fillStyle = 'black'; 
x = 200; 
y = 100; 

this.context.save(); 
this.context.translate(x, y); 
this.context.rotate(-Math.PI/4); 

this.context.textAlign = 'left'; 
this.context.fillText('left', 0, lineHeight/2); 

this.context.restore(); 

this.context.fillStyle = 'red'; 
this.context.fillRect(x, y, 2, 2); 

라인 this.context.fillText('right', 0, lineHeight/2);

관련 문제