iT邦幫忙

0

請問各位大神~如何使用vue2元件props傳資料 並用echarts顯示資料

  • 分享至 

  • xImage

大家好~想請問
我用echarts做圖表 用vue套資料
發現在內層資料傳到外層後就是空的(1.程式碼資料傳到2.)
不知道傳送資料時哪邊要修改

https://ithelp.ithome.com.tw/upload/images/20220822/20147822yCZQB5jP85.png

<template>
    <div class="card">
        <div class="card-body">
            <h5 class="card-title">
                <div class="card-titleCenter">急診檢傷人數(本事件)</div>
                <div class="card-titleBottom">
                    <span class="block_DateRange">
                        <date-picker-range @change-date="changeDate">
                        </date-picker-range>
                    </span>
                </div>
            </h5>
            <div class="card-content">
                <stack-bar01 :five-Level-Obj="fiveLevelObj"></stack-bar01>
            </div>
        </div>
    </div>
</template>

<script>
//自定義元件
import DatePickerRange from "@/components/DatePickerRange";
import StackBar01 from "./components/StackBar01";

//api
import PatientStatusResource from "@/api/jie-qiao/patient-status";

//套件
import moment from "moment";

const patientStatusResource = new PatientStatusResource();

export default {
    name: "FiveLevelBlock",
    components: { DatePickerRange, StackBar01 },
    props: {},
    data() {
        return {
            fiveLevelObj: [],
            filterFormData: {
                StartDate: moment().locale("zh-tw").format("YYYY-MM-DD"),
                EndDate: moment().locale("zh-tw").format("YYYY-MM-DD"),
            },
        };
    },
    computed: {},
    created() {},
    mounted() {
        this.init();
    },
    methods: {
        async getFiveLevelList() {
            const fiveLevelObj = await patientStatusResource.fiveLevelList(
                this.filterFormData
            );
            fiveLevelObj &&
                this.$set(this, "fiveLevelObj", fiveLevelObj);
            console.log("---- 輸入標題 -----");
            console.log(fiveLevelObj);
            console.log("---- 輸入結尾 -----");
        },
        init() {
            this.$nextTick(() => {
                this.getFiveLevelList();
            });
        },
        changeDate(date) {
            this.filterFormData.StartDate = date[0];
            this.filterFormData.EndDate = date[1];
            this.init();
        },
    },
    watch: {},
};
</script>

<style lang="scss" scoped></style>
<template>
    <div
        class="ac_chartBlock"
        id="acChart01"
        style="width: 100%; height: 800px"
    ></div>
</template>

<script>
//echarts套件
const acPieChart = {
    ...
};

export default {
    name: "StackBar01",
    components: {},
    props: {
        fiveLevelObj: {
            type: Object,
        },
    },
    data() {
        return {
            acPieChart: acPieChart,
        };
    },
    computed: {},
    created() {},
    mounted() {
        const acChart01 = echarts.init(document.getElementById("acChart01"));
        acChart01.setOption(acPieChart);
            // console.log('---- 輸入標題 -----')
            // console.log(fiveLevelObj);
            // console.log('---- 輸入結尾 -----')
        },
    methods: {},
    watch: {
        fiveLevelObj: {
            handler(newValue, oldValue) {
                const acChart01 = echarts.init(
                    document.getElementById("acChart01")
                );
                for (let i = 0; i < 5; i++) {
                    this.acPieChart.series[i].data = [];
                    this.acPieChart.series[i].data = _(this.fiveLevelObj)
                        .map(`chK_LEVEL${i + 1}`)
                        .value();
                }
                acChart01.setOption(this.acPieChart);
            },
            deep: true,
        },
    },
};
</script>

<style lang="scss" scoped></style>
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
w4560000
iT邦研究生 5 級 ‧ 2022-08-22 10:30:27
最佳解答

目前看你父子元件 傳遞的參數跟型別不一致

父元件
你宣告 fiveLevelObj 是 陣列型別

<stack-bar01 :five-Level-Obj="fiveLevelObj"></stack-bar01>

子元件 改成這樣試試看

props: {
        five-Level-Obj: {
            type: Array,
        },
    },
看更多先前的回應...收起先前的回應...
碼農 iT邦新手 4 級 ‧ 2022-08-22 11:28:54 檢舉

five-Level-Obj這段會報錯
我記得這是放在html標籤的寫法

w4560000 iT邦研究生 5 級 ‧ 2022-08-22 12:05:48 檢舉

改成這樣試試

props: {
        fiveLevelObj: {
            type: Array,
        },
    },
碼農 iT邦新手 4 級 ‧ 2022-08-22 13:13:50 檢舉

