charts.ko.js 11 KB

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