1 2 /** 3 * @fileoverview Simple pie chart implementation. 4 * @version 1.0.1 5 * @see https://google.github.io/styleguide/jsguide.html 6 * @see https://github.com/google/closure-compiler/wiki 7 */ 8 9 10 11 /** 12 * TagChart constructor. 13 * @param {string|Element} container The HTML container. 14 * @constructor 15 * @extends {charts.BaseChart} charts.BaseChart 16 * @requires formatters.NumberFormatter 17 * @example 18 * <b>var</b> chart = <b>new</b> charts.TagChart('container_id'); 19 * chart.draw([['Country', 'Population'], 20 * ['Germany', 200], 21 * ['USA', 300], 22 * ['Brazil', 400], 23 * ['Canada', 500], 24 * ['France', 600], 25 * ['Russia', 700] 26 * ]); 27 * 28 * <div style="border: solid 1px #ccc; margin: 5px; padding: 5px; width: 560px"> 29 * <div id="chart-container" 30 * style="width: 560px; height: 300px;"></div> 31 * </div> 32 * <script src="https://greylock.js.org/greylock.js"></script> 33 * <script> 34 * var chart = new charts.TagChart('chart-container'); 35 * chart.draw([['Country', 'Population'], 36 * ['Germany', 200], 37 * ['USA', 300], 38 * ['Brazil', 400], 39 * ['Canada', 500], 40 * ['France', 600], 41 * ['Russia', 700] 42 * ]); 43 * </script> 44 */ 45 charts.TagChart = function(container) { 46 charts.BaseChart.apply(this, arguments); 47 48 /** 49 * Draws the chart based on <code>data</code> and <code>opt_options</code>. 50 * @param {!Array.<Array>} data A chart data. 51 * @param {Object=} opt_options A optional chart's configuration options. 52 * @see charts.BaseChart#getOptions 53 * @override 54 * @example 55 * options: { 56 * 'font': {'family': 'Arial'} 57 * } 58 */ 59 this.draw = function(data, opt_options) { 60 data_ = data; 61 options_ = getOptions_(opt_options); 62 self_.tooltip.setOptions(options_); 63 shuffle_(data_); 64 65 draw_(); 66 }; 67 68 /** 69 * Draws content into <code>this.container</code> as <code>innerHTML</code>. 70 * @param {string} content SVG or VML markup content. 71 * @param {number=} opt_width Optional chart width. 72 * @param {number=} opt_height Optional chart height. 73 */ 74 this.drawContent = function(content, opt_width, opt_height) { 75 opt_width = opt_width || self_.container.offsetWidth || 200; 76 opt_height = opt_height || self_.container.offsetHeight || opt_width; 77 78 self_.container.style.position = 'relative'; 79 self_.container.style.overflow = 'hidden'; 80 81 self_.container.innerHTML = content; 82 }; 83 84 // Export for closure compiler. 85 this['draw'] = this.draw; 86 87 // Export for closure compiler. 88 this['drawContent'] = this.drawContent; 89 90 /** 91 * Gets chart's options merged with defaults chart's options. 92 * @param {Object=} opt_options A optional chart's configuration options. 93 * @return {!Object.<string, *>} A map of name/value pairs. 94 * @see charts.BaseChart#getOptions 95 * @private 96 * @example 97 * options: { 98 * 'font': {'family': 'Arial'} 99 * } 100 */ 101 function getOptions_(opt_options) { 102 opt_options = opt_options || {}; 103 opt_options['font'] = opt_options['font'] || {}; 104 opt_options['font']['family'] = opt_options['font']['family'] || ''; 105 return self_.getOptions(opt_options); 106 } 107 108 /** 109 * @private 110 */ 111 function draw_() { 112 /** @type {!Array.<number>} */ var range = self_.getDataRange(data_, 1); 113 /** @type {number} */ var width = self_.container.offsetWidth || 200; 114 /** @type {number} */ var height = self_.container.offsetHeight || width; 115 /** @type {string} */ var content = '<div style="text-align: center;' + 116 ' line-height: 1.6em; padding: 10px;">'; 117 /** @type {number} */ var minValue = range[0]; 118 /** @type {number} */ var maxValue = range[1]; 119 120 for (/** @type {number} */ var i = 1; i < data_.length; i++) { 121 /** @type {string} */ var title = data_[i][0]; 122 /** @type {number} */ var value = data_[i][1]; 123 /** @type {string} */ var color = options_['colors'][i - 1]; 124 /** @type {string} */ var tooltip = '<b>' + title + '</b><br>' + 125 data_[0][1] + ': ' + value; 126 /** @type {number} */ var fontSize = Math.round( 127 (value - minValue) * 150 / maxValue) + 100; 128 129 content += '<span ' + 130 'tooltip="' + tooltip + '"' + 131 'style="' + 132 'font-size:' + fontSize + '%;' + 133 'padding: 0 3px;' + 134 'font-family:' + options_['font']['family'] + ';' + 135 'color: ' + color + 136 '">' + title + ' </span>'; 137 } 138 139 content += '</div>'; 140 141 self_.drawContent(content, width, height); 142 setTimeout(initEvents_, 100); 143 } 144 145 146 function shuffle_(array) { 147 /** @type {!Array} */ var head = array.shift(); 148 /** @type {number} */ var i = array.length; 149 while (i) { 150 /** @type {number} */ var randIndex = Math.floor(Math.random() * i--); 151 /** @type {number} */ var tmp = array[i]; 152 array[i] = array[randIndex]; 153 array[randIndex] = tmp; 154 } 155 array.unshift(head); 156 return array; 157 } 158 159 /** 160 * Initializes events handlers. 161 * @private 162 */ 163 function initEvents_() { 164 /** @type {NodeList} */ 165 var nodes = dom.getElementsByTagName(self_.container, 'SPAN'); 166 for (/** @type {number} */ var i = 0; i < nodes.length; i++) { 167 setEvents_(nodes[i]); 168 } 169 } 170 171 /** 172 * Sets events handlers. 173 * @param {!Element} node The element. 174 * @private 175 */ 176 function setEvents_(node) { 177 /** @type {string} */ var attr = 'opacity'; 178 /** @type {!Object.<string, function(Event,...)>} */ var events = {}; 179 180 events[dom.events.TYPE.MOUSEMOVE] = function(e) { 181 self_.tooltip.show(e); 182 }; 183 184 events[dom.events.TYPE.MOUSEOVER] = function(e) { 185 node.style[attr] = 1; 186 self_.tooltip.show(e); 187 }; 188 189 events[dom.events.TYPE.MOUSEOUT] = function(e) { 190 node.style[attr] = options_['opacity']; 191 self_.tooltip.hide(e); 192 }; 193 194 for (/** @type {string} */ var key in events) { 195 dom.events.addEventListener(node, key, events[key]); 196 } 197 198 events[dom.events.TYPE.MOUSEOUT](null); 199 } 200 201 /** 202 * The reference to current class instance. Used in private methods. 203 * @type {!charts.TagChart} 204 * @private 205 */ 206 var self_ = this; 207 208 /** 209 * @type {Array.<Array>} 210 * @private 211 */ 212 var data_ = null; 213 214 /** 215 * @dict 216 * @private 217 */ 218 var options_ = null; 219 220 }; 221 222 // Export for closure compiler. 223 charts['PieChart'] = charts.PieChart; 224