chart_info.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. # -*- coding: utf-8 -*-
  2. from odoo.http import request
  3. from odoo.utils.constant import LINE, BAR
  4. from odoo.utils.jinja_util import change_to_json
  5. from . import chart
  6. from .indicator import Indicator
  7. class ChartInfo(object):
  8. __slots__ = ['chart_type', 'unit_field', 'x_field', 'x_show', 'indicator_list', 'column_head_list', 'rows',
  9. '_column_length', 'unit_archive_model', 'chart_id']
  10. def __init__(self):
  11. self.chart_id = 0
  12. self.chart_type = ''
  13. self.unit_field = ''
  14. self.unit_archive_model = ''
  15. self.x_field = ''
  16. self.x_show = ''
  17. self.indicator_list = []
  18. self.column_head_list = [] # 查询结果:表头
  19. self.rows = [] # 查询结果
  20. self._column_length = 0 # 查询结果总列数
  21. return
  22. def set_chart_id(self, chart_id):
  23. self.chart_id = chart_id
  24. return
  25. def set_chart_type(self, chart_type):
  26. self.chart_type = chart_type
  27. return
  28. def set_unit(self, unit_field, unit_archive_model):
  29. self.unit_field = unit_field
  30. self.unit_archive_model = unit_archive_model
  31. return
  32. def set_x(self, x_field, x_show):
  33. self.x_field = x_field
  34. self.x_show = x_show
  35. return
  36. def add_indicator(self, field, show):
  37. indicator = Indicator(field, show)
  38. self.indicator_list.append(indicator)
  39. return
  40. def query_chart(self, where_expression, param, source):
  41. column_list = self._query_chart_column(where_expression, param, source)
  42. column_list = self._query_name(column_list)
  43. self._query_chart_data(where_expression, param, column_list, source)
  44. return
  45. def _query_name(self, column_list):
  46. domain = [('id', 'in', column_list)]
  47. data = request.env[self.unit_archive_model].sudo().search_read(domain, ['id', 'name'])
  48. return [[row['id'], row['name']] for row in data]
  49. def get(self, table_height, table_width):
  50. res = {
  51. 'chart_id': self.chart_id,
  52. 'chart': self._get_chart(),
  53. "table_height": table_height,
  54. "table_width": table_width,
  55. }
  56. # print 'chart res:', res
  57. return change_to_json(res)
  58. def _query_chart_column(self, where_expression, param, source):
  59. sql_format = """select {} from {} {}"""
  60. sql = sql_format.format('distinct ' + self.unit_field, source, where_expression)
  61. cr = request.env.cr
  62. if where_expression:
  63. cr.execute(sql, param)
  64. else:
  65. cr.execute(sql)
  66. result = cr.fetchall()
  67. # result = [list(row) for row in result]
  68. # self._change_none_(result)
  69. return [row[0] for row in result]
  70. def _query_chart_data(self, where_expression, param, column_list, source):
  71. sql_format = """select {} from {} {} group by {} order by {}"""
  72. field_expression_list = self._get_indicator_expression(column_list)
  73. field_expression_list = [self.x_field] + field_expression_list
  74. self._column_length = len(field_expression_list)
  75. field_expressions = ','.join(field_expression_list)
  76. sql = sql_format.format(field_expressions, source, where_expression, self.x_field, self.x_field)
  77. cr = request.env.cr
  78. if where_expression:
  79. cr.execute(sql, param)
  80. else:
  81. cr.execute(sql)
  82. result = cr.fetchall()
  83. result = [list(row) for row in result]
  84. self._change_none_(result, self._column_length)
  85. self.rows = result
  86. def _change_none_(self, rows, _length):
  87. for r in rows:
  88. for index in range(_length):
  89. if not r[index]:
  90. r[index] = ''
  91. return
  92. def _get_indicator_expression(self, column_value_list):
  93. res = []
  94. heads_list = [self.x_show]
  95. for _id, name in column_value_list:
  96. for indicator in self.indicator_list:
  97. res.append("sum(case when {}={} then {} end) as {}".format(self.unit_field, _id, indicator.field,
  98. indicator.show))
  99. heads_list.append("{}/{}".format(name, indicator.show))
  100. self.column_head_list = heads_list
  101. return res
  102. def _get_chart(self):
  103. data = self._get_chart_data()
  104. helper = chart.Chart(None)
  105. helper.set_data(data)
  106. helper.set_zoom(0, 100)
  107. helper.set_chart_type(self._get_chart_type())
  108. # helper.set_change_xy()
  109. return helper.get()
  110. def _get_chart_data(self):
  111. data = [self.column_head_list] + self.rows
  112. return list(map(list, zip(*data))) # 行列转换
  113. def _get_chart_type(self):
  114. if self.chart_type == LINE:
  115. return chart.ChartType().line
  116. if self.chart_type == BAR:
  117. return chart.ChartType().bar
  118. return chart.ChartType().line