這樣寫法我有試過 不會報錯
但父層有資料 子層是空的
https://ithelp.ithome.com.tw/upload/images/20220822/201478223E7jSqgGky.png

https://ithelp.ithome.com.tw/upload/images/20220822/20147822VPxse61608.png

w4560000 iT邦研究生 5 級 ‧ 2022-08-22 14:26:02 檢舉

可否提供一下 fiveLevelObj Json測試資料

碼農 iT邦新手 4 級 ‧ 2022-08-22 14:42:15 檢舉
[{"hospitaL_CODE":"0421040011","hospitalNickName":"成大醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"1141310019","hospitalNickName":"奇美醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"1141090512","hospitalNickName":"柳營奇美醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"1105050012","hospitalNickName":"佳里奇美醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"1121010018","hospitalNickName":"台南新樓醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"1105040016","hospitalNickName":"麻豆新樓醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"1305370013","hospitalNickName":"台南市安南醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"0905320023","hospitalNickName":"台南市立醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"0641310018","hospitalNickName":"榮總醫院臺南分院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"0141010013","hospitalNickName":"衛部新營醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"0121050011","hospitalNickName":"衛部臺南醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"0141060513","hospitalNickName":"衛部臺南新化分院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0},{"hospitaL_CODE":"1521031104","hospitalNickName":"郭綜合醫院","chK_LEVEL1":0,"chK_LEVEL2":3,"chK_LEVEL3":0,"chK_LEVEL4":0,"chK_LEVEL5":0}]

api

import Resource from './resource';
import request from '@/utils/jie-qiao-request';
import { FiveLevel, PaintUnit } from '@/class';

class PatientStatusResource extends Resource {
  constructor() {
    super('PatientStatus');
  }

  //急診檢傷人數
  async fiveLevelList(query) {
    const response = await request({
      url: `/${this.uri}/Get5Level`,
      method: 'get',
      params: query,
    })

    if (response) {
      const fiveLevelList = _.map([...response.data], (element) => {
        const fiveLevelObj = new FiveLevel(element);
        return fiveLevelObj;
      });
      return fiveLevelList
    }

  }

  //各治療單位病患明細資料
  async paintUnitList(query) {
    const response = await request({
      url: `/${this.uri}/GetPaintUNIT`,
      method: 'get',
      params: query,
    })

    if (response) {
      const paintUnitList = _.map([...response.data], (element) => {
        const paintUnitObj = new PaintUnit(element);
        return paintUnitObj;
      });
      return paintUnitList
    }

  }

}

export default PatientStatusResource;

class

import Base from './Base';

class FiveLevel extends Base {
    hospitaL_CODE = ""     //醫事代碼
    hospitalNickName = ""  //醫院中文
    total = 0              //急診檢傷總數
    chK_LEVEL1 = 0         //檢傷一級的數量
    chK_LEVEL2 = 0         //檢傷二級的數量
    chK_LEVEL3 = 0         //檢傷三級的數量
    chK_LEVEL4 = 0         //檢傷四級的數量
    chK_LEVEL5 = 0         //檢傷五級的數量

    constructor(obj) {
        super();
        (obj) && (this.setInit(obj));
    }

    setInit(obj) {
        this.hospitaL_CODE = obj.hospitaL_CODE;
        this.hospitalNickName = obj.hospitalNickName;
        this.total = obj.chK_LEVEL1 + obj.chK_LEVEL2 + obj.chK_LEVEL3 + obj.chK_LEVEL4 + obj.chK_LEVEL5;
        this.chK_LEVEL1 = obj.chK_LEVEL1;
        this.chK_LEVEL2 = obj.chK_LEVEL2;
        this.chK_LEVEL3 = obj.chK_LEVEL3;
        this.chK_LEVEL4 = obj.chK_LEVEL4;
        this.chK_LEVEL5 = obj.chK_LEVEL5;
    }
}
export default FiveLevel;

w4560000 iT邦研究生 5 級 ‧ 2022-08-22 15:41:13 檢舉
碼農 iT邦新手 4 級 ‧ 2022-08-22 16:56:32 檢舉

在你的環境可以^^~

但在我的環境laravel就有錯誤 不知道有無差別
我是用api拿資料 沒有寫死

StackBar01.vue
為何要引入這兩行??父層不是都有
import * as echarts from "echarts";
import { fn } from "moment";

w4560000 iT邦研究生 5 級 ‧ 2022-08-22 17:25:35 檢舉

測試環境 我就直接import了 方便測試而已
你沒貼錯誤出來 我也不知甚麼錯

碼農 iT邦新手 4 級 ‧ 2022-08-22 17:37:31 檢舉

