lrf402788946 4 năm trước cách đây
mục cha
commit
e403337abf

+ 127 - 0
src/components/statistics/bar.vue

@@ -0,0 +1,127 @@
+<template>
+  <div id="bar">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import { Bar, Column } from '@antv/g2plot';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'bar',
+  props: {
+    data: { type: [Object, Array], default: () => [] },
+    axis: { type: Object, default: () => {} },
+    gid: { type: String, default: `${new Date().getTime()}` },
+    horizontal: { type: Boolean, default: true },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      list: [],
+    };
+  },
+  created() {},
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let e = document.getElementById(this.gid);
+      if (!e) {
+        console.warn('没有找到指定渲染容器');
+        return;
+      }
+      if (!this.list) {
+        //未获得数据
+        return;
+      }
+      if (this.chart) {
+        this.chart.updateConfig({ data: this.list });
+      } else {
+        let { x, y, xAlias, yAlias } = this.axis;
+        let meta = {};
+        meta[x] = { alias: xAlias };
+        meta[y] = { alias: yAlias };
+        let options = {
+          pixelRatio: 1,
+          data: this.list,
+          //条形和柱状的x,y轴需要互换
+          xField: this.horizontal ? y : x,
+          yField: this.horizontal ? x : y,
+          meta: meta,
+          point: {
+            visible: true,
+          },
+          label: {
+            visible: true,
+          },
+          //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+          stackField: x,
+          legend: {
+            visible: true,
+            position: 'right-top',
+          },
+          xAxis: {
+            nice: true,
+            visible: true,
+            line: {
+              visible: true,
+            },
+            grid: {
+              visible: true,
+            },
+            tickLine: {
+              visible: true,
+            },
+          },
+          yAxis: {
+            nice: true,
+            visible: true,
+            grid: {
+              visible: true,
+            },
+            line: {
+              visible: true,
+            },
+          },
+
+          events: {
+            // onColumnClick: e => this.gclick(e),
+          },
+        };
+        if (this.horizontal) this.chart = new Bar(this.gid, options);
+        else this.chart = new Column(this.gid, options);
+      }
+      this.chart.render();
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val.length > 0) this.$set(this, `list`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+    list: {
+      handler(val) {
+        if (val) this.$nextTick(() => this.init());
+      },
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 102 - 0
src/components/statistics/donut.vue

@@ -0,0 +1,102 @@
+<template>
+  <div id="donut">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+import { Donut } from '@antv/g2plot';
+export default {
+  name: 'donut',
+  props: {
+    data: { type: Array, default: () => [] },
+    axis: { type: Object, default: () => {} }, //{x:x轴字段名; xAlias:x轴名称; y:y轴字段名; yAlias:y轴名称}
+    gid: { type: String, default: `${new Date().getTime()}` },
+    headTitle: { type: String, default: '' },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      list: undefined,
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let e = document.getElementById(this.gid);
+      if (!e) {
+        console.warn('没有找到指定渲染容器');
+        return;
+      }
+      if (!this.list) {
+        //未获得数据
+        return;
+      }
+      if (this.chart) {
+        this.chart.updateConfig({ data: this.list });
+      } else {
+        let { x, y, xAlias, yAlias } = this.axis;
+        let meta = {};
+        meta[x] = { alias: xAlias };
+        meta[y] = { alias: yAlias };
+        this.chart = new Donut(this.gid, {
+          title: { visible: true, text: this.headTitle },
+          pixelRatio: 4,
+          data: this.list,
+          colorField: x,
+          angleField: y,
+          meta: meta,
+          point: {
+            visible: true,
+          },
+          label: {
+            visible: true,
+            type: 'spider',
+            formatter: (text, item) => `${item._origin[x]}: ${item._origin[y]}`,
+          },
+          //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+          stackField: x,
+          legend: {
+            visible: true,
+            position: 'right-top',
+          },
+          events: {
+            // onPieClick: e => this.gclick(e),
+          },
+        });
+      }
+
+      this.chart.render();
+    },
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val.length > 0) this.$set(this, `list`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+    list: {
+      handler(val) {
+        if (val) this.$nextTick(() => this.init());
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 81 - 0
src/components/statistics/liquid.vue

@@ -0,0 +1,81 @@
+<template>
+  <div id="liquid">
+    <div :id="gid" style="height:450px"></div>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import { mapState, createNamespacedHelpers } from 'vuex';
+import { Liquid } from '@antv/g2plot';
+export default {
+  name: 'liquid',
+  props: {
+    data: { type: [Number, String], default: 0 },
+    max: { type: Number, default: 100 }, //整体上限,调整比例
+    min: { type: Number, default: 0 }, //整体上限,调整比例
+    gid: { type: String, default: `${new Date().getTime()}` },
+    headTitle: { type: String, default: '' },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      value: 0,
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  created() {},
+  methods: {
+    async init() {
+      let e = document.getElementById(this.gid);
+      if (!e) {
+        console.warn('没有找到指定渲染容器');
+        return;
+      }
+      if (this.chart) {
+        this.chart.updateConfig({ value: this.value });
+      } else {
+        this.chart = new Liquid(this.gid, {
+          title: { visible: true, text: this.headTitle },
+          min: this.min,
+          max: this.max,
+          value: this.value, //
+          events: {
+            // onPieClick: e => this.gclick(e),
+          },
+        });
+      }
+
+      this.chart.render();
+    },
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val) this.$set(this, `value`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+    value: {
+      handler(val) {
+        if (val) this.$nextTick(() => this.init());
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 114 - 0
src/components/statistics/pie.vue

@@ -0,0 +1,114 @@
+<template>
+  <div id="down-pie">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+import { Pie } from '@antv/g2plot';
+export default {
+  name: 'downPie',
+  props: {
+    data: { type: Array, default: () => [] },
+    axis: { type: Object, default: () => {} }, //{x:x轴字段名; xAlias:x轴名称; y:y轴字段名; yAlias:y轴名称}
+    gid: { type: String, default: `${new Date().getTime()}` },
+    headTitle: { type: String, default: '' },
+  },
+  components: {},
+  data: () => {
+    return {
+      chart: null,
+      list: undefined,
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let e = document.getElementById(this.gid);
+      if (!e) {
+        console.warn('没有找到指定渲染容器');
+        return;
+      }
+      if (!this.list) {
+        //未获得数据
+        return;
+      }
+      if (this.chart) {
+        this.chart.updateConfig({ data: this.list });
+      } else {
+        let { x, y, xAlias, yAlias } = this.axis;
+        let meta = {};
+        meta[x] = { alias: xAlias };
+        meta[y] = { alias: yAlias };
+        this.chart = new Pie(this.gid, {
+          title: { visible: true, text: this.headTitle },
+          pixelRatio: 4,
+          data: this.list,
+          colorField: x,
+          angleField: y,
+          meta: meta,
+          point: {
+            visible: true,
+          },
+          label: {
+            visible: true,
+            type: 'spider',
+            formatter: (text, item) => `${item._origin[x]}: ${item._origin[y]}`,
+          },
+          //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+          stackField: x,
+          legend: {
+            visible: true,
+            position: 'right-top',
+          },
+          events: {
+            // onPieClick: e => this.gclick(e),
+          },
+        });
+      }
+
+      this.chart.render();
+    },
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val.length > 0) this.$set(this, `list`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+    list: {
+      handler(val) {
+        if (val) this.$nextTick(() => this.init());
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.rightData {
+  padding: 0 30px;
+  height: 391px;
+  overflow: hidden;
+}
+/deep/.el-table td {
+  padding: 8px 0;
+}
+/deep/.el-table th {
+  padding: 8px 0;
+}
+</style>

+ 104 - 0
src/components/statistics/rose.vue

@@ -0,0 +1,104 @@
+<template>
+  <div id="rose">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+import { Rose } from '@antv/g2plot';
+export default {
+  name: 'rose',
+  props: {
+    data: { type: Array, default: () => [] },
+    axis: { type: Object, default: () => {} }, //{x:x轴字段名; xAlias:x轴名称; y:y轴字段名; yAlias:y轴名称}
+    gid: { type: String, default: `${new Date().getTime()}` },
+    headTitle: { type: String, default: '' },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      list: undefined,
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let e = document.getElementById(this.gid);
+      if (!e) {
+        console.warn('没有找到指定渲染容器');
+        return;
+      }
+      if (!this.list) {
+        //未获得数据
+        return;
+      }
+      if (this.chart) {
+        this.chart.updateConfig({ data: this.list });
+      } else {
+        let { x, y, xAlias, yAlias } = this.axis;
+        let meta = {};
+        meta[x] = { alias: xAlias };
+        meta[y] = { alias: yAlias };
+        this.chart = new Rose(this.gid, {
+          title: { visible: true, text: this.headTitle },
+          pixelRatio: 4,
+          data: this.list,
+          radiusField: y,
+          categoryField: x,
+          colorField: x,
+          // angleField: y,
+          meta: meta,
+          point: {
+            visible: true,
+          },
+          label: {
+            visible: true,
+            type: 'spider',
+            formatter: (text, item) => `${item[x]}: ${item[y]}`,
+          },
+          //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+          stackField: x,
+          legend: {
+            visible: true,
+            position: 'right-top',
+          },
+          events: {
+            // onPieClick: e => this.gclick(e),
+          },
+        });
+      }
+
+      this.chart.render();
+    },
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val.length > 0) this.$set(this, `list`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+    list: {
+      handler(val) {
+        if (val) this.$nextTick(() => this.init());
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>