ChartDeptBar.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. <template>
  2. <div>
  3. <el-card shadow="always">
  4. <div class="charts-box" style=" display: table; width:100%; margin-bottom: 10px;">
  5. <div
  6. style="border:1px solid #ebeef5; background-color: #fff; margin-bottom:10px; display: table-cell; border-right:none;"
  7. v-loading="loading"
  8. >
  9. <ve-histogram
  10. ref="chart-histogram"
  11. :title="dept_name"
  12. :xAxis="xAxis"
  13. :tooltip="tooltip"
  14. :series="series"
  15. :grid="{left:10,bottom:15,top:70}"
  16. :legend="Legend"
  17. height="250px"
  18. :settings="chartSettings"
  19. :colors="colorsintegral"
  20. ></ve-histogram>
  21. </div>
  22. <div
  23. style="border:1px solid #ebeef5; background-color: #fff; display: table-cell; width:400px;"
  24. v-loading="loading"
  25. >
  26. <ve-pie
  27. :title="{
  28. text:'积分构成',
  29. top:20,
  30. left:115,
  31. textStyle:{
  32. fontSize:14,
  33. lineHeight:30
  34. },
  35. }"
  36. :legend="pieLegend"
  37. :series="pieseries"
  38. :legend-visible="true"
  39. width="400px"
  40. height="250px"
  41. ></ve-pie>
  42. </div>
  43. </div>
  44. </el-card>
  45. <div style="height: 10px;"></div>
  46. </div>
  47. </template>
  48. <script>
  49. import Vue from "vue";
  50. import VCharts from "v-charts";
  51. Vue.use(VCharts);
  52. export default {
  53. props: {
  54. time_range: {
  55. type: Array,
  56. default: []
  57. },
  58. dept_id: {
  59. type: Number,
  60. default: 0
  61. },
  62. dept_name: {
  63. type: Object,
  64. default: ""
  65. }
  66. },
  67. data() {
  68. this.chartSettings = {
  69. stack: { 日期: ["奖分", "扣分"] }
  70. };
  71. return {
  72. histogramWidth: "200px",
  73. loading: false,
  74. Legend: {
  75. itemWidth: 18,
  76. itemHeight: 12,
  77. right: 10,
  78. top: 20
  79. },
  80. tooltip: {
  81. trigger: "axis",
  82. axisPointer: {
  83. type: "shadow"
  84. }
  85. },
  86. xAxis: {
  87. type: "category",
  88. data: []
  89. },
  90. series: [
  91. {
  92. name: "奖分",
  93. type: "bar",
  94. stack: "分数",
  95. data: [],
  96. barMinHeight: 1
  97. },
  98. {
  99. name: "扣分",
  100. type: "bar",
  101. stack: "分数",
  102. data: [],
  103. barMinHeight: 0
  104. }
  105. ],
  106. colorsintegral: ["#5ab1ef", "#fc8675"],
  107. pieseries: {
  108. name: "姓名",
  109. type: "pie",
  110. radius: 55,
  111. center: [90, 140],
  112. label: { show: false },
  113. data: [],
  114. itemStyle: {
  115. emphasis: {
  116. shadowBlur: 10,
  117. shadowOffsetX: 0,
  118. shadowColor: "rgba(0, 0, 0, 0.5)"
  119. }
  120. }
  121. },
  122. pieLegend: {
  123. type: "scroll",
  124. orient: "vertical",
  125. right: 10,
  126. top: 80,
  127. bottom: 20,
  128. data: []
  129. },
  130. comWidth: this.$store.getters.sidebar.opened,
  131. filter: {
  132. dept_id: [this.dept_id],
  133. category_id: [],
  134. point_type: 0,
  135. time_range: this.time_range
  136. },
  137. instantPickerOptions: {
  138. shortcuts: [
  139. {
  140. text: "本周",
  141. onClick(picker) {
  142. const now = new Date(new Date().toLocaleDateString());
  143. const start =
  144. now.getTime() - (now.getDay() - 1) * 24 * 60 * 60 * 1000;
  145. const end = start + 7 * 24 * 60 * 60 * 1000 - 1000;
  146. picker.$emit("pick", [start, end]);
  147. }
  148. },
  149. {
  150. text: "上周",
  151. onClick(picker) {
  152. const now = new Date(new Date().toLocaleDateString());
  153. const start =
  154. now.getTime() - (now.getDay() + 6) * 24 * 60 * 60 * 1000;
  155. const end = start + 7 * 24 * 60 * 60 * 1000 - 1000;
  156. picker.$emit("pick", [start, end]);
  157. }
  158. },
  159. {
  160. text: "本月",
  161. onClick(picker) {
  162. const now = new Date();
  163. const startDate = new Date(now.getFullYear(), now.getMonth(), 1);
  164. const endDate = new Date(
  165. now.getFullYear(),
  166. now.getMonth() + 1,
  167. 0
  168. );
  169. picker.$emit("pick", [startDate.getTime(), endDate.getTime()]);
  170. }
  171. },
  172. {
  173. text: "上月",
  174. onClick(picker) {
  175. const now = new Date();
  176. const startDate = new Date(
  177. now.getFullYear() - (now.getMonth() > 0 ? 0 : 1),
  178. (now.getMonth() + 11) % 12,
  179. 1
  180. );
  181. const endDate = new Date(now.getFullYear(), now.getMonth(), 0);
  182. picker.$emit("pick", [startDate.getTime(), endDate.getTime()]);
  183. }
  184. },
  185. {
  186. text: "本年",
  187. onClick(picker) {
  188. const now = new Date();
  189. const startDate = new Date(now.getFullYear(), 0, 1);
  190. const endDate = new Date(now.getFullYear() + 1, 0, 0);
  191. picker.$emit("pick", [startDate.getTime(), endDate.getTime()]);
  192. }
  193. }
  194. ]
  195. }
  196. };
  197. },
  198. components: {},
  199. methods: {
  200. loadChartData() {
  201. const params = {
  202. employee_id: 0
  203. };
  204. for (const item in this.filter) {
  205. const value = this.filter[item];
  206. if (item == "category_id" || item == "dept_id") {
  207. if (!value || value.length == 0) {
  208. continue;
  209. }
  210. params[item] = value[value.length - 1];
  211. } else if (item == "time_range") {
  212. if (!value || value.length < 2) {
  213. continue;
  214. }
  215. const timeRangeArr = value.map(x => parseInt(x / 1000));
  216. timeRangeArr[1] += 60 * 60 * 24 - 1;
  217. params[item] = timeRangeArr.join(",");
  218. } else {
  219. params[item] = value;
  220. }
  221. }
  222. var self = this;
  223. self.loading = true;
  224. this.$http('get',"/integral.php/point_data/chart_data_by_dept",params)
  225. .then(function(response) {
  226. if (response.status == 200) {
  227. const jsonData = response.data;
  228. self.loading = false;
  229. try {
  230. self.pieseries.data = [];
  231. const datetime = [];
  232. const add_point = [];
  233. const sub_point = [];
  234. if (typeof jsonData.trend_chart_data != "undefined") {
  235. for (const item in jsonData.trend_chart_data.labels) {
  236. datetime.push(jsonData.trend_chart_data.labels[item]);
  237. add_point.push(jsonData.trend_chart_data.p_positive[item]);
  238. sub_point.push(
  239. jsonData.trend_chart_data.p_negative[item] * -1
  240. );
  241. }
  242. const pieseries = [];
  243. const pieLegend = [];
  244. for (const item in jsonData.structure_positive_chart_data) {
  245. pieseries.push({
  246. value: jsonData.structure_positive_chart_data[item][1],
  247. name:
  248. jsonData.structure_positive_chart_data[item][0] +
  249. "(" +
  250. jsonData.structure_positive_chart_data[item][1] +
  251. ")"
  252. });
  253. pieLegend.push(
  254. jsonData.structure_positive_chart_data[item][0] +
  255. "(" +
  256. jsonData.structure_positive_chart_data[item][1] +
  257. ")"
  258. );
  259. }
  260. self.$set(self.pieseries, "data", pieseries);
  261. self.$set(self.pieLegend, "data", pieLegend);
  262. }
  263. self.$set(self.series[0], "data", add_point);
  264. self.$set(self.series[1], "data", sub_point);
  265. self.$set(self.xAxis, "data", datetime);
  266. } catch (err) {
  267. console.log(err);
  268. }
  269. }
  270. })
  271. .catch(function(error) {
  272. console.log(error);
  273. });
  274. }
  275. },
  276. watch: {
  277. "$store.getters.sidebar.opened": function(curVal, oldVal) {
  278. //左边菜单发生变化时,重新设定图表宽度,以适应屏幕
  279. const self = this;
  280. setTimeout(() => {
  281. self.$refs["chart-histogram"].echarts.resize();
  282. }, 300);
  283. }
  284. },
  285. created() {
  286. // alert(123)
  287. const self = this;
  288. this.$nextTick(() => {
  289. setTimeout(() => {
  290. self.$refs["chart-histogram"].echarts.resize();
  291. }, 300);
  292. });
  293. this.loadChartData();
  294. }
  295. };
  296. </script>