抱歉講錯了 沒有噴錯誤
但問題ㄧ樣 就是沒有資料
https://ithelp.ithome.com.tw/upload/images/20220822/201478226q0JyD4O9E.png

碼農 iT邦新手 4 級 ‧ 2022-08-23 17:05:08 檢舉

感謝您熱心協助^^

0
froce
iT邦大師 1 級 ‧ 2022-08-22 10:47:37

我覺得你有問題的是

  1. 不知道你的 acPieChart 是幹嘛的,然後不斷的創新的 echarts 物件。
    不過我沒有環境可以測,所以只能給你個大概。
  2. 你的document.getElementById("acChart01")可能根本取不到。
<template>
    <div
        class="ac_chartBlock"
        id="acChart01"
        style="width: 100%; height: 800px"

        ref="acChart01"
    
    ></div>
</template>


<script>
const pieChartDefaultConfig = {
 ...
 // 初始設定
}

export default {
    name: "StackBar01",
    components: {},
    props: {
        fiveLevelObj: {
            type: Array,
        },
    },
    data() {
        return {
            acPieChart: null,
        };
    },
    computed: {},
    created() {},
    mounted() {
        this.acPieChart = echarts.init(this.$refs.acChart01);
        this.acPieChart.setOption(pieChartDefaultConfig);
        },
    methods: {},
    watch: {
        fiveLevelObj: {
            handler(newValue, oldValue) {
                // 處理你的props,我沒看懂你在幹嘛所以不詳細寫。
                const dataHandler = (v) => {
                    // 處理props變成echart用的config
                    return newFiveLevelObj
                }
                const newEchartConfig = dataHandler(newValue)
                this.acPieChart.setOption(newEchartConfig);
            },
            deep: true,
        },
    },
};
</script>

<style lang="scss" scoped></style>

大概的建議會是這樣

  1. 用其中一個data變數當共用物件。
  2. 用ref去取元素不要用document.query去取。

啊,樓上說的也有可能,你可能是傳錯變數型態被擋掉。

看更多先前的回應...收起先前的回應...
碼農 iT邦新手 4 級 ‧ 2022-08-22 11:41:01 檢舉

這兩個檔案程式碼是之前寫的另一個圖表 有成功取得值
抱歉這邊補上,可以看到完整acPieChart(差在名字是acLineBarChart)
圖表資料與上面提問的圖表資料相似度很高 有改寫成一樣 但沒有資料
https://ithelp.ithome.com.tw/upload/images/20220822/20147822xEqocxeUqJ.png

<template>
    <div class="card">
        <div class="card-body">
            <h5 class="card-title">
                <div class="card-titleCenter">大傷檢傷人數(本事件)</div>
                <div class="card-titleBottom">
                    <span class="block_DateRange">
                        <date-picker-range @change-date="changeDate">
                        </date-picker-range>
                    </span>
                </div>
            </h5>
            <div class="card-content">
                <line-bar01 :check-level-list="checkLevel"></line-bar01>
            </div>
        </div>
    </div>
</template>

<script>
//自定義元件
import DatePickerRange from "@/components/DatePickerRange";
import LineBar01 from "./components/LineBar01";

//api
import MajorInjuryResource from "@/api/jie-qiao/major-injury";

//套件
import moment from "moment";

const majorInjuryResource = new MajorInjuryResource();

export default {
    name: "CheckLevelBlock",
    components: { DatePickerRange, LineBar01 },
    props: {},
    data() {
        return {
            checkLevel: [],
            filterFormData: {
                StartDate: moment().locale("zh-tw").format("YYYY-MM-DD"),
                EndDate: moment().locale("zh-tw").format("YYYY-MM-DD"),
                Code: "223411789012",
            },
        };
    },
    computed: {},
    created() {},
    mounted() {
        this.init();
    },
    methods: {
        async getMajorInjuryObj() {
            const majorInjuryObj = await majorInjuryResource.getmajorInjury(
                this.filterFormData
            );
            majorInjuryObj &&
                this.$set(this, "checkLevel", majorInjuryObj.checkLevel);
        },
        init() {
            this.$nextTick(() => {
                this.getMajorInjuryObj();
            });
        },
        changeDate(date) {
            this.filterFormData.StartDate = date[0];
            this.filterFormData.EndDate = date[1];
            this.init();
        },
    },
    watch: {},
};
</script>

<style lang="scss" scoped></style>

<template>
    <div
        class="ac_chartBlock"
        id="acChart03"
        style="width: 100%; height: 820px"
    ></div>
</template>

<script>
//套件

