@@ -3,64 +3,106 @@ class BubbleChart.Popover
33 constructor : (bubble , o ) ->
44 @bubble = bubble
55 @fillColor = o .fillColor or ' #333'
6- @textColor = o .textColor or ' #fff '
6+ @textColor = o .textColor or ' #FFF '
77 @textFont = o .textFont or ' helvetica'
88 @opacity = o .opacity or 0.8
9- @lineHeight = 20
9+ @labelSize = o .labelSize or 18
10+ @metricSize = o .metricSize or 12
1011 @last_draw = null
12+ @textDems = {}
13+ @pre = null
14+
15+ getTextDems : (context , text , size , font ) ->
16+ if not @textDems [" #{ text}#{ size}#{ font} " ]?
17+ # Width is easy
18+ context .font = " #{ size} px '#{ font} '"
19+ width = context .measureText (text).width
20+
21+ # Height is a bit tricky
22+ d = document .createElement " span"
23+ d .style .fontSize = " #{ size} px"
24+ d .style .fontFamily = font
25+ d .style .visibility = " hidden"
26+ d .textContent = text
27+ document .body .appendChild d
28+ height = d .offsetHeight
29+ document .body .removeChild d
30+ @textDems [" #{ text}#{ size}#{ font} " ] =
31+ width : width
32+ height : height
33+ @textDems [" #{ text}#{ size}#{ font} " ]
34+
35+ calculateTriangle : (base_width , height , ratio ) ->
36+ triangle =
37+ x : 0 , y : 0
38+ x2 : 0 , y2 : 0
39+ x3 : 0 , y3 : 0
1140
12- clear : (context ) ->
13- if @last_draw ?
14- context .clearRect @last_draw .x , @last_draw .y , @last_draw .w , @last_draw .h
15- @last_draw = null
41+ triangle .x -= base_width / 2
42+ triangle .x2 = triangle .x + base_width / 2
43+ triangle .x3 = triangle .x + base_width
44+
45+ if height > 0
46+ triangle .y += height - (26 * ratio)
47+ else
48+ triangle .y += height + (48 * ratio)
49+
50+ triangle .y2 = triangle .y + height
51+ triangle .y3 = triangle .y
52+
53+ triangle
1654
1755 paint : (pointer , context ) ->
1856 return unless pointer .current ?
57+ ratio = BubbleChart .getPixelRatio context
1958
20- context . font = " 17px ' #{ @textFont } ' "
21- label_measurement = context . measureText @bubble . label
22- metric_measurement = context . measureText " #{ @bubble . data } #{ @bubble . metric } "
23- lineWidth = if label_measurement . width > metric_measurement . width
24- label_measurement . width + 15
25- else
26- metric_measurement . width + 15
59+ labelSize = @labelSize
60+ metricSize = @metricSize
61+ lr_pad = 8 * ratio
62+ tb_pad = 5 * ratio
63+ triangle_width = 16 * ratio
64+ triangle_height = 8 * ratio
65+ metric_text = " #{ @bubble . data } #{ @bubble . metric } "
2766
28- labelX = pointer .current .x - 14
29- labelY = pointer .current .y - 26 - @lineHeight * 2
30- triangle =
31- x : 0 , y : 0
32- x2 : 0 , y2 : 0
33- x3 : 0 , y3 : 0
67+ l_dems = @ getTextDems context, @bubble .label , labelSize, @textFont
68+ m_dems = @ getTextDems context, metric_text, metricSize, @textFont
69+
70+ lineWidth = (Math .max (l_dems .width , m_dems .width ) + (lr_pad * 2 )) * ratio
71+ lineHeight = Math .max (l_dems .height , m_dems .height ) * ratio
72+
73+ box_height = (lineHeight * 2 ) + (tb_pad * 2 )
74+
75+ labelX = pointer .current .x - (14 * ratio)
76+ labelY = pointer .current .y - box_height - triangle_height - (tb_pad * 2 )
3477
3578 if labelY < 0
36- labelY = pointer .current .y + 26
37- triangle .y = pointer .current .y + 26
38- triangle .y3 = triangle .y - 4
79+ labelY = pointer .current .y + (40 * ratio)
80+ triangle = @ calculateTriangle (triangle_width, - triangle_height, ratio)
3981 else
40- triangle .y = pointer .current .y - 16
41- triangle .y3 = pointer .current .y - 10
82+ triangle = @ calculateTriangle (triangle_width, triangle_height, ratio)
4283
43- # triangle setup
44- triangle .x = pointer .current .x - 8
45- triangle .x2 = triangle .x + 16
46- triangle .y2 = triangle .y
47- triangle .x3 = triangle .x2 - 8
84+ triangle .x += pointer .current .x
85+ triangle .y += pointer .current .y
86+ triangle .x2 += pointer .current .x
87+ triangle .y2 += pointer .current .y
88+ triangle .x3 += pointer .current .x
89+ triangle .y3 += pointer .current .y
4890
4991 # right edge case
5092 if labelX + lineWidth > context .canvas .width
5193 labelX -= labelX + lineWidth - context .canvas .width
5294
95+ @last_draw =
96+ x : labelX
97+ y : labelY - (triangle_height)
98+ w : lineWidth + 2
99+ h : box_height + (triangle_height * 2 )
100+
53101 context .beginPath ()
54102 context .fillStyle = @fillColor
55103 context .globalAlpha = @opacity
56104
57- @last_draw =
58- x : labelX
59- y : labelY
60- w : lineWidth
61- h : @lineHeight * 2 + 10 + (triangle .y3 - triangle .y ) + 5
62-
63- context .roundedRect labelX, labelY, lineWidth, @lineHeight * 2 + 10 , 7
105+ context .roundedRect labelX, labelY, lineWidth, box_height, 7 * ratio
64106
65107 context .moveTo triangle .x , triangle .y
66108 context .lineTo triangle .x2 , triangle .y2
@@ -70,12 +112,20 @@ class BubbleChart.Popover
70112
71113 context .globalAlpha = 1
72114
115+
73116 context .fillStyle = @textColor
74- context .fillText @bubble .label , labelX + 7 , labelY + @lineHeight
117+ context .font = " #{ labelSize * ratio} px #{ @textFont } "
118+ context .fillText @bubble .label , labelX + lr_pad, labelY + lineHeight
75119
76- context .font = " 11px #{ @textFont } "
77- detailX = labelX + 7
78- detailY = labelY + @ lineHeight * 2
79- context .fillText " #{ @bubble . data } #{ @bubble . metric } " , detailX, detailY
120+ context .font = " #{ metricSize * ratio } px #{ @textFont } "
121+ detailX = labelX + lr_pad
122+ detailY = labelY + lineHeight * 2
123+ context .fillText metric_text , detailX, detailY
80124
81125 context .closePath ()
126+
127+
128+ clear : (context ) ->
129+ if @last_draw ?
130+ context .clearRect @last_draw .x , @last_draw .y , @last_draw .w , @last_draw .h
131+ @last_draw = null
0 commit comments