OCA reporting engine fork for dev and update.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
3.8 KiB

  1. odoo.define('kpi_dashboard.GraphWidget', function (require) {
  2. "use strict";
  3. var AbstractWidget = require('kpi_dashboard.AbstractWidget');
  4. var registry = require('kpi_dashboard.widget_registry');
  5. var core = require('web.core');
  6. var qweb = core.qweb;
  7. var GraphWidget = AbstractWidget.extend({
  8. template: 'kpi_dashboard.graph',
  9. jsLibs: [
  10. '/web/static/lib/nvd3/d3.v3.js',
  11. '/web/static/lib/nvd3/nv.d3.js',
  12. '/web/static/src/js/libs/nvd3.js',
  13. ],
  14. cssLibs: [
  15. '/web/static/lib/nvd3/nv.d3.css',
  16. ],
  17. start: function () {
  18. this._onResize = this._onResize.bind(this);
  19. nv.utils.windowResize(this._onResize);
  20. return this._super.apply(this, arguments);
  21. },
  22. destroy: function () {
  23. if ('nv' in window && nv.utils && nv.utils.offWindowResize) {
  24. // if the widget is destroyed before the lazy loaded libs (nv) are
  25. // actually loaded (i.e. after the widget has actually started),
  26. // nv is undefined, but the handler isn't bound yet anyway
  27. nv.utils.offWindowResize(this._onResize);
  28. }
  29. this._super.apply(this, arguments);
  30. },
  31. _getChartOptions: function (values) {
  32. return {
  33. x: function (d, u) { return u; },
  34. margin: {'left': 0, 'right': 0, 'top': 5, 'bottom': 0},
  35. showYAxis: false,
  36. showXAxis: false,
  37. showLegend: false,
  38. height: this.widget_size_y - 90,
  39. width: this.widget_size_x - 20,
  40. };
  41. },
  42. _chartConfiguration: function (values) {
  43. this.chart.forceY([0]);
  44. this.chart.xAxis.tickFormat(function (d) {
  45. var label = '';
  46. _.each(values.value.graphs, function (v) {
  47. if (v.values[d] && v.values[d].x) {
  48. label = v.values[d].x;
  49. }
  50. });
  51. return label;
  52. });
  53. this.chart.yAxis.tickFormat(d3.format(',.2f'));
  54. this.chart.tooltip.contentGenerator(function (key) {
  55. return qweb.render('GraphCustomTooltip', {
  56. 'color': key.point.color,
  57. 'key': key.series[0].title,
  58. 'value': d3.format(',.2f')(key.point.y)
  59. });
  60. });
  61. },
  62. _addGraph: function (values) {
  63. var data = values.value.graphs;
  64. this.$svg.addClass('o_graph_linechart');
  65. this.chart = nv.models.lineChart();
  66. this.chart.options(
  67. this._getChartOptions(values)
  68. );
  69. this._chartConfiguration(values);
  70. d3.select(this.$('svg')[0])
  71. .datum(data)
  72. .transition().duration(600)
  73. .call(this.chart);
  74. this.$('svg').css('height', this.widget_size_y - 90);
  75. this._customizeChart();
  76. },
  77. fillWidget: function (values) {
  78. var self = this;
  79. var element = this.$el.find('[data-bind="value"]');
  80. element.empty();
  81. element.css('padding-left', 10).css('padding-right', 10);
  82. this.chart = null;
  83. nv.addGraph(function () {
  84. self.$svg = self.$el.find(
  85. '[data-bind="value"]'
  86. ).append('<svg width=' + (self.widget_size_x - 20) + '>');
  87. self._addGraph(values);
  88. });
  89. },
  90. _customizeChart: function () {
  91. // Hook function
  92. },
  93. _onResize: function () {
  94. if (this.chart) {
  95. this.chart.update();
  96. this._customizeChart();
  97. }
  98. },
  99. });
  100. registry.add('graph', GraphWidget);
  101. return GraphWidget;
  102. });