const acLineBarChart = {
    title: {
        text: "",
        top: "2%",
        left: "center",
    },
    tooltip: {
        trigger: "axis",
        axisPointer: {
            type: "cross",
            label: {
                backgroundColor: "#6a7985",
            },
        },
    },
    xAxis: {
        type: "value",
        splitLine: {
            //y軸背景匡線
            show: true,
            lineStyle: {
                color: "#e3eaff",
                opacity: 0.5,
            },
        },
    },
    yAxis: {
        type: "category",
        axisLabel: {
            lineHeight: 18,
        },
        offset: "10",
        data: [
            "郭綜合醫院",
            "榮總醫院臺南分院",
            "台南市立醫院",
            "麻豆新樓醫院",
            "台南新樓醫院",
            "衛部臺南新化分院",
            "衛部臺南醫院",
            "衛部新營醫院",
            "台南市安南醫院",
            "柳營奇美醫院",
            "佳里奇美醫院",
            "奇美醫院",
            "成大醫院",
        ],
    },
    legend: [
        {
            //分類文字那行的位置
            top: "2%",
            left: "center",
            icon: "circle",
            itemGap: 15,
            textStyle: {
                padding: -8,
            },
        },
    ],
    grid: {
        top: "8%",
        left: "3%",
        right: "2%",
        bottom: "0%",
        containLabel: true,
    },
    series: [
        {
            name: "檢傷1級",
            type: "bar",
            barCategoryGap: "50%",
            stack: "total",
            color: "#F4F5FF",
            label: {
                show: true,
                color: "#302F64",
            },

            emphasis: {
                focus: "series",
            },
            data: [],
        },
        {
            name: "檢傷2級",
            type: "bar",
            stack: "total",
            color: "#DEE2FF",
            label: {
                show: true,
                color: "#302F64",
            },
            emphasis: {
                focus: "series",
            },
            data: [],
        },
        {
            name: "檢傷3級",
            type: "bar",
            stack: "total",
            color: "#C8CFFF",
            label: {
                show: true,
                color: "#302F64",
            },

            emphasis: {
                focus: "series",
            },
            data: [],
        },
        {
            name: "檢傷4級",
            type: "bar",
            stack: "total",
            color: "#B3BCFF",
            label: {
                show: true,
                color: "#302F64",
            },
            emphasis: {
                focus: "series",
            },
            data: [],
        },
        {
            name: "檢傷5級",
            type: "bar",
            stack: "total",
            color: "#929FFF",
            itemStyle: {
                barBorderRadius: [0, 50, 50, 0],
            },
            label: {
                show: true,
                color: "#302F64",
            },

            emphasis: {
                focus: "series",
            },
            data: [],
        },
    ],
};

export default {
    name: "LineBar01",
    components: {},
    props: {
        checkLevelList: {
            type: Array,
        },
    },
    data() {
        return {
            acLineBarChart: acLineBarChart,
        };
    },
    computed: {},
    created() {},
    mounted() {},
    methods: {},
    watch: {
        checkLevelList: {
            handler(newValue, oldValue) {
                const acChart03 = echarts.init(
                    document.getElementById("acChart03")
                );
                for (let i = 0; i < 5; i++) {
                    this.acLineBarChart.series[i].data = [];
                    this.acLineBarChart.series[i].data = _(this.checkLevelList)
                        .map(`chK_LEVEL${i + 1}`)
                        .value();
                }
                acChart03.setOption(this.acLineBarChart);
            },
            deep: true,
        },
    },
};
</script>

<style lang="scss" scoped></style>

froce iT邦大師 1 級 ‧ 2022-08-22 11:58:07 檢舉

我能給你的意見就以上兩點加樓上一點而已。
不管怎樣,按你原本的寫法,只要資料一變動就要重新初始化一個物件,這開銷會不會太大,你自己考慮。

碼農 iT邦新手 4 級 ‧ 2022-08-22 13:22:29 檢舉

大師你watch那段
我可以照寫跑跑看嗎
還是需要再加什麼

這個是公司前輩的寫法 目前也是看不太懂 單純照著改就跑不動
公司目前是安排自己找問題 不給問只好上來求救

froce iT邦大師 1 級 ‧ 2022-08-22 13:36:37 檢舉

我code有小改一下。,加入的初始設定的部分。


跑是一定不會動的啊,我又沒幫你真正實現設定的部分。
甚至連引入都沒引入。

一般來說,vue要包其他原生JS套件庫程組件的架構大概就是這樣,真正去改資料的部分,還有初始值、引入這些就麻煩你自己實踐。

改大概就 pieChartDefaultConfig 和 dataHandler 這兩塊會需要你自己實踐。

eChart我是沒在用,所以沒辦法給更詳細的範例了。

碼農 iT邦新手 4 級 ‧ 2022-08-23 17:14:15 檢舉

感謝熱心協助,祝出入平安~身體健康

我要發表回答

立即登入回答