chart.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # -*- coding: utf-8 -*-
  2. from odoo.utils.jinja_util import change_to_json
  3. LINE = 1
  4. BAR = 2
  5. PIE = 3
  6. class ChartType(object):
  7. __slots__ = ['line', 'bar', 'pie']
  8. def __init__(self):
  9. self.line = LINE
  10. self.bar = BAR
  11. self.pie = PIE
  12. class Chart(object):
  13. def __init__(self, title):
  14. self.title = title
  15. self.data = []
  16. self.zoom = ()
  17. self.chart_type = '1'
  18. self.is_change_xy = False
  19. return
  20. def set_data(self, data):
  21. self.data = data
  22. return
  23. def set_zoom(self, start, end):
  24. self.zoom = (start, end)
  25. return
  26. def set_chart_type(self, chart_type):
  27. self.chart_type = chart_type
  28. return
  29. def set_change_xy(self):
  30. self.is_change_xy = True
  31. return
  32. def _get_chart_type(self):
  33. if self.chart_type == BAR:
  34. return 'bar'
  35. if self.chart_type == PIE:
  36. return 'pie'
  37. return 'line'
  38. def get(self):
  39. if not self.data or len(self.data) < 2:
  40. return Chart._get_default()
  41. if self.chart_type == PIE:
  42. return self._get_pie()
  43. dic = {
  44. 'legend': {},
  45. 'tooltip': {},
  46. 'dataset': {'source': self.data}
  47. }
  48. if self.title:
  49. dic['title'] = {'text': self.title}
  50. if self.is_change_xy:
  51. dic['xAxis'] = {}
  52. dic['yAxis'] = {'type': 'category'}
  53. else:
  54. dic['xAxis'] = {'type': 'category'}
  55. dic['yAxis'] = {}
  56. if self.zoom:
  57. dic['dataZoom'] = [
  58. {'type': 'slider', 'start': self.zoom[0], 'end': self.zoom[1]},
  59. {'type': 'inside', 'start': self.zoom[0], 'end': self.zoom[1]}
  60. ]
  61. chart_type = self._get_chart_type()
  62. series = [{'type': chart_type, 'seriesLayoutBy': 'row'} for x in range(len(self.data) - 1)]
  63. dic['series'] = series
  64. data = Chart._get_4_json(dic)
  65. # print 'data:', data
  66. return data
  67. def _get_pie(self):
  68. if not self.data or len(self.data) == 0:
  69. return Chart._get_default()
  70. data = self._get_pie_data()
  71. dic = {
  72. 'series': [
  73. {
  74. 'name': '访问来源',
  75. 'type': 'pie', # 设置图表类型为饼图
  76. 'radius': '55%', # 饼图的半径,外半径为可视区尺寸(容器高宽中较小一项)的 55% 长度。
  77. 'label': {
  78. 'formatter': '{b}: {@2012} ({d}%)'
  79. },
  80. 'data': data
  81. }
  82. ]
  83. }
  84. return Chart._get_4_json(dic)
  85. def _get_pie_data(self):
  86. # 格式举例:
  87. # [ # 数据数组,name 为数据项名称,value 为数据项值
  88. # {'value': 235, 'name': '视频广告'},
  89. # {'value': 274, 'name': '联盟广告'}
  90. # ]
  91. data = self.data[1:]
  92. return [{'value': row[1], 'name': row[0]} for row in data]
  93. @staticmethod
  94. def _get_4_json(data):
  95. return data
  96. # _data = change_to_json(data)
  97. # return change_to_json(_data)
  98. @staticmethod
  99. def _get_default():
  100. return False
  101. # return Chart._get_4_json(False)
  102. # dataZoom: [
  103. # { // 这个dataZoom组件,默认控制x轴。
  104. # type: 'slider', // 这个 dataZoom 组件是 slider 型 dataZoom 组件
  105. # start: 10, // 左边在 10% 的位置。
  106. # end: 60 // 右边在 60% 的位置。
  107. # },
  108. # { // 这个dataZoom组件,也控制x轴。
  109. # type: 'inside', // 这个 dataZoom 组件是 inside 型 dataZoom 组件
  110. # start: 10, // 左边在 10% 的位置。
  111. # end: 60 // 右边在 60% 的位置。
  112. # }
  113. #
  114. # ],