serverchart.js 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827
  1. // Copyright 2007 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Component for generating chart PNGs using Google Chart Server.
  16. *
  17. * @deprecated Google Chart Images service (the server-side component of this
  18. * class) has been deprecated. See
  19. * https://developers.google.com/chart/ for alternatives.
  20. *
  21. * @see ../demos/serverchart.html
  22. */
  23. /**
  24. * Namespace for chart functions
  25. */
  26. goog.provide('goog.ui.ServerChart');
  27. goog.provide('goog.ui.ServerChart.AxisDisplayType');
  28. goog.provide('goog.ui.ServerChart.ChartType');
  29. goog.provide('goog.ui.ServerChart.EncodingType');
  30. goog.provide('goog.ui.ServerChart.Event');
  31. goog.provide('goog.ui.ServerChart.LegendPosition');
  32. goog.provide('goog.ui.ServerChart.MaximumValue');
  33. goog.provide('goog.ui.ServerChart.MultiAxisAlignment');
  34. goog.provide('goog.ui.ServerChart.MultiAxisType');
  35. goog.provide('goog.ui.ServerChart.UriParam');
  36. goog.provide('goog.ui.ServerChart.UriTooLongEvent');
  37. goog.require('goog.Uri');
  38. goog.require('goog.array');
  39. goog.require('goog.asserts');
  40. goog.require('goog.dom.TagName');
  41. goog.require('goog.dom.safe');
  42. goog.require('goog.events.Event');
  43. goog.require('goog.string');
  44. goog.require('goog.ui.Component');
  45. /**
  46. * Will construct a chart using Google's chartserver.
  47. *
  48. * @param {goog.ui.ServerChart.ChartType} type The chart type.
  49. * @param {number=} opt_width The width of the chart.
  50. * @param {number=} opt_height The height of the chart.
  51. * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM Helper.
  52. * @param {string=} opt_uri Optional uri used to connect to the chart server, if
  53. * different than goog.ui.ServerChart.CHART_SERVER_SCHEME_INDEPENDENT_URI.
  54. * @constructor
  55. * @extends {goog.ui.Component}
  56. *
  57. * @deprecated Google Chart Server has been deprecated. See
  58. * https://developers.google.com/chart/image/ for details.
  59. * @final
  60. */
  61. goog.ui.ServerChart = function(
  62. type, opt_width, opt_height, opt_domHelper, opt_uri) {
  63. goog.ui.Component.call(this, opt_domHelper);
  64. /**
  65. * Image URI.
  66. * @type {goog.Uri}
  67. * @private
  68. */
  69. this.uri_ = new goog.Uri(
  70. opt_uri || goog.ui.ServerChart.CHART_SERVER_SCHEME_INDEPENDENT_URI);
  71. /**
  72. * Encoding method for the URI data format.
  73. * @type {goog.ui.ServerChart.EncodingType}
  74. * @private
  75. */
  76. this.encodingType_ = goog.ui.ServerChart.EncodingType.AUTOMATIC;
  77. /**
  78. * Two-dimensional array of the data sets on the chart.
  79. * @type {Array<Array<number>>}
  80. * @private
  81. */
  82. this.dataSets_ = [];
  83. /**
  84. * Colors for each data set.
  85. * @type {Array<string>}
  86. * @private
  87. */
  88. this.setColors_ = [];
  89. /**
  90. * Legend texts for each data set.
  91. * @type {Array<string>}
  92. * @private
  93. */
  94. this.setLegendTexts_ = [];
  95. /**
  96. * Labels on the X-axis.
  97. * @type {Array<string>}
  98. * @private
  99. */
  100. this.xLabels_ = [];
  101. /**
  102. * Labels on the left along the Y-axis.
  103. * @type {Array<string>}
  104. * @private
  105. */
  106. this.leftLabels_ = [];
  107. /**
  108. * Labels on the right along the Y-axis.
  109. * @type {Array<string>}
  110. * @private
  111. */
  112. this.rightLabels_ = [];
  113. /**
  114. * Axis type for each multi-axis in the chart. The indices into this array
  115. * also work as the reference index for all other multi-axis properties.
  116. * @type {Array<goog.ui.ServerChart.MultiAxisType>}
  117. * @private
  118. */
  119. this.multiAxisType_ = [];
  120. /**
  121. * Axis text for each multi-axis in the chart, indexed by the indices from
  122. * multiAxisType_ in a sparse array.
  123. * @type {Object}
  124. * @private
  125. */
  126. this.multiAxisLabelText_ = {};
  127. /**
  128. * Axis position for each multi-axis in the chart, indexed by the indices
  129. * from multiAxisType_ in a sparse array.
  130. * @type {Object}
  131. * @private
  132. */
  133. this.multiAxisLabelPosition_ = {};
  134. /**
  135. * Axis range for each multi-axis in the chart, indexed by the indices from
  136. * multiAxisType_ in a sparse array.
  137. * @type {Object}
  138. * @private
  139. */
  140. this.multiAxisRange_ = {};
  141. /**
  142. * Axis style for each multi-axis in the chart, indexed by the indices from
  143. * multiAxisType_ in a sparse array.
  144. * @type {Object}
  145. * @private
  146. */
  147. this.multiAxisLabelStyle_ = {};
  148. this.setType(type);
  149. this.setSize(opt_width, opt_height);
  150. /**
  151. * Minimum value for the chart (used for normalization). By default,
  152. * this is set to infinity, and is eventually updated to the lowest given
  153. * value in the data. The minimum value is then subtracted from all other
  154. * values. For a pie chart, subtracting the minimum value does not make
  155. * sense, so minValue_ is set to zero because 0 is the additive identity.
  156. * @type {number}
  157. * @private
  158. */
  159. this.minValue_ = this.isPieChart() ? 0 : Infinity;
  160. };
  161. goog.inherits(goog.ui.ServerChart, goog.ui.Component);
  162. /**
  163. * Base scheme-independent URI for the chart renderer.
  164. * @type {string}
  165. */
  166. goog.ui.ServerChart.CHART_SERVER_SCHEME_INDEPENDENT_URI =
  167. '//chart.googleapis.com/chart';
  168. /**
  169. * Base HTTP URI for the chart renderer.
  170. * @type {string}
  171. */
  172. goog.ui.ServerChart.CHART_SERVER_HTTP_URI = 'http://chart.googleapis.com/chart';
  173. /**
  174. * Base HTTPS URI for the chart renderer.
  175. * @type {string}
  176. */
  177. goog.ui.ServerChart.CHART_SERVER_HTTPS_URI =
  178. 'https://chart.googleapis.com/chart';
  179. /**
  180. * Base URI for the chart renderer.
  181. * @type {string}
  182. * @deprecated Use
  183. * {@link goog.ui.ServerChart.CHART_SERVER_SCHEME_INDEPENDENT_URI},
  184. * {@link goog.ui.ServerChart.CHART_SERVER_HTTP_URI} or
  185. * {@link goog.ui.ServerChart.CHART_SERVER_HTTPS_URI} instead.
  186. */
  187. goog.ui.ServerChart.CHART_SERVER_URI =
  188. goog.ui.ServerChart.CHART_SERVER_HTTP_URI;
  189. /**
  190. * The 0 - 1.0 ("fraction of the range") value to use when getMinValue() ==
  191. * getMaxValue(). This determines, for example, the vertical position
  192. * of the line in a flat line-chart.
  193. * @type {number}
  194. */
  195. goog.ui.ServerChart.DEFAULT_NORMALIZATION = 0.5;
  196. /**
  197. * The upper limit on the length of the chart image URI, after encoding.
  198. * If the URI's length equals or exceeds it, goog.ui.ServerChart.UriTooLongEvent
  199. * is dispatched on the goog.ui.ServerChart object.
  200. * @type {number}
  201. * @private
  202. */
  203. goog.ui.ServerChart.prototype.uriLengthLimit_ = 2048;
  204. /**
  205. * Number of gridlines along the X-axis.
  206. * @type {number}
  207. * @private
  208. */
  209. goog.ui.ServerChart.prototype.gridX_ = 0;
  210. /**
  211. * Number of gridlines along the Y-axis.
  212. * @type {number}
  213. * @private
  214. */
  215. goog.ui.ServerChart.prototype.gridY_ = 0;
  216. /**
  217. * Maximum value for the chart (used for normalization). The minimum is
  218. * declared in the constructor.
  219. * @type {number}
  220. * @private
  221. */
  222. goog.ui.ServerChart.prototype.maxValue_ = -Infinity;
  223. /**
  224. * Chart title.
  225. * @type {?string}
  226. * @private
  227. */
  228. goog.ui.ServerChart.prototype.title_ = null;
  229. /**
  230. * Chart title size.
  231. * @type {number}
  232. * @private
  233. */
  234. goog.ui.ServerChart.prototype.titleSize_ = 13.5;
  235. /**
  236. * Chart title color.
  237. * @type {string}
  238. * @private
  239. */
  240. goog.ui.ServerChart.prototype.titleColor_ = '333333';
  241. /**
  242. * Chart legend.
  243. * @type {Array<string>?}
  244. * @private
  245. */
  246. goog.ui.ServerChart.prototype.legend_ = null;
  247. /**
  248. * ChartServer supports using data sets to position markers. A data set
  249. * that is being used for positioning only can be made "invisible", in other
  250. * words, the caller can indicate to ChartServer that ordinary chart elements
  251. * (e.g. bars in a bar chart) should not be drawn on the data points of the
  252. * invisible data set. Such data sets must be provided at the end of the
  253. * chd parameter, and if invisible data sets are being used, the chd
  254. * parameter must indicate the number of visible data sets.
  255. * @type {?number}
  256. * @private
  257. */
  258. goog.ui.ServerChart.prototype.numVisibleDataSets_ = null;
  259. /**
  260. * Creates the DOM node (image) needed for the Chart
  261. * @override
  262. */
  263. goog.ui.ServerChart.prototype.createDom = function() {
  264. var size = this.getSize();
  265. this.setElementInternal(this.getDomHelper().createDom(goog.dom.TagName.IMG, {
  266. 'src': this.getUri(),
  267. 'class': goog.getCssName('goog-serverchart-image'),
  268. 'width': size[0],
  269. 'height': size[1]
  270. }));
  271. };
  272. /**
  273. * Decorate an image already in the DOM.
  274. * Expects the following structure:
  275. * <pre>
  276. * - img
  277. * </pre>
  278. *
  279. * @param {Element} img Image to decorate.
  280. * @override
  281. */
  282. goog.ui.ServerChart.prototype.decorateInternal = function(img) {
  283. goog.dom.safe.setImageSrc(
  284. /** @type {!HTMLImageElement} */ (img), this.getUri().toString());
  285. this.setElementInternal(img);
  286. };
  287. /**
  288. * Updates the image if any of the data or settings have changed.
  289. */
  290. goog.ui.ServerChart.prototype.updateChart = function() {
  291. if (this.getElement()) {
  292. goog.dom.safe.setImageSrc(
  293. /** @type {!HTMLImageElement} */ (this.getElement()),
  294. this.getUri().toString());
  295. }
  296. };
  297. /**
  298. * Sets the URI of the chart.
  299. *
  300. * @param {goog.Uri} uri The chart URI.
  301. */
  302. goog.ui.ServerChart.prototype.setUri = function(uri) {
  303. this.uri_ = uri;
  304. };
  305. /**
  306. * Returns the URI of the chart.
  307. *
  308. * @return {goog.Uri} The chart URI.
  309. */
  310. goog.ui.ServerChart.prototype.getUri = function() {
  311. this.computeDataString_();
  312. return this.uri_;
  313. };
  314. /**
  315. * Returns the upper limit on the length of the chart image URI, after encoding.
  316. * If the URI's length equals or exceeds it, goog.ui.ServerChart.UriTooLongEvent
  317. * is dispatched on the goog.ui.ServerChart object.
  318. *
  319. * @return {number} The chart URI length limit.
  320. */
  321. goog.ui.ServerChart.prototype.getUriLengthLimit = function() {
  322. return this.uriLengthLimit_;
  323. };
  324. /**
  325. * Sets the upper limit on the length of the chart image URI, after encoding.
  326. * If the URI's length equals or exceeds it, goog.ui.ServerChart.UriTooLongEvent
  327. * is dispatched on the goog.ui.ServerChart object.
  328. *
  329. * @param {number} uriLengthLimit The chart URI length limit.
  330. */
  331. goog.ui.ServerChart.prototype.setUriLengthLimit = function(uriLengthLimit) {
  332. this.uriLengthLimit_ = uriLengthLimit;
  333. };
  334. /**
  335. * Sets the 'chg' parameter of the chart Uri.
  336. * This is used by various types of charts to specify Grids.
  337. *
  338. * @param {string} value Value for the 'chg' parameter in the chart Uri.
  339. */
  340. goog.ui.ServerChart.prototype.setGridParameter = function(value) {
  341. this.uri_.setParameterValue(goog.ui.ServerChart.UriParam.GRID, value);
  342. };
  343. /**
  344. * Returns the 'chg' parameter of the chart Uri.
  345. * This is used by various types of charts to specify Grids.
  346. *
  347. * @return {string|undefined} The 'chg' parameter of the chart Uri.
  348. */
  349. goog.ui.ServerChart.prototype.getGridParameter = function() {
  350. return /** @type {string} */ (
  351. this.uri_.getParameterValue(goog.ui.ServerChart.UriParam.GRID));
  352. };
  353. /**
  354. * Sets the 'chm' parameter of the chart Uri.
  355. * This is used by various types of charts to specify Markers.
  356. *
  357. * @param {string} value Value for the 'chm' parameter in the chart Uri.
  358. */
  359. goog.ui.ServerChart.prototype.setMarkerParameter = function(value) {
  360. this.uri_.setParameterValue(goog.ui.ServerChart.UriParam.MARKERS, value);
  361. };
  362. /**
  363. * Returns the 'chm' parameter of the chart Uri.
  364. * This is used by various types of charts to specify Markers.
  365. *
  366. * @return {string|undefined} The 'chm' parameter of the chart Uri.
  367. */
  368. goog.ui.ServerChart.prototype.getMarkerParameter = function() {
  369. return /** @type {string} */ (
  370. this.uri_.getParameterValue(goog.ui.ServerChart.UriParam.MARKERS));
  371. };
  372. /**
  373. * Sets the 'chp' parameter of the chart Uri.
  374. * This is used by various types of charts to specify certain options.
  375. * e.g., finance charts use this to designate which line is the 0 axis.
  376. *
  377. * @param {string|number} value Value for the 'chp' parameter in the chart Uri.
  378. */
  379. goog.ui.ServerChart.prototype.setMiscParameter = function(value) {
  380. this.uri_.setParameterValue(
  381. goog.ui.ServerChart.UriParam.MISC_PARAMS, String(value));
  382. };
  383. /**
  384. * Returns the 'chp' parameter of the chart Uri.
  385. * This is used by various types of charts to specify certain options.
  386. * e.g., finance charts use this to designate which line is the 0 axis.
  387. *
  388. * @return {string|undefined} The 'chp' parameter of the chart Uri.
  389. */
  390. goog.ui.ServerChart.prototype.getMiscParameter = function() {
  391. return /** @type {string} */ (
  392. this.uri_.getParameterValue(goog.ui.ServerChart.UriParam.MISC_PARAMS));
  393. };
  394. /**
  395. * Enum of chart data encoding types
  396. *
  397. * @enum {string}
  398. */
  399. goog.ui.ServerChart.EncodingType = {
  400. AUTOMATIC: '',
  401. EXTENDED: 'e',
  402. SIMPLE: 's',
  403. TEXT: 't'
  404. };
  405. /**
  406. * Enum of chart types with their short names used by the chartserver.
  407. *
  408. * @enum {string}
  409. */
  410. goog.ui.ServerChart.ChartType = {
  411. BAR: 'br',
  412. CLOCK: 'cf',
  413. CONCENTRIC_PIE: 'pc',
  414. FILLEDLINE: 'lr',
  415. FINANCE: 'lfi',
  416. GOOGLEOMETER: 'gom',
  417. HORIZONTAL_GROUPED_BAR: 'bhg',
  418. HORIZONTAL_STACKED_BAR: 'bhs',
  419. LINE: 'lc',
  420. MAP: 't',
  421. MAPUSA: 'tuss',
  422. MAPWORLD: 'twoc',
  423. PIE: 'p',
  424. PIE3D: 'p3',
  425. RADAR: 'rs',
  426. SCATTER: 's',
  427. SPARKLINE: 'ls',
  428. VENN: 'v',
  429. VERTICAL_GROUPED_BAR: 'bvg',
  430. VERTICAL_STACKED_BAR: 'bvs',
  431. XYLINE: 'lxy'
  432. };
  433. /**
  434. * Enum of multi-axis types.
  435. *
  436. * @enum {string}
  437. */
  438. goog.ui.ServerChart.MultiAxisType = {
  439. X_AXIS: 'x',
  440. LEFT_Y_AXIS: 'y',
  441. RIGHT_Y_AXIS: 'r',
  442. TOP_AXIS: 't'
  443. };
  444. /**
  445. * Enum of multi-axis alignments.
  446. *
  447. * @enum {number}
  448. */
  449. goog.ui.ServerChart.MultiAxisAlignment = {
  450. ALIGN_LEFT: -1,
  451. ALIGN_CENTER: 0,
  452. ALIGN_RIGHT: 1
  453. };
  454. /**
  455. * Enum of legend positions.
  456. *
  457. * @enum {string}
  458. */
  459. goog.ui.ServerChart.LegendPosition = {
  460. TOP: 't',
  461. BOTTOM: 'b',
  462. LEFT: 'l',
  463. RIGHT: 'r'
  464. };
  465. /**
  466. * Enum of line and tick options for an axis.
  467. *
  468. * @enum {string}
  469. */
  470. goog.ui.ServerChart.AxisDisplayType = {
  471. LINE_AND_TICKS: 'lt',
  472. LINE: 'l',
  473. TICKS: 't'
  474. };
  475. /**
  476. * Enum of chart maximum values in pixels, as listed at:
  477. * http://code.google.com/apis/chart/basics.html
  478. *
  479. * @enum {number}
  480. */
  481. goog.ui.ServerChart.MaximumValue = {
  482. WIDTH: 1000,
  483. HEIGHT: 1000,
  484. MAP_WIDTH: 440,
  485. MAP_HEIGHT: 220,
  486. TOTAL_AREA: 300000
  487. };
  488. /**
  489. * Enum of ChartServer URI parameters.
  490. *
  491. * @enum {string}
  492. */
  493. goog.ui.ServerChart.UriParam = {
  494. BACKGROUND_FILL: 'chf',
  495. BAR_HEIGHT: 'chbh',
  496. DATA: 'chd',
  497. DATA_COLORS: 'chco',
  498. DATA_LABELS: 'chld',
  499. DATA_SCALING: 'chds',
  500. DIGITAL_SIGNATURE: 'sig',
  501. GEOGRAPHICAL_REGION: 'chtm',
  502. GRID: 'chg',
  503. LABEL_COLORS: 'chlc',
  504. LEFT_Y_LABELS: 'chly',
  505. LEGEND: 'chdl',
  506. LEGEND_POSITION: 'chdlp',
  507. LEGEND_TEXTS: 'chdl',
  508. LINE_STYLES: 'chls',
  509. MARGINS: 'chma',
  510. MARKERS: 'chm',
  511. MISC_PARAMS: 'chp',
  512. MULTI_AXIS_LABEL_POSITION: 'chxp',
  513. MULTI_AXIS_LABEL_TEXT: 'chxl',
  514. MULTI_AXIS_RANGE: 'chxr',
  515. MULTI_AXIS_STYLE: 'chxs',
  516. MULTI_AXIS_TYPES: 'chxt',
  517. RIGHT_LABELS: 'chlr',
  518. RIGHT_LABEL_POSITIONS: 'chlrp',
  519. SIZE: 'chs',
  520. TITLE: 'chtt',
  521. TITLE_FORMAT: 'chts',
  522. TYPE: 'cht',
  523. X_AXIS_STYLE: 'chx',
  524. X_LABELS: 'chl'
  525. };
  526. /**
  527. * Sets the background fill.
  528. *
  529. * @param {Array<Object>} fill An array of background fill specification
  530. * objects. Each object may have the following properties:
  531. * {string} area The area to fill, either 'bg' for background or 'c' for
  532. * chart area. The default is 'bg'.
  533. * {string} color (required) The color of the background fill.
  534. * // TODO(user): Add support for gradient/stripes, which requires
  535. * // a different object structure.
  536. */
  537. goog.ui.ServerChart.prototype.setBackgroundFill = function(fill) {
  538. var value = [];
  539. goog.array.forEach(fill, function(spec) {
  540. spec.area = spec.area || 'bg';
  541. spec.effect = spec.effect || 's';
  542. value.push([spec.area, spec.effect, spec.color].join(','));
  543. });
  544. value = value.join('|');
  545. this.setParameterValue(goog.ui.ServerChart.UriParam.BACKGROUND_FILL, value);
  546. };
  547. /**
  548. * Returns the background fill.
  549. *
  550. * @return {!Array<Object>} An array of background fill specifications.
  551. * If the fill specification string is in an unsupported format, the method
  552. * returns an empty array.
  553. */
  554. goog.ui.ServerChart.prototype.getBackgroundFill = function() {
  555. var value =
  556. this.uri_.getParameterValue(goog.ui.ServerChart.UriParam.BACKGROUND_FILL);
  557. var result = [];
  558. if (goog.isDefAndNotNull(value)) {
  559. var fillSpecifications = value.split('|');
  560. var valid = true;
  561. goog.array.forEach(fillSpecifications, function(spec) {
  562. var parts = spec.split(',');
  563. if (valid && parts[1] == 's') {
  564. result.push({area: parts[0], effect: parts[1], color: parts[2]});
  565. } else {
  566. // If the format is unsupported, return an empty array.
  567. result = [];
  568. valid = false;
  569. }
  570. });
  571. }
  572. return result;
  573. };
  574. /**
  575. * Sets the encoding type.
  576. *
  577. * @param {goog.ui.ServerChart.EncodingType} type Desired data encoding type.
  578. */
  579. goog.ui.ServerChart.prototype.setEncodingType = function(type) {
  580. this.encodingType_ = type;
  581. };
  582. /**
  583. * Gets the encoding type.
  584. *
  585. * @return {goog.ui.ServerChart.EncodingType} The encoding type.
  586. */
  587. goog.ui.ServerChart.prototype.getEncodingType = function() {
  588. return this.encodingType_;
  589. };
  590. /**
  591. * Sets the chart type.
  592. *
  593. * @param {goog.ui.ServerChart.ChartType} type The desired chart type.
  594. */
  595. goog.ui.ServerChart.prototype.setType = function(type) {
  596. this.uri_.setParameterValue(goog.ui.ServerChart.UriParam.TYPE, type);
  597. };
  598. /**
  599. * Returns the chart type.
  600. *
  601. * @return {goog.ui.ServerChart.ChartType} The chart type.
  602. */
  603. goog.ui.ServerChart.prototype.getType = function() {
  604. return /** @type {goog.ui.ServerChart.ChartType} */ (
  605. this.uri_.getParameterValue(goog.ui.ServerChart.UriParam.TYPE));
  606. };
  607. /**
  608. * Sets the chart size.
  609. *
  610. * @param {number=} opt_width Optional chart width, defaults to 300.
  611. * @param {number=} opt_height Optional chart height, defaults to 150.
  612. */
  613. goog.ui.ServerChart.prototype.setSize = function(opt_width, opt_height) {
  614. var sizeString = [opt_width || 300, opt_height || 150].join('x');
  615. this.uri_.setParameterValue(goog.ui.ServerChart.UriParam.SIZE, sizeString);
  616. };
  617. /**
  618. * Returns the chart size.
  619. *
  620. * @return {!Array<string>} [Width, Height].
  621. */
  622. goog.ui.ServerChart.prototype.getSize = function() {
  623. var sizeStr = this.uri_.getParameterValue(goog.ui.ServerChart.UriParam.SIZE);
  624. return sizeStr.split('x');
  625. };
  626. /**
  627. * Sets the minimum value of the chart.
  628. *
  629. * @param {number} minValue The minimum value of the chart.
  630. */
  631. goog.ui.ServerChart.prototype.setMinValue = function(minValue) {
  632. this.minValue_ = minValue;
  633. };
  634. /**
  635. * @return {number} The minimum value of the chart.
  636. */
  637. goog.ui.ServerChart.prototype.getMinValue = function() {
  638. return this.minValue_;
  639. };
  640. /**
  641. * Sets the maximum value of the chart.
  642. *
  643. * @param {number} maxValue The maximum value of the chart.
  644. */
  645. goog.ui.ServerChart.prototype.setMaxValue = function(maxValue) {
  646. this.maxValue_ = maxValue;
  647. };
  648. /**
  649. * @return {number} The maximum value of the chart.
  650. */
  651. goog.ui.ServerChart.prototype.getMaxValue = function() {
  652. return this.maxValue_;
  653. };
  654. /**
  655. * Sets the chart margins.
  656. *
  657. * @param {number} leftMargin The size in pixels of the left margin.
  658. * @param {number} rightMargin The size in pixels of the right margin.
  659. * @param {number} topMargin The size in pixels of the top margin.
  660. * @param {number} bottomMargin The size in pixels of the bottom margin.
  661. */
  662. goog.ui.ServerChart.prototype.setMargins = function(
  663. leftMargin, rightMargin, topMargin, bottomMargin) {
  664. var margins = [leftMargin, rightMargin, topMargin, bottomMargin].join(',');
  665. var UriParam = goog.ui.ServerChart.UriParam;
  666. this.uri_.setParameterValue(UriParam.MARGINS, margins);
  667. };
  668. /**
  669. * Sets the number of grid lines along the X-axis.
  670. *
  671. * @param {number} gridlines The number of X-axis grid lines.
  672. */
  673. goog.ui.ServerChart.prototype.setGridX = function(gridlines) {
  674. // Need data for this to work.
  675. this.gridX_ = gridlines;
  676. this.setGrids_(this.gridX_, this.gridY_);
  677. };
  678. /**
  679. * @return {number} The number of gridlines along the X-axis.
  680. */
  681. goog.ui.ServerChart.prototype.getGridX = function() {
  682. return this.gridX_;
  683. };
  684. /**
  685. * Sets the number of grid lines along the Y-axis.
  686. *
  687. * @param {number} gridlines The number of Y-axis grid lines.
  688. */
  689. goog.ui.ServerChart.prototype.setGridY = function(gridlines) {
  690. // Need data for this to work.
  691. this.gridY_ = gridlines;
  692. this.setGrids_(this.gridX_, this.gridY_);
  693. };
  694. /**
  695. * @return {number} The number of gridlines along the Y-axis.
  696. */
  697. goog.ui.ServerChart.prototype.getGridY = function() {
  698. return this.gridY_;
  699. };
  700. /**
  701. * Sets the grids for the chart
  702. *
  703. * @private
  704. * @param {number} x The number of grid lines along the x-axis.
  705. * @param {number} y The number of grid lines along the y-axis.
  706. */
  707. goog.ui.ServerChart.prototype.setGrids_ = function(x, y) {
  708. var gridArray = [x == 0 ? 0 : 100 / x, y == 0 ? 0 : 100 / y];
  709. this.uri_.setParameterValue(
  710. goog.ui.ServerChart.UriParam.GRID, gridArray.join(','));
  711. };
  712. /**
  713. * Sets the X Labels for the chart.
  714. *
  715. * @param {Array<string>} labels The X Labels for the chart.
  716. */
  717. goog.ui.ServerChart.prototype.setXLabels = function(labels) {
  718. this.xLabels_ = labels;
  719. this.uri_.setParameterValue(
  720. goog.ui.ServerChart.UriParam.X_LABELS, this.xLabels_.join('|'));
  721. };
  722. /**
  723. * @return {Array<string>} The X Labels for the chart.
  724. */
  725. goog.ui.ServerChart.prototype.getXLabels = function() {
  726. return this.xLabels_;
  727. };
  728. /**
  729. * @return {boolean} Whether the chart is a bar chart.
  730. */
  731. goog.ui.ServerChart.prototype.isBarChart = function() {
  732. var type = this.getType();
  733. return type == goog.ui.ServerChart.ChartType.BAR ||
  734. type == goog.ui.ServerChart.ChartType.HORIZONTAL_GROUPED_BAR ||
  735. type == goog.ui.ServerChart.ChartType.HORIZONTAL_STACKED_BAR ||
  736. type == goog.ui.ServerChart.ChartType.VERTICAL_GROUPED_BAR ||
  737. type == goog.ui.ServerChart.ChartType.VERTICAL_STACKED_BAR;
  738. };
  739. /**
  740. * @return {boolean} Whether the chart is a pie chart.
  741. */
  742. goog.ui.ServerChart.prototype.isPieChart = function() {
  743. var type = this.getType();
  744. return type == goog.ui.ServerChart.ChartType.PIE ||
  745. type == goog.ui.ServerChart.ChartType.PIE3D ||
  746. type == goog.ui.ServerChart.ChartType.CONCENTRIC_PIE;
  747. };
  748. /**
  749. * @return {boolean} Whether the chart is a grouped bar chart.
  750. */
  751. goog.ui.ServerChart.prototype.isGroupedBarChart = function() {
  752. var type = this.getType();
  753. return type == goog.ui.ServerChart.ChartType.HORIZONTAL_GROUPED_BAR ||
  754. type == goog.ui.ServerChart.ChartType.VERTICAL_GROUPED_BAR;
  755. };
  756. /**
  757. * @return {boolean} Whether the chart is a horizontal bar chart.
  758. */
  759. goog.ui.ServerChart.prototype.isHorizontalBarChart = function() {
  760. var type = this.getType();
  761. return type == goog.ui.ServerChart.ChartType.BAR ||
  762. type == goog.ui.ServerChart.ChartType.HORIZONTAL_GROUPED_BAR ||
  763. type == goog.ui.ServerChart.ChartType.HORIZONTAL_STACKED_BAR;
  764. };
  765. /**
  766. * @return {boolean} Whether the chart is a line chart.
  767. */
  768. goog.ui.ServerChart.prototype.isLineChart = function() {
  769. var type = this.getType();
  770. return type == goog.ui.ServerChart.ChartType.FILLEDLINE ||
  771. type == goog.ui.ServerChart.ChartType.LINE ||
  772. type == goog.ui.ServerChart.ChartType.SPARKLINE ||
  773. type == goog.ui.ServerChart.ChartType.XYLINE;
  774. };
  775. /**
  776. * @return {boolean} Whether the chart is a map.
  777. */
  778. goog.ui.ServerChart.prototype.isMap = function() {
  779. var type = this.getType();
  780. return type == goog.ui.ServerChart.ChartType.MAP ||
  781. type == goog.ui.ServerChart.ChartType.MAPUSA ||
  782. type == goog.ui.ServerChart.ChartType.MAPWORLD;
  783. };
  784. /**
  785. * @return {boolean} Whether the chart is a stacked bar chart.
  786. */
  787. goog.ui.ServerChart.prototype.isStackedBarChart = function() {
  788. var type = this.getType();
  789. return type == goog.ui.ServerChart.ChartType.BAR ||
  790. type == goog.ui.ServerChart.ChartType.HORIZONTAL_STACKED_BAR ||
  791. type == goog.ui.ServerChart.ChartType.VERTICAL_STACKED_BAR;
  792. };
  793. /**
  794. * @return {boolean} Whether the chart is a vertical bar chart.
  795. */
  796. goog.ui.ServerChart.prototype.isVerticalBarChart = function() {
  797. var type = this.getType();
  798. return type == goog.ui.ServerChart.ChartType.VERTICAL_GROUPED_BAR ||
  799. type == goog.ui.ServerChart.ChartType.VERTICAL_STACKED_BAR;
  800. };
  801. /**
  802. * Sets the Left Labels for the chart.
  803. * NOTE: The array should start with the lowest value, and then
  804. * move progessively up the axis. So if you want labels
  805. * from 0 to 100 with 0 at bottom of the graph, then you would
  806. * want to pass something like [0,25,50,75,100].
  807. *
  808. * @param {Array<string>} labels The Left Labels for the chart.
  809. */
  810. goog.ui.ServerChart.prototype.setLeftLabels = function(labels) {
  811. this.leftLabels_ = labels;
  812. this.uri_.setParameterValue(
  813. goog.ui.ServerChart.UriParam.LEFT_Y_LABELS,
  814. this.leftLabels_.reverse().join('|'));
  815. };
  816. /**
  817. * @return {Array<string>} The Left Labels for the chart.
  818. */
  819. goog.ui.ServerChart.prototype.getLeftLabels = function() {
  820. return this.leftLabels_;
  821. };
  822. /**
  823. * Sets the given ChartServer parameter.
  824. *
  825. * @param {goog.ui.ServerChart.UriParam} key The ChartServer parameter to set.
  826. * @param {string} value The value to set for the ChartServer parameter.
  827. */
  828. goog.ui.ServerChart.prototype.setParameterValue = function(key, value) {
  829. this.uri_.setParameterValue(key, value);
  830. };
  831. /**
  832. * Removes the given ChartServer parameter.
  833. *
  834. * @param {goog.ui.ServerChart.UriParam} key The ChartServer parameter to
  835. * remove.
  836. */
  837. goog.ui.ServerChart.prototype.removeParameter = function(key) {
  838. this.uri_.removeParameter(key);
  839. };
  840. /**
  841. * Sets the Right Labels for the chart.
  842. * NOTE: The array should start with the lowest value, and then
  843. * move progessively up the axis. So if you want labels
  844. * from 0 to 100 with 0 at bottom of the graph, then you would
  845. * want to pass something like [0,25,50,75,100].
  846. *
  847. * @param {Array<string>} labels The Right Labels for the chart.
  848. */
  849. goog.ui.ServerChart.prototype.setRightLabels = function(labels) {
  850. this.rightLabels_ = labels;
  851. this.uri_.setParameterValue(
  852. goog.ui.ServerChart.UriParam.RIGHT_LABELS,
  853. this.rightLabels_.reverse().join('|'));
  854. };
  855. /**
  856. * @return {Array<string>} The Right Labels for the chart.
  857. */
  858. goog.ui.ServerChart.prototype.getRightLabels = function() {
  859. return this.rightLabels_;
  860. };
  861. /**
  862. * Sets the position relative to the chart where the legend is to be displayed.
  863. *
  864. * @param {goog.ui.ServerChart.LegendPosition} value Legend position.
  865. */
  866. goog.ui.ServerChart.prototype.setLegendPosition = function(value) {
  867. this.uri_.setParameterValue(
  868. goog.ui.ServerChart.UriParam.LEGEND_POSITION, value);
  869. };
  870. /**
  871. * Returns the position relative to the chart where the legend is to be
  872. * displayed.
  873. *
  874. * @return {goog.ui.ServerChart.LegendPosition} Legend position.
  875. */
  876. goog.ui.ServerChart.prototype.getLegendPosition = function() {
  877. return /** @type {goog.ui.ServerChart.LegendPosition} */ (
  878. this.uri_.getParameterValue(
  879. goog.ui.ServerChart.UriParam.LEGEND_POSITION));
  880. };
  881. /**
  882. * Sets the number of "visible" data sets. All data sets that come after
  883. * the visible data set are not drawn as part of the chart. Instead, they
  884. * are available for positioning markers.
  885. * @param {?number} n The number of visible data sets, or null if all data
  886. * sets are to be visible.
  887. */
  888. goog.ui.ServerChart.prototype.setNumVisibleDataSets = function(n) {
  889. this.numVisibleDataSets_ = n;
  890. };
  891. /**
  892. * Returns the number of "visible" data sets. All data sets that come after
  893. * the visible data set are not drawn as part of the chart. Instead, they
  894. * are available for positioning markers.
  895. *
  896. * @return {?number} The number of visible data sets, or null if all data
  897. * sets are visible.
  898. */
  899. goog.ui.ServerChart.prototype.getNumVisibleDataSets = function() {
  900. return this.numVisibleDataSets_;
  901. };
  902. /**
  903. * Sets the weight function for a Venn Diagram along with the associated
  904. * colors and legend text. Weights are assigned as follows:
  905. * weights[0] is relative area of circle A.
  906. * weights[1] is relative area of circle B.
  907. * weights[2] is relative area of circle C.
  908. * weights[3] is relative area of overlap of circles A and B.
  909. * weights[4] is relative area of overlap of circles A and C.
  910. * weights[5] is relative area of overlap of circles B and C.
  911. * weights[6] is relative area of overlap of circles A, B and C.
  912. * For a two circle Venn Diagram the weights are assigned as follows:
  913. * weights[0] is relative area of circle A.
  914. * weights[1] is relative area of circle B.
  915. * weights[2] is relative area of overlap of circles A and B.
  916. *
  917. * @param {Array<number>} weights The relative weights of the circles.
  918. * @param {Array<string>=} opt_legendText The legend labels for the circles.
  919. * @param {Array<string>=} opt_colors The colors for the circles.
  920. */
  921. goog.ui.ServerChart.prototype.setVennSeries = function(
  922. weights, opt_legendText, opt_colors) {
  923. if (this.getType() != goog.ui.ServerChart.ChartType.VENN) {
  924. throw Error('Can only set a weight function for a Venn diagram.');
  925. }
  926. var dataMin = this.arrayMin_(weights);
  927. if (dataMin < this.minValue_) {
  928. this.minValue_ = dataMin;
  929. }
  930. var dataMax = this.arrayMax_(weights);
  931. if (dataMax > this.maxValue_) {
  932. this.maxValue_ = dataMax;
  933. }
  934. if (goog.isDef(opt_legendText)) {
  935. goog.array.forEach(opt_legendText, goog.bind(function(legend) {
  936. this.setLegendTexts_.push(legend);
  937. }, this));
  938. this.uri_.setParameterValue(
  939. goog.ui.ServerChart.UriParam.LEGEND_TEXTS,
  940. this.setLegendTexts_.join('|'));
  941. }
  942. // If the caller only gave three weights, then they wanted a two circle
  943. // Venn Diagram. Create a 3 circle weight function where circle C has
  944. // area zero.
  945. if (weights.length == 3) {
  946. weights[3] = weights[2];
  947. weights[2] = 0.0;
  948. }
  949. this.dataSets_.push(weights);
  950. if (goog.isDef(opt_colors)) {
  951. goog.array.forEach(opt_colors, goog.bind(function(color) {
  952. this.setColors_.push(color);
  953. }, this));
  954. this.uri_.setParameterValue(
  955. goog.ui.ServerChart.UriParam.DATA_COLORS, this.setColors_.join(','));
  956. }
  957. };
  958. /**
  959. * Sets the title of the chart.
  960. *
  961. * @param {string} title The chart title.
  962. */
  963. goog.ui.ServerChart.prototype.setTitle = function(title) {
  964. this.title_ = title;
  965. this.uri_.setParameterValue(
  966. goog.ui.ServerChart.UriParam.TITLE, this.title_.replace(/\n/g, '|'));
  967. };
  968. /**
  969. * Sets the size of the chart title.
  970. *
  971. * @param {number} size The title size, in points.
  972. */
  973. goog.ui.ServerChart.prototype.setTitleSize = function(size) {
  974. this.titleSize_ = size;
  975. this.uri_.setParameterValue(
  976. goog.ui.ServerChart.UriParam.TITLE_FORMAT,
  977. this.titleColor_ + ',' + this.titleSize_);
  978. };
  979. /**
  980. * @return {number} size The title size, in points.
  981. */
  982. goog.ui.ServerChart.prototype.getTitleSize = function() {
  983. return this.titleSize_;
  984. };
  985. /**
  986. * Sets the color of the chart title.
  987. *
  988. * NOTE: The color string should NOT have a '#' at the beginning of it.
  989. *
  990. * @param {string} color The hex value for the title color.
  991. */
  992. goog.ui.ServerChart.prototype.setTitleColor = function(color) {
  993. this.titleColor_ = color;
  994. this.uri_.setParameterValue(
  995. goog.ui.ServerChart.UriParam.TITLE_FORMAT,
  996. this.titleColor_ + ',' + this.titleSize_);
  997. };
  998. /**
  999. * @return {string} color The hex value for the title color.
  1000. */
  1001. goog.ui.ServerChart.prototype.getTitleColor = function() {
  1002. return this.titleColor_;
  1003. };
  1004. /**
  1005. * Adds a legend to the chart.
  1006. *
  1007. * @param {Array<string>} legend The legend to add.
  1008. */
  1009. goog.ui.ServerChart.prototype.setLegend = function(legend) {
  1010. this.legend_ = legend;
  1011. this.uri_.setParameterValue(
  1012. goog.ui.ServerChart.UriParam.LEGEND, this.legend_.join('|'));
  1013. };
  1014. /**
  1015. * Sets the data scaling.
  1016. * NOTE: This also changes the encoding type because data scaling will
  1017. * only work with {@code goog.ui.ServerChart.EncodingType.TEXT}
  1018. * encoding.
  1019. * @param {number} minimum The lowest number to apply to the data.
  1020. * @param {number} maximum The highest number to apply to the data.
  1021. */
  1022. goog.ui.ServerChart.prototype.setDataScaling = function(minimum, maximum) {
  1023. this.encodingType_ = goog.ui.ServerChart.EncodingType.TEXT;
  1024. this.uri_.setParameterValue(
  1025. goog.ui.ServerChart.UriParam.DATA_SCALING, minimum + ',' + maximum);
  1026. };
  1027. /**
  1028. * Sets the widths of the bars and the spaces between the bars in a bar
  1029. * chart.
  1030. * NOTE: If the space between groups is specified but the space between
  1031. * bars is left undefined, the space between groups will be interpreted
  1032. * as the space between bars because this is the behavior exposed
  1033. * in the external developers guide.
  1034. * @param {number} barWidth The width of a bar in pixels.
  1035. * @param {number=} opt_spaceBars The width of the space between
  1036. * bars in a group in pixels.
  1037. * @param {number=} opt_spaceGroups The width of the space between
  1038. * groups.
  1039. */
  1040. goog.ui.ServerChart.prototype.setBarSpaceWidths = function(
  1041. barWidth, opt_spaceBars, opt_spaceGroups) {
  1042. var widths = [barWidth];
  1043. if (goog.isDef(opt_spaceBars)) {
  1044. widths.push(opt_spaceBars);
  1045. }
  1046. if (goog.isDef(opt_spaceGroups)) {
  1047. widths.push(opt_spaceGroups);
  1048. }
  1049. this.uri_.setParameterValue(
  1050. goog.ui.ServerChart.UriParam.BAR_HEIGHT, widths.join(','));
  1051. };
  1052. /**
  1053. * Specifies that the bar width in a bar chart should be calculated
  1054. * automatically given the space available in the chart, while optionally
  1055. * setting the spaces between the bars.
  1056. * NOTE: If the space between groups is specified but the space between
  1057. * bars is left undefined, the space between groups will be interpreted
  1058. * as the space between bars because this is the behavior exposed
  1059. * in the external developers guide.
  1060. * @param {number=} opt_spaceBars The width of the space between
  1061. * bars in a group in pixels.
  1062. * @param {number=} opt_spaceGroups The width of the space between
  1063. * groups.
  1064. */
  1065. goog.ui.ServerChart.prototype.setAutomaticBarWidth = function(
  1066. opt_spaceBars, opt_spaceGroups) {
  1067. var widths = ['a'];
  1068. if (goog.isDef(opt_spaceBars)) {
  1069. widths.push(opt_spaceBars);
  1070. }
  1071. if (goog.isDef(opt_spaceGroups)) {
  1072. widths.push(opt_spaceGroups);
  1073. }
  1074. this.uri_.setParameterValue(
  1075. goog.ui.ServerChart.UriParam.BAR_HEIGHT, widths.join(','));
  1076. };
  1077. /**
  1078. * Adds a multi-axis to the chart, and sets its type. Multiple axes of the same
  1079. * type can be added.
  1080. *
  1081. * @param {goog.ui.ServerChart.MultiAxisType} axisType The desired axis type.
  1082. * @return {number} The index of the newly inserted axis, suitable for feeding
  1083. * to the setMultiAxis*() functions.
  1084. */
  1085. goog.ui.ServerChart.prototype.addMultiAxis = function(axisType) {
  1086. this.multiAxisType_.push(axisType);
  1087. this.uri_.setParameterValue(
  1088. goog.ui.ServerChart.UriParam.MULTI_AXIS_TYPES,
  1089. this.multiAxisType_.join(','));
  1090. return this.multiAxisType_.length - 1;
  1091. };
  1092. /**
  1093. * Returns the axis type for the given axis, or all of them in an array if the
  1094. * axis number is not given.
  1095. *
  1096. * @param {number=} opt_axisNumber The axis index, as returned by addMultiAxis.
  1097. * @return {goog.ui.ServerChart.MultiAxisType|
  1098. * Array<goog.ui.ServerChart.MultiAxisType>}
  1099. * The axis type for the given axis, or all of them in an array if the
  1100. * axis number is not given.
  1101. */
  1102. goog.ui.ServerChart.prototype.getMultiAxisType = function(opt_axisNumber) {
  1103. if (goog.isDef(opt_axisNumber)) {
  1104. return this.multiAxisType_[opt_axisNumber];
  1105. }
  1106. return this.multiAxisType_;
  1107. };
  1108. /**
  1109. * Sets the label text (usually multiple values) for a given axis, overwriting
  1110. * any existing values.
  1111. *
  1112. * @param {number} axisNumber The axis index, as returned by addMultiAxis.
  1113. * @param {Array<string>} labelText The actual label text to be added.
  1114. */
  1115. goog.ui.ServerChart.prototype.setMultiAxisLabelText = function(
  1116. axisNumber, labelText) {
  1117. this.multiAxisLabelText_[axisNumber] = labelText;
  1118. var axisString = this.computeMultiAxisDataString_(
  1119. this.multiAxisLabelText_, ':|', '|', '|');
  1120. this.uri_.setParameterValue(
  1121. goog.ui.ServerChart.UriParam.MULTI_AXIS_LABEL_TEXT, axisString);
  1122. };
  1123. /**
  1124. * Returns the label text, or all of them in a two-dimensional array if the
  1125. * axis number is not given.
  1126. *
  1127. * @param {number=} opt_axisNumber The axis index, as returned by addMultiAxis.
  1128. * @return {Object|Array<string>} The label text, or all of them in a
  1129. * two-dimensional array if the axis number is not given.
  1130. */
  1131. goog.ui.ServerChart.prototype.getMultiAxisLabelText = function(opt_axisNumber) {
  1132. if (goog.isDef(opt_axisNumber)) {
  1133. return this.multiAxisLabelText_[opt_axisNumber];
  1134. }
  1135. return this.multiAxisLabelText_;
  1136. };
  1137. /**
  1138. * Sets the label positions for a given axis, overwriting any existing values.
  1139. * The label positions are assumed to be floating-point numbers within the
  1140. * range of the axis.
  1141. *
  1142. * @param {number} axisNumber The axis index, as returned by addMultiAxis.
  1143. * @param {Array<number>} labelPosition The actual label positions to be added.
  1144. */
  1145. goog.ui.ServerChart.prototype.setMultiAxisLabelPosition = function(
  1146. axisNumber, labelPosition) {
  1147. this.multiAxisLabelPosition_[axisNumber] = labelPosition;
  1148. var positionString = this.computeMultiAxisDataString_(
  1149. this.multiAxisLabelPosition_, ',', ',', '|');
  1150. this.uri_.setParameterValue(
  1151. goog.ui.ServerChart.UriParam.MULTI_AXIS_LABEL_POSITION, positionString);
  1152. };
  1153. /**
  1154. * Returns the label positions for a given axis number, or all of them in a
  1155. * two-dimensional array if the axis number is not given.
  1156. *
  1157. * @param {number=} opt_axisNumber The axis index, as returned by addMultiAxis.
  1158. * @return {Object|Array<number>} The label positions for a given axis number,
  1159. * or all of them in a two-dimensional array if the axis number is not
  1160. * given.
  1161. */
  1162. goog.ui.ServerChart.prototype.getMultiAxisLabelPosition = function(
  1163. opt_axisNumber) {
  1164. if (goog.isDef(opt_axisNumber)) {
  1165. return this.multiAxisLabelPosition_[opt_axisNumber];
  1166. }
  1167. return this.multiAxisLabelPosition_;
  1168. };
  1169. /**
  1170. * Sets the label range for a given axis, overwriting any existing range.
  1171. * The default range is from 0 to 100. If the start value is larger than the
  1172. * end value, the axis direction is reversed. rangeStart and rangeEnd must
  1173. * be two different finite numbers.
  1174. *
  1175. * @param {number} axisNumber The axis index, as returned by addMultiAxis.
  1176. * @param {number} rangeStart The new start of the range.
  1177. * @param {number} rangeEnd The new end of the range.
  1178. * @param {number=} opt_interval The interval between axis labels.
  1179. */
  1180. goog.ui.ServerChart.prototype.setMultiAxisRange = function(
  1181. axisNumber, rangeStart, rangeEnd, opt_interval) {
  1182. goog.asserts.assert(
  1183. rangeStart != rangeEnd, 'Range start and end cannot be the same value.');
  1184. goog.asserts.assert(
  1185. isFinite(rangeStart) && isFinite(rangeEnd),
  1186. 'Range start and end must be finite numbers.');
  1187. this.multiAxisRange_[axisNumber] = [rangeStart, rangeEnd];
  1188. if (goog.isDef(opt_interval)) {
  1189. this.multiAxisRange_[axisNumber].push(opt_interval);
  1190. }
  1191. var rangeString =
  1192. this.computeMultiAxisDataString_(this.multiAxisRange_, ',', ',', '|');
  1193. this.uri_.setParameterValue(
  1194. goog.ui.ServerChart.UriParam.MULTI_AXIS_RANGE, rangeString);
  1195. };
  1196. /**
  1197. * Returns the label range for a given axis number as a two-element array of
  1198. * (range start, range end), or all of them in a two-dimensional array if the
  1199. * axis number is not given.
  1200. *
  1201. * @param {number=} opt_axisNumber The axis index, as returned by addMultiAxis.
  1202. * @return {Object|Array<number>} The label range for a given axis number as a
  1203. * two-element array of (range start, range end), or all of them in a
  1204. * two-dimensional array if the axis number is not given.
  1205. */
  1206. goog.ui.ServerChart.prototype.getMultiAxisRange = function(opt_axisNumber) {
  1207. if (goog.isDef(opt_axisNumber)) {
  1208. return this.multiAxisRange_[opt_axisNumber];
  1209. }
  1210. return this.multiAxisRange_;
  1211. };
  1212. /**
  1213. * Sets the label style for a given axis, overwriting any existing style.
  1214. * The default style is as follows: Default is x-axis labels are centered, left
  1215. * hand y-axis labels are right aligned, right hand y-axis labels are left
  1216. * aligned. The font size and alignment are optional parameters.
  1217. *
  1218. * NOTE: The color string should NOT have a '#' at the beginning of it.
  1219. *
  1220. * @param {number} axisNumber The axis index, as returned by addMultiAxis.
  1221. * @param {string} color The hex value for this label's color.
  1222. * @param {number=} opt_fontSize The label font size, in pixels.
  1223. * @param {goog.ui.ServerChart.MultiAxisAlignment=} opt_alignment The label
  1224. * alignment.
  1225. * @param {goog.ui.ServerChart.AxisDisplayType=} opt_axisDisplay The axis
  1226. * line and ticks.
  1227. */
  1228. goog.ui.ServerChart.prototype.setMultiAxisLabelStyle = function(
  1229. axisNumber, color, opt_fontSize, opt_alignment, opt_axisDisplay) {
  1230. var style = [color];
  1231. if (goog.isDef(opt_fontSize) || goog.isDef(opt_alignment)) {
  1232. style.push(opt_fontSize || '');
  1233. }
  1234. if (goog.isDef(opt_alignment)) {
  1235. style.push(opt_alignment);
  1236. }
  1237. if (opt_axisDisplay) {
  1238. style.push(opt_axisDisplay);
  1239. }
  1240. this.multiAxisLabelStyle_[axisNumber] = style;
  1241. var styleString = this.computeMultiAxisDataString_(
  1242. this.multiAxisLabelStyle_, ',', ',', '|');
  1243. this.uri_.setParameterValue(
  1244. goog.ui.ServerChart.UriParam.MULTI_AXIS_STYLE, styleString);
  1245. };
  1246. /**
  1247. * Returns the label style for a given axis number as a one- to three-element
  1248. * array, or all of them in a two-dimensional array if the axis number is not
  1249. * given.
  1250. *
  1251. * @param {number=} opt_axisNumber The axis index, as returned by addMultiAxis.
  1252. * @return {Object|Array<number>} The label style for a given axis number as a
  1253. * one- to three-element array, or all of them in a two-dimensional array if
  1254. * the axis number is not given.
  1255. */
  1256. goog.ui.ServerChart.prototype.getMultiAxisLabelStyle = function(
  1257. opt_axisNumber) {
  1258. if (goog.isDef(opt_axisNumber)) {
  1259. return this.multiAxisLabelStyle_[opt_axisNumber];
  1260. }
  1261. return this.multiAxisLabelStyle_;
  1262. };
  1263. /**
  1264. * Adds a data set.
  1265. * NOTE: The color string should NOT have a '#' at the beginning of it.
  1266. *
  1267. * @param {Array<?number>} data An array of numbers (values can be
  1268. * NaN or null).
  1269. * @param {string} color The hex value for this data set's color.
  1270. * @param {string=} opt_legendText The legend text, if any, for this data
  1271. * series. NOTE: If specified, all previously added data sets must also
  1272. * have a legend text.
  1273. */
  1274. goog.ui.ServerChart.prototype.addDataSet = function(
  1275. data, color, opt_legendText) {
  1276. var dataMin = this.arrayMin_(data);
  1277. if (dataMin < this.minValue_) {
  1278. this.minValue_ = dataMin;
  1279. }
  1280. var dataMax = this.arrayMax_(data);
  1281. if (dataMax > this.maxValue_) {
  1282. this.maxValue_ = dataMax;
  1283. }
  1284. if (goog.isDef(opt_legendText)) {
  1285. if (this.setLegendTexts_.length < this.dataSets_.length) {
  1286. throw Error('Cannot start adding legends text after first element.');
  1287. }
  1288. this.setLegendTexts_.push(opt_legendText);
  1289. this.uri_.setParameterValue(
  1290. goog.ui.ServerChart.UriParam.LEGEND_TEXTS,
  1291. this.setLegendTexts_.join('|'));
  1292. }
  1293. this.dataSets_.push(data);
  1294. this.setColors_.push(color);
  1295. this.uri_.setParameterValue(
  1296. goog.ui.ServerChart.UriParam.DATA_COLORS, this.setColors_.join(','));
  1297. };
  1298. /**
  1299. * Clears the data sets from the graph. All data, including the colors and
  1300. * legend text, is cleared.
  1301. */
  1302. goog.ui.ServerChart.prototype.clearDataSets = function() {
  1303. var queryData = this.uri_.getQueryData();
  1304. queryData.remove(goog.ui.ServerChart.UriParam.LEGEND_TEXTS);
  1305. queryData.remove(goog.ui.ServerChart.UriParam.DATA_COLORS);
  1306. queryData.remove(goog.ui.ServerChart.UriParam.DATA);
  1307. this.setLegendTexts_.length = 0;
  1308. this.setColors_.length = 0;
  1309. this.dataSets_.length = 0;
  1310. };
  1311. /**
  1312. * Returns the given data set or all of them in a two-dimensional array if
  1313. * the set number is not given.
  1314. *
  1315. * @param {number=} opt_setNumber Optional data set number to get.
  1316. * @return {Array<?>} The given data set or all of them in a two-dimensional
  1317. * array if the set number is not given.
  1318. */
  1319. goog.ui.ServerChart.prototype.getData = function(opt_setNumber) {
  1320. if (goog.isDef(opt_setNumber)) {
  1321. return this.dataSets_[opt_setNumber];
  1322. }
  1323. return this.dataSets_;
  1324. };
  1325. /**
  1326. * Computes the data string using the data in this.dataSets_ and sets
  1327. * the object's URI accordingly. If the URI's length equals or exceeds the
  1328. * limit, goog.ui.ServerChart.UriTooLongEvent is dispatched on the
  1329. * goog.ui.ServerChart object.
  1330. * @private
  1331. */
  1332. goog.ui.ServerChart.prototype.computeDataString_ = function() {
  1333. var ok;
  1334. if (this.encodingType_ != goog.ui.ServerChart.EncodingType.AUTOMATIC) {
  1335. ok = this.computeDataStringForEncoding_(this.encodingType_);
  1336. } else {
  1337. ok = this.computeDataStringForEncoding_(
  1338. goog.ui.ServerChart.EncodingType.EXTENDED);
  1339. if (!ok) {
  1340. ok = this.computeDataStringForEncoding_(
  1341. goog.ui.ServerChart.EncodingType.SIMPLE);
  1342. }
  1343. }
  1344. if (!ok) {
  1345. this.dispatchEvent(
  1346. new goog.ui.ServerChart.UriTooLongEvent(this.uri_.toString()));
  1347. }
  1348. };
  1349. /**
  1350. * Computes the data string using the data in this.dataSets_ and the encoding
  1351. * specified by the encoding parameter, which must not be AUTOMATIC, and sets
  1352. * the object's URI accordingly.
  1353. * @param {goog.ui.ServerChart.EncodingType} encoding The data encoding to use;
  1354. * must not be AUTOMATIC.
  1355. * @return {boolean} False if the resulting URI is too long.
  1356. * @private
  1357. */
  1358. goog.ui.ServerChart.prototype.computeDataStringForEncoding_ = function(
  1359. encoding) {
  1360. var dataStrings = [];
  1361. for (var i = 0, setLen = this.dataSets_.length; i < setLen; ++i) {
  1362. dataStrings[i] = this.getChartServerValues_(
  1363. this.dataSets_[i], this.minValue_, this.maxValue_, encoding);
  1364. }
  1365. var delimiter = encoding == goog.ui.ServerChart.EncodingType.TEXT ? '|' : ',';
  1366. dataStrings = dataStrings.join(delimiter);
  1367. var data;
  1368. if (this.numVisibleDataSets_ == null) {
  1369. data = goog.string.buildString(encoding, ':', dataStrings);
  1370. } else {
  1371. data = goog.string.buildString(
  1372. encoding, this.numVisibleDataSets_, ':', dataStrings);
  1373. }
  1374. this.uri_.setParameterValue(goog.ui.ServerChart.UriParam.DATA, data);
  1375. return this.uri_.toString().length < this.uriLengthLimit_;
  1376. };
  1377. /**
  1378. * Computes a multi-axis data string from the given data and separators. The
  1379. * general data format for each index/element in the array will be
  1380. * "<arrayIndex><indexSeparator><arrayElement.join(elementSeparator)>", with
  1381. * axisSeparator used between multiple elements.
  1382. * @param {Object} data The data to compute the data string for, as a
  1383. * sparse array of arrays. NOTE: The function uses the length of
  1384. * multiAxisType_ to determine the upper bound for the outer array.
  1385. * @param {string} indexSeparator The separator string inserted between each
  1386. * index and the data itself, commonly a comma (,).
  1387. * @param {string} elementSeparator The separator string inserted between each
  1388. * element inside each sub-array in the data, if there are more than one;
  1389. * commonly a comma (,).
  1390. * @param {string} axisSeparator The separator string inserted between each
  1391. * axis specification, if there are more than one; usually a pipe sign (|).
  1392. * @return {string} The multi-axis data string.
  1393. * @private
  1394. */
  1395. goog.ui.ServerChart.prototype.computeMultiAxisDataString_ = function(
  1396. data, indexSeparator, elementSeparator, axisSeparator) {
  1397. var elementStrings = [];
  1398. for (var i = 0, setLen = this.multiAxisType_.length; i < setLen; ++i) {
  1399. if (data[i]) {
  1400. elementStrings.push(i + indexSeparator + data[i].join(elementSeparator));
  1401. }
  1402. }
  1403. return elementStrings.join(axisSeparator);
  1404. };
  1405. /**
  1406. * Array of possible ChartServer data values
  1407. * @type {string}
  1408. */
  1409. goog.ui.ServerChart.CHART_VALUES = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
  1410. 'abcdefghijklmnopqrstuvwxyz' +
  1411. '0123456789';
  1412. /**
  1413. * Array of extended ChartServer data values
  1414. * @type {string}
  1415. */
  1416. goog.ui.ServerChart.CHART_VALUES_EXTENDED =
  1417. goog.ui.ServerChart.CHART_VALUES + '-.';
  1418. /**
  1419. * Upper bound for extended values
  1420. */
  1421. goog.ui.ServerChart.EXTENDED_UPPER_BOUND =
  1422. Math.pow(goog.ui.ServerChart.CHART_VALUES_EXTENDED.length, 2) - 1;
  1423. /**
  1424. * Converts a single number to an encoded data value suitable for ChartServer.
  1425. * The TEXT encoding is the number in decimal; the SIMPLE encoding is a single
  1426. * character, and the EXTENDED encoding is two characters. See
  1427. * https://developers.google.com/chart/image/docs/data_formats for the detailed
  1428. * specification of these encoding formats.
  1429. *
  1430. * @private
  1431. * @param {?number} value The value to convert (null for a missing data point).
  1432. * @param {number} minValue The minimum value (used for normalization).
  1433. * @param {number} maxValue The maximum value (used for normalization).
  1434. * @param {goog.ui.ServerChart.EncodingType} encoding The data encoding to use;
  1435. * must not be AUTOMATIC.
  1436. * @return {string} The encoded data value.
  1437. */
  1438. goog.ui.ServerChart.prototype.getConvertedValue_ = function(
  1439. value, minValue, maxValue, encoding) {
  1440. goog.asserts.assert(
  1441. minValue <= maxValue,
  1442. 'minValue should be less than or equal to maxValue');
  1443. var isExtended = (encoding == goog.ui.ServerChart.EncodingType.EXTENDED);
  1444. if (goog.isNull(value) || !goog.isDef(value) || isNaN(value) ||
  1445. value < minValue || value > maxValue) {
  1446. return isExtended ? '__' : '_';
  1447. }
  1448. if (encoding == goog.ui.ServerChart.EncodingType.TEXT) {
  1449. return String(value);
  1450. }
  1451. var frac = goog.ui.ServerChart.DEFAULT_NORMALIZATION;
  1452. if (maxValue > minValue) {
  1453. frac = (value - minValue) / (maxValue - minValue);
  1454. // Previous checks of value ensure that 0 <= frac <= 1 at this point.
  1455. }
  1456. if (isExtended) {
  1457. var maxIndex = goog.ui.ServerChart.CHART_VALUES_EXTENDED.length;
  1458. var upperBound = goog.ui.ServerChart.EXTENDED_UPPER_BOUND;
  1459. var index1 = Math.floor(frac * upperBound / maxIndex);
  1460. var index2 = Math.floor((frac * upperBound) % maxIndex);
  1461. var extendedVals = goog.ui.ServerChart.CHART_VALUES_EXTENDED;
  1462. return extendedVals.charAt(index1) + extendedVals.charAt(index2);
  1463. }
  1464. var index = Math.round(frac * (goog.ui.ServerChart.CHART_VALUES.length - 1));
  1465. return goog.ui.ServerChart.CHART_VALUES.charAt(index);
  1466. };
  1467. /**
  1468. * Creates the chd string for chartserver.
  1469. *
  1470. * @private
  1471. * @param {Array<number>} values An array of numbers to graph.
  1472. * @param {number} minValue The minimum value (used for normalization).
  1473. * @param {number} maxValue The maximum value (used for normalization).
  1474. * @param {goog.ui.ServerChart.EncodingType} encoding The data encoding to use;
  1475. * must not be AUTOMATIC.
  1476. * @return {string} The chd string for chartserver.
  1477. */
  1478. goog.ui.ServerChart.prototype.getChartServerValues_ = function(
  1479. values, minValue, maxValue, encoding) {
  1480. var s = [];
  1481. for (var i = 0, valuesLen = values.length; i < valuesLen; ++i) {
  1482. s.push(this.getConvertedValue_(values[i], minValue, maxValue, encoding));
  1483. }
  1484. return s.join(
  1485. this.encodingType_ == goog.ui.ServerChart.EncodingType.TEXT ? ',' : '');
  1486. };
  1487. /**
  1488. * Finds the minimum value in an array and returns it.
  1489. * Needed because Math.min does not handle sparse arrays the way we want.
  1490. *
  1491. * @param {Array<number?>} ary An array of values.
  1492. * @return {number} The minimum value.
  1493. * @private
  1494. */
  1495. goog.ui.ServerChart.prototype.arrayMin_ = function(ary) {
  1496. var min = Infinity;
  1497. for (var i = 0, aryLen = ary.length; i < aryLen; ++i) {
  1498. var value = ary[i];
  1499. if (value != null && value < min) {
  1500. min = value;
  1501. }
  1502. }
  1503. return min;
  1504. };
  1505. /**
  1506. * Finds the maximum value in an array and returns it.
  1507. * Needed because Math.max does not handle sparse arrays the way we want.
  1508. *
  1509. * @param {Array<number?>} ary An array of values.
  1510. * @return {number} The maximum value.
  1511. * @private
  1512. */
  1513. goog.ui.ServerChart.prototype.arrayMax_ = function(ary) {
  1514. var max = -Infinity;
  1515. for (var i = 0, aryLen = ary.length; i < aryLen; ++i) {
  1516. var value = ary[i];
  1517. if (value != null && value > max) {
  1518. max = value;
  1519. }
  1520. }
  1521. return max;
  1522. };
  1523. /** @override */
  1524. goog.ui.ServerChart.prototype.disposeInternal = function() {
  1525. goog.ui.ServerChart.superClass_.disposeInternal.call(this);
  1526. delete this.xLabels_;
  1527. delete this.leftLabels_;
  1528. delete this.rightLabels_;
  1529. delete this.gridX_;
  1530. delete this.gridY_;
  1531. delete this.setColors_;
  1532. delete this.setLegendTexts_;
  1533. delete this.dataSets_;
  1534. this.uri_ = null;
  1535. delete this.minValue_;
  1536. delete this.maxValue_;
  1537. this.title_ = null;
  1538. delete this.multiAxisType_;
  1539. delete this.multiAxisLabelText_;
  1540. delete this.multiAxisLabelPosition_;
  1541. delete this.multiAxisRange_;
  1542. delete this.multiAxisLabelStyle_;
  1543. this.legend_ = null;
  1544. };
  1545. /**
  1546. * Event types dispatched by the ServerChart object
  1547. * @enum {string}
  1548. */
  1549. goog.ui.ServerChart.Event = {
  1550. /**
  1551. * Dispatched when the resulting URI reaches or exceeds the URI length limit.
  1552. */
  1553. URI_TOO_LONG: 'uritoolong'
  1554. };
  1555. /**
  1556. * Class for the event dispatched on the ServerChart when the resulting URI
  1557. * exceeds the URI length limit.
  1558. * @constructor
  1559. * @param {string} uri The overly-long URI string.
  1560. * @extends {goog.events.Event}
  1561. * @final
  1562. */
  1563. goog.ui.ServerChart.UriTooLongEvent = function(uri) {
  1564. goog.events.Event.call(this, goog.ui.ServerChart.Event.URI_TOO_LONG);
  1565. /**
  1566. * The overly-long URI string.
  1567. * @type {string}
  1568. */
  1569. this.uri = uri;
  1570. };
  1571. goog.inherits(goog.ui.ServerChart.UriTooLongEvent, goog.events.Event);