Visualforce と Google Chart の統合
Google Chart は、さまざまな視覚効果でデータを動的に表示する方法を提供します。Visualforce と組み合わせることによって、Google Chart はダッシュボードを使用するよりも高い柔軟性と配信可能性を提供できます。グラフは URL を介して生成されるため、画像を使用できるところであれば、視覚化を共有して組み込むことができます。
Google Charts API の使用には 2 つの前提条件があります。1 つ目は、データの符号化方法の決定です。Google Charts API には、テキスト、簡易、および拡張という 3 つのデータ符号化タイプがあります。この例では、簡易符号化のみを使用します。2 つ目は、使用するグラフの種類の決定です。この例では、ユーザは棒グラフと線グラフのいずれかを選択します。
カスタムコントローラには、上記の要件に対応する init() と create() という重要な関数が 2 つあります。
- 関数 init() は数値を取り、Google Chart の簡易データエンコードタイプに変換します。詳細は、Google Charts APIドキュメントの「Simple Encoding Data Format」を参照してください。
- 関数 create() は、Google Chart API に要求を行う URL を構成します。
次のコードは、Visualforce ページのコントローラを表します。
1swfobject.registerObject("clippy.codeblock-0", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/* This class contains the encoding algorithm for use with the
18 Google chartAPI. */
19
20public class GoogleDataEncoding {
21 // Exceptions to handle any erroneous data
22 public class EncodingException extends Exception {}
23 public class UnsupportedEncodingTypeException
24 extends Exception {}
25
26 /* The encoding map which takes an integer key and returns the
27 respective encoding value as defined by Google.
28 This map is initialized in init() */
29 private Map<Integer, String> encodingMap { get; set; }
30
31 /* The maximum encoding value supported for the given encoding
32 type. This value is set during init() */
33 private Integer encodingMax { get; set; }
34
35 /* The minimum encoding value supported for the given encoding
36 type. This value is set during init() */
37 private Integer encodingMin { get; set; }
38
39 /* The encoding type according to Google's API. Only SIMPLE
40 is implemented. */
41 public enum EncodingType { TEXT, SIMPLE, EXTENDED }
42
43 /* The minimum value to use in the generation of an encoding
44 value. */
45 public Integer min { get; private set; }
46
47 /* The maximum value to use in the generation of an encoding
48 value. */
49 public Integer max { get; private set; }
50
51 // The encoding type according to the API defined by Google
52 public EncodingType eType { get; private set; }
53
54 // Corresponds to the data set provided by the page
55 public String dataSet { get; set; }
56
57 // Corresponds to the type of graph selected on the page
58 public String graph { get; set; }
59
60 // The URL that renders the Google Chart
61 public String chartURL { get; set; }
62
63 // Indicates whether the chart should be displayed
64 public Boolean displayChart { get; set; }
65
66 public GoogleDataEncoding() {
67 min = 0;
68 max = 61;
69 eType = EncodingType.SIMPLE;
70 displayChart = false;
71 init();
72 }
73
74 public PageReference create() {
75 String[] dataSetList = dataSet.split(',', 0);
76 String mappedValue = 'chd=s:';
77
78 chartURL = 'http://chart.apis.google.com/chart?chs=600x300'
79 + '&chtt=Time+vs|Distance&chxt=x,y,x,y'
80 + '&chxr=0,0,10,1|1,0,65,5'
81 + '&chxl=2:|Seconds|3:|Meters';
82
83 if (graph.compareTo('barChart') == 0)
84 {
85 chartURL += '&cht=bvs';
86 }
87 else if (graph.compareTo('lineChart') == 0)
88 {
89 chartURL += '&cht=ls';
90 }
91 else
92 {
93 throw new EncodingException('An unsupported chart type'
94 + 'was selected: ' + graph + ' does not exist.');
95 }
96
97 for(String dataPoint : dataSetList)
98 {
99 mappedValue +=
100 getEncode(Integer.valueOf(dataPoint.trim()));
101 }
102
103 chartURL += '&' + mappedValue;
104 displayChart = true;
105 return null;
106 }
107
108
109 /* This method returns the encoding type parameter value that
110 matches the specified encoding type. */
111 public static String getEncodingDescriptor(EncodingType t) {
112 if(t == EncodingType.TEXT) return 't';
113 else if(t == EncodingType.SIMPLE) return 's';
114 else if(t == EncodingType.EXTENDED) return 'e';
115 else return '';
116 }
117
118 /* This method takes a given number within the declared
119 range of the encoding class and encodes it according to the
120 encoding type. If the value provided fall outside of the
121 declared range, an EncodingException is thrown. */
122 public String getEncode(Integer d) {
123 if(d > max || d < min) {
124 throw new EncodingException('Value provided ' + d
125 + ' was outside the declared min/max range ('
126 + min + '/' + max + ')');
127 }
128 else {
129 return encodingMap.get(d);
130 }
131 }
132
133 /* This method initializes the encoding map which is then
134 stored for expected repetitious use to minimize statement
135 invocation. */
136 private void init() {
137 if(eType == EncodingType.SIMPLE) {
138 encodingMax = 61;
139 encodingMin = 0;
140 encodingMap = new Map<Integer, String>();
141 encodingMap.put(0,'A');
142 encodingMap.put(1,'B');
143 encodingMap.put(2,'C');
144 encodingMap.put(3,'D');
145 encodingMap.put(4,'E');
146 encodingMap.put(5,'F');
147 encodingMap.put(6,'G');
148 encodingMap.put(7,'H');
149 encodingMap.put(8,'I');
150 encodingMap.put(9,'J');
151 encodingMap.put(10,'K');
152 encodingMap.put(11,'L');
153 encodingMap.put(12,'M');
154 encodingMap.put(13,'N');
155 encodingMap.put(14,'O');
156 encodingMap.put(15,'P');
157 encodingMap.put(16,'Q');
158 encodingMap.put(17,'R');
159 encodingMap.put(18,'S');
160 encodingMap.put(19,'T');
161 encodingMap.put(20,'U');
162 encodingMap.put(21,'V');
163 encodingMap.put(22,'W');
164 encodingMap.put(23,'X');
165 encodingMap.put(24,'Y');
166 encodingMap.put(25,'Z');
167 encodingMap.put(26,'a');
168 encodingMap.put(27,'b');
169 encodingMap.put(28,'c');
170 encodingMap.put(29,'d');
171 encodingMap.put(30,'e');
172 encodingMap.put(31,'f');
173 encodingMap.put(32,'g');
174 encodingMap.put(33,'h');
175 encodingMap.put(34,'i');
176 encodingMap.put(35,'j');
177 encodingMap.put(36,'k');
178 encodingMap.put(37,'l');
179 encodingMap.put(38,'m');
180 encodingMap.put(39,'n');
181 encodingMap.put(40,'o');
182 encodingMap.put(41,'p');
183 encodingMap.put(42,'q');
184 encodingMap.put(43,'r');
185 encodingMap.put(44,'s');
186 encodingMap.put(45,'t');
187 encodingMap.put(46,'u');
188 encodingMap.put(47,'v');
189 encodingMap.put(48,'w');
190 encodingMap.put(49,'x');
191 encodingMap.put(50,'y');
192 encodingMap.put(51,'z');
193 encodingMap.put(52,'0');
194 encodingMap.put(53,'1');
195 encodingMap.put(54,'2');
196 encodingMap.put(55,'3');
197 encodingMap.put(56,'4');
198 encodingMap.put(57,'5');
199 encodingMap.put(58,'6');
200 encodingMap.put(59,'7');
201 encodingMap.put(60,'8');
202 encodingMap.put(61,'9');
203 }
204 }
205}
Visualforce ページには 2 つの入力要素 (グラフの種類とデータセットのそれぞれに 1 つずつ) が必要です。以下は、この情報を収集するフォームを構成するサンプルページです。
1swfobject.registerObject("clippy.codeblock-1", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<apex:page controller="GoogleDataEncoding">
18 <apex:form >
19 <apex:pageBlock
20 title="Create a Google Chart for Time and Distance">
21 <apex:outputLabel
22 value="Enter data set, separated by commas: "
23 for="dataInput"/><br/>
24 <apex:inputTextArea
25 id="dataInput" title="First Data Point"
26 value="{!dataSet}" rows="3" cols="50"/><br/>
27 <apex:selectRadio value="{!graph}"
28 layout="pageDirection">
29 <apex:selectOption itemValue="barChart"
30 itemLabel="Horizontal Bar Chart"/>
31 <apex:selectOption itemValue="lineChart"
32 itemLabel="Line Chart"/>
33 </apex:selectRadio>
34 <apex:commandButton action="{!create}"
35 value="Create"/>
36 </apex:pageBlock>
37 </apex:form>
38 <apex:image url="{!chartURL}" alt="Sample chart"
39 rendered="{!displayChart}"/>
40</apex:page>