charts.ko.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. // Licensed to Cloudera, Inc. under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. Cloudera, Inc. licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. ko.bindingHandlers.pieChart = {
  17. init: function (element, valueAccessor) {
  18. var _options = valueAccessor();
  19. var _data = _options.transformer(_options.data);
  20. nv.addGraph(function () {
  21. var _chart = nv.models.growingPieChart()
  22. .x(function (d) {
  23. return d.label
  24. })
  25. .y(function (d) {
  26. return d.value
  27. })
  28. .height($(element).width())
  29. .showLabels(true).showLegend(false);
  30. var _d3 = ($(element).find('svg').length > 0) ? d3.select($(element).find('svg')[0]) : d3.select($(element)[0]).append('svg');
  31. _d3.datum(_data)
  32. .transition().duration(150)
  33. .each("end", _options.onComplete)
  34. .call(_chart);
  35. $.each(_options.fqs(), function(cnt, item){
  36. if (item.field() == _options.field()){
  37. _chart.selectSlices(item.filter());
  38. }
  39. });
  40. nv.utils.windowResize(_chart.update);
  41. $(element).height($(element).width());
  42. return _chart;
  43. }, function () {
  44. d3.selectAll(".nv-slice").on('click',
  45. function (d, i) {
  46. _options.onClick(d);
  47. });
  48. });
  49. },
  50. update: function (element, valueAccessor) {
  51. var value = valueAccessor();
  52. // do something with the updated value
  53. }
  54. };
  55. ko.bindingHandlers.barChart = {
  56. init: function (element, valueAccessor) {
  57. barChart(element, valueAccessor(), false);
  58. },
  59. update: function (element, valueAccessor) {
  60. var value = valueAccessor();
  61. // do something with the updated value
  62. }
  63. };
  64. ko.bindingHandlers.timelineChart = {
  65. init: function (element, valueAccessor) {
  66. barChart(element, valueAccessor(), true);
  67. },
  68. update: function (element, valueAccessor) {
  69. var value = valueAccessor();
  70. // do something with the updated value
  71. }
  72. };
  73. ko.bindingHandlers.lineChart = {
  74. init: function (element, valueAccessor) {
  75. lineChart(element, valueAccessor());
  76. },
  77. update: function (element, valueAccessor) {
  78. var value = valueAccessor();
  79. // do something with the updated value
  80. }
  81. };
  82. ko.bindingHandlers.mapChart = {
  83. init: function (element, valueAccessor) {
  84. var _options = valueAccessor();
  85. $(element).css("position", "relative");
  86. $(element).css("marginLeft", "auto");
  87. $(element).css("marginRight", "auto");
  88. if (typeof _options.maxWidth != "undefined"){
  89. var _max = _options.maxWidth*1;
  90. if ($(element).width() > _max){
  91. $(element).width(_max);
  92. }
  93. }
  94. $(element).height($(element).width() / 2.23);
  95. var _data = _options.transformer(_options.data);
  96. var _maxWeight = 0;
  97. $(_data).each(function(cnt, item) {
  98. if (item.value > _maxWeight) _maxWeight = item.value;
  99. });
  100. var _chunk = _maxWeight / _data.length;
  101. var _mapdata = {};
  102. var _maphovers = {};
  103. var _fills = {};
  104. var _noncountries = [];
  105. if (_options.isScale){
  106. _fills["defaultFill"] = HueColors.LIGHT_BLUE;
  107. var _colors = HueColors.scale(HueColors.LIGHT_BLUE, HueColors.DARK_BLUE, _data.length);
  108. $(_colors).each(function(cnt, item) {
  109. _fills["fill_" + cnt] = item;
  110. });
  111. $(_data).each(function(cnt, item) {
  112. var _place = item.label;
  113. if (_place != null){
  114. _mapdata[_place] = {
  115. fillKey: "fill_" + Math.floor(item.value / _chunk),
  116. id: _place
  117. };
  118. _maphovers[_place] = item.value;
  119. }
  120. else {
  121. _noncountries.push(item);
  122. }
  123. });
  124. }
  125. else {
  126. _fills["defaultFill"] = HueColors.BLUE;
  127. _fills["selected"] = HueColors.DARK_BLUE;
  128. $(_data).each(function(cnt, item){
  129. var _place = item.label;
  130. if (_place != null){
  131. _mapdata[_place] = {
  132. fillKey: "selected",
  133. id: _place
  134. };
  135. _maphovers[_place] = item.value;
  136. }
  137. else {
  138. _noncountries.push(item);
  139. }
  140. });
  141. }
  142. var _map = null;
  143. function createDatamap(element, options, fills, mapData, nonCountries, mapHovers) {
  144. _map = new Datamap({
  145. element: element,
  146. fills: fills,
  147. scope: 'world',
  148. data: mapData,
  149. done: function(datamap) {
  150. datamap.svg.selectAll('.datamaps-subunit').on('click', function(geography) {
  151. if (typeof options.onClick != "undefined"){
  152. options.onClick(geography);
  153. }
  154. });
  155. var _bubbles = [];
  156. if (options.enableGeocoding){
  157. $(nonCountries).each(function(cnt, item){
  158. HueGeo.getCityCoordinates(item.label, function(lat, lng){
  159. _bubbles.push({
  160. fillKey: "selected",
  161. label: item.label,
  162. value: item.value,
  163. radius: 4,
  164. latitude: lat,
  165. longitude: lng
  166. });
  167. _map.bubbles(_bubbles, {
  168. popupTemplate: function(geo, data) {
  169. return '<div class="hoverinfo" style="text-align: center"><strong>' + data.label + '</strong><br/>' + item.value + '</div>'
  170. }
  171. });
  172. });
  173. });
  174. }
  175. },
  176. geographyConfig: {
  177. hideAntarctica: true,
  178. borderWidth: 1,
  179. borderColor: HueColors.DARK_BLUE,
  180. highlightOnHover: true,
  181. highlightFillColor: HueColors.DARK_BLUE,
  182. highlightBorderColor: HueColors.DARK_BLUE,
  183. popupTemplate: function(geography, data) {
  184. var _hover = '';
  185. if (data != null) {
  186. _hover = '<br/>' + mapHovers[data.id];
  187. }
  188. return '<div class="hoverinfo" style="text-align: center"><strong>' + geography.properties.name + '</strong>' + _hover + '</div>'
  189. }
  190. }
  191. });
  192. options.onComplete();
  193. }
  194. createDatamap(element, _options, _fills, _mapdata, _noncountries, _maphovers)
  195. nv.utils.windowResize(_map.update);
  196. $(element).parents(".card-widget").on("resize", function(){
  197. $(element).empty();
  198. if (typeof _options.maxWidth != "undefined"){
  199. var _max = _options.maxWidth*1;
  200. if ($(element).width() > _max){
  201. $(element).width(_max);
  202. }
  203. }
  204. $(element).height($(element).width() / 2.23);
  205. createDatamap(element, _options, _fills, _mapdata, _noncountries, _maphovers)
  206. });
  207. },
  208. update: function (element, valueAccessor) {
  209. var value = valueAccessor();
  210. // do something with the updated value
  211. }
  212. };
  213. function lineChart(element, options) {
  214. var _datum = options.transformer(options.datum);
  215. $(element).height(300);
  216. nv.addGraph(function () {
  217. var _chart = nv.models.lineWithBrushChart();
  218. _chart.onSelectRange(options.onSelectRange);
  219. _chart.xAxis
  220. .showMaxMin(true)
  221. .tickFormat(d3.format(',0f'))
  222. .transitionDuration(100);
  223. _chart.yAxis
  224. .tickFormat(d3.format(',0f'));
  225. var _d3 = ($(element).find('svg').length > 0) ? d3.select($(element).find('svg')[0]) : d3.select($(element)[0]).append('svg');
  226. _d3.datum(_datum)
  227. .transition().duration(150)
  228. .each("end", options.onComplete)
  229. .call(_chart);
  230. nv.utils.windowResize(_chart.update);
  231. return _chart;
  232. }, function () {
  233. d3.selectAll(".nv-bar").on('click',
  234. function (d, i) {
  235. options.onClick(d);
  236. });
  237. });
  238. }
  239. function barChart(element, options, isTimeline) {
  240. var _datum = options.transformer(options.datum);
  241. $(element).height(300);
  242. nv.addGraph(function () {
  243. var _chart;
  244. var insertLinebreaks = function (d) {
  245. var _el = d3.select(this);
  246. var _mom = moment(d);
  247. if (_mom != null) {
  248. var _words = _mom.format("hh:mm:ss YYYY-MM-DD").split(" ");
  249. _el.text('');
  250. for (var i = 0; i < _words.length; i++) {
  251. var tspan = _el.append("tspan").text(_words[i]);
  252. if (i > 0) {
  253. tspan.attr("x", 0).attr("dy", '15');
  254. }
  255. }
  256. }
  257. };
  258. if (isTimeline) {
  259. _chart = nv.models.multiBarWithBrushChart();
  260. if (_datum.length > 0 && _datum[0].values.length > 10){
  261. _chart.enableSelection();
  262. }
  263. _chart.onSelectRange(options.onSelectRange);
  264. _chart.xAxis.tickFormat(d3.time.format("%Y-%m-%d %H:%M:%S"));
  265. _chart.multibar.hideable(true);
  266. _chart.multibar.stacked(typeof options.stacked != "undefined" ? options.stacked : false);
  267. _chart.onStateChange(options.onStateChange);
  268. _chart.onChartUpdate(function(){
  269. _d3.selectAll("g.nv-x.nv-axis g text").each(insertLinebreaks);
  270. });
  271. }
  272. else {
  273. var _isDiscrete = false;
  274. for (var j=0;j<_datum.length;j++){
  275. for (var i=0;i<_datum[j].values.length;i++){
  276. if (isNaN(_datum[j].values[i].x * 1)){
  277. _isDiscrete = true;
  278. break;
  279. }
  280. }
  281. }
  282. if (_isDiscrete){
  283. _chart = nv.models.growingDiscreteBarChart()
  284. .x(function(d) { return d.x })
  285. .y(function(d) { return d.y })
  286. .staggerLabels(true);
  287. }
  288. else {
  289. _chart = nv.models.multiBarWithBrushChart();
  290. _chart.xAxis
  291. .showMaxMin(true)
  292. .tickFormat(d3.format(',0f'));
  293. _chart.multibar.hideable(true);
  294. _chart.multibar.stacked(typeof options.stacked != "undefined" ? options.stacked : false);
  295. _chart.onStateChange(options.onStateChange);
  296. }
  297. }
  298. _chart.transitionDuration(100);
  299. _chart.yAxis
  300. .tickFormat(d3.format(',0f'));
  301. var _d3 = ($(element).find('svg').length > 0) ? d3.select($(element).find('svg')[0]) : d3.select($(element)[0]).append('svg');
  302. _d3.datum(_datum)
  303. .transition().duration(150)
  304. .each("end", function(){
  305. options.onComplete();
  306. if (isTimeline) {
  307. _d3.selectAll("g.nv-x.nv-axis g text").each(insertLinebreaks);
  308. }
  309. }).call(_chart);
  310. nv.utils.windowResize(_chart.update);
  311. return _chart;
  312. }, function () {
  313. d3.selectAll(".nv-bar").on("click",
  314. function (d, i) {
  315. options.onClick(d);
  316. });
  317. });
  318. }