linmasahiro / vue3-table-lite

A simple and lightweight data table component for Vue.js 3. Features sorting, paging, row check, dynamic data rendering, supported TypeScript, and more.
https://vue3-lite-table.vercel.app/
MIT License
248 stars 74 forks source link

Is it possible to add apexchart sparkline to doSearch() function? #101

Closed jasonbau closed 10 months ago

jasonbau commented 10 months ago

Is it possible to add apexchart's sparkline to doSearch() function? I tried to add formatter to column but it does not work.

linmasahiro commented 10 months ago

Hi @jasonbau

Is it possible to add apexchart's sparkline to doSearch() function? I tried to add formatter to column but it does not work.

Of course yes, but I don't know why not work in your code, so I tried to created an example for you, hope helpful you https://codesandbox.io/s/determined-nash-wscc4w?file=/src/App.vue

jasonbau commented 10 months ago

Thank you for providing example, I'm new to Vue and I hope the code I provided can receive your guidance.

<script>
    import axios from "axios";
    import { defineComponent, reactive, computed, onMounted, ref, h } from "vue";
    import { useAppVariableStore } from "@/stores/app-variable";
    import vueTable from "@/components/plugins/VueTable.vue";
    import apexchart from "@/components/plugins/Apexcharts.vue";
    import jsVectorMap from "jsvectormap";
    import "jsvectormap/dist/maps/world.js";
    import "jsvectormap/dist/css/jsvectormap.min.css";
    import datepicker from "@/components/plugins/Datepicker.vue";

    export default {
        props: {
            row: Object,
        },
        data() {
            return {
                searchQuery: this.searchQuery,
            };
        },
        components: {
            vueTable: vueTable,
            apexchart: apexchart,
        },
        watch: {},
        created() {},
        methods: {
            handlePageviewsSparklineData(data) {
                console.log('Pageviews Sparkline Data:', data);
            },
        },
        setup() {
            // console.log(123123123);
            const searchQuery = ref("");
            const handleSearch = () => {
                doSearch(0, 10, "id", "asc", searchQuery.value);
            };
            const table = reactive({
                searchQuery: "",
                isLoading: false,
                columns: [
                ],
                rows: [],
                totalRecordCount: 0,
                sortable: {
                    order: "id",
                    sort: "asc",
                },
                currentPage: 1, 
                paginationConfig: {
                    pageSizes: [20, 30, 50],
                },
            });

            const doSearch = (offset, limit, order, sort, searchQuery) => {
                console.log("offset:" + offset + "  limit:" + limit + "  order:" + order + "  order:" + sort + " searchQuery:" + table.searchQuery);
                // console.log(this.searchQuery);
                table.isLoading = true;
                if (table.searchQuery == "") table.searchQuery = searchQuery || "";
                axios
                    .get(
                        "https://example.com/api?limit=" +
                            limit +
                            "&offset=" +
                            offset +
                            "&sort=" +
                            sort +
                            "&order=" +
                            order +
                            "&datatime=today" +
                            "&searchQuery=" +
                            table.searchQuery +
                            "&searchColumn=title"
                    )
                    .then((response) => {
                        response.data.rows.forEach((row) => {
                            row.pageviewsSparklineData = reactive({
                                series: [
                                    {
                                        name: "pageviewsSparklineData",
                                        data: row.pageviewsSparklineData.map((value) => parseInt(value) || 0),
                                    },
                                ],
                                options: {
                                    chart: {
                                        sparkline: {
                                            enabled: true,
                                        },
                                    },
                                    stroke: {
                                        width: 2,
                                    },
                                    height: 25,
                                },
                                height: 10,
                            });
                            row.apexSparkline = h(apexchart, { row });
                            // row.pageviewsSparklineData = "";
                        });
                        response.data.columns.forEach((column) => {
                            if (column.field == "id") {
                                column.sortable = true;
                                column.isKey = true;
                            } else {
                                column.sortable = true;
                            }
                            if (column.field == "pageviewsSparklineData") {
                                column.sortable = false;
                                // console.log(43534);
                                column.formatter = (row) => {
                                    console.log(123123123123);
                                };
                            }
                        });
                        console.log(response.data.columns);

                        // console.log(response.data)
                        // console.log(columns);
                        // console.log(table);

                        table.columns = response.data.columns;
                        table.rows = response.data.rows;
                        table.totalRecordCount = response.data.totalRecordCount;
                        // console.log(123123);
                        table.isLoading = false;
                        // console.log(table);
                        // console.log(response.data.rows);
                    })
                    .catch((error) => {
                        console.error("Error fetching data:", error);
                    });
            };
            const tableLoadingFinish = (elements) => {
                // console.log(elements);
                // console.log("finish");
                table.isLoading = false;
            };

            doSearch(0, 10, "id", "asc", searchQuery);
            // table.doSearch = doSearch;
            // table.tableLoadingFinish = tableLoadingFinish;

            return { table, doSearch, tableLoadingFinish, searchQuery, handleSearch };
        },
        mounted() {
            // this.tableLoadingFinish();
            // this.doSearch(0, 10, "id", "asc");
            // this.loadDataFromServer();
        },
    };
</script>
<template>
    <!-- BEGIN breadcrumb -->
    <ol class="breadcrumb float-xl-end">
        <li class="breadcrumb-item"><a href="javascript:;">Home</a></li>
        <li class="breadcrumb-item"><a href="javascript:;">Library</a></li>
        <li class="breadcrumb-item active">Data</li>
    </ol>
    <!-- END breadcrumb -->
    <!-- BEGIN page-header -->
    <h1 class="page-header">Page Header <small>header small text goes here...</small></h1>
    <!-- END page-header -->

    <!-- BEGIN panel -->
    <panel>
        <panel-header>
            <panel-title>Panel title here</panel-title>
            <panel-toolbar />
        </panel-header>
        <panel-body>
            <!-- BEGIN input-group -->
            <div class="input-group input-group-lg mb-3">
                <input type="text" class="form-control input-white" placeholder="Enter keywords here..." v-model="searchQuery" @keyup.enter="handleSearch" />
                <button type="button" class="btn btn-primary" @click="handleSearch"><i class="fa fa-search fa-fw"></i> Search</button>
            </div>
            <!-- END input-group -->
            <!-- <vue-table class="vue-table"
          :is-static-mode="true"
          :columns="table.columns"
          :rows="table.rows"
          :total="table.totalRecordCount"
          :sortable="table.sortable" /> -->

            <vue-table
                :key="tableKey"
                :is-slot-mode="true"
                :is-loading="table.isLoading"
                :columns="table.columns"
                :rows="table.rows"
                :total="table.totalRecordCount"
                :sortable="table.sortable"
                @do-search="doSearch"
                @is-finished="tableLoadingFinish"
            >
                <template v-slot:pageviewsSparklineData="{ row }">
                    <td>
                        <apexchart :key="row.id" :height="row.apexSparkline.height" :options="row.apexSparkline.options" :series="row.apexSparkline.series"></apexchart>
                    </td>
                </template>
            </vue-table>

        </panel-body>
    </panel>
    <!-- END panel -->
</template>

Result as below:

2023-11-12 11 28 25

linmasahiro commented 10 months ago

Hi, @jasonbau component送進slot時已經是object,你應該不再需要把row用大括弧括起來,所以你可以嘗試把 <template v-slot:pageviewsSparklineData="{ row }"> 換成 <template v-slot:pageviewsSparklineData="row" 試試看。

I saw you try to object parse to object, you not need to do that because it always be an object in the slot. So maybe you can try to change <template v-slot:pageviewsSparklineData="{ row }"> to <template v-slot:pageviewsSparklineData="row".

jasonbau commented 10 months ago

我嘗試過了,也是不行...,我在想是不是前面哪裡還有寫錯><

linmasahiro commented 10 months ago

我嘗試過了,也是不行...,我在想是不是前面哪裡還有寫錯><

好,我等等有空幫你看一下 :)

jasonbau commented 10 months ago

感謝你:)

jasonbau commented 10 months ago

大概知道問題了,好像是因為套版包了VueTable.vue包vue3-table-lite,但VueTable.vue似乎沒有把slot的資訊傳到vue3-table-lite,但不確定VueTable.vue要怎麼改比較好。

<script>
import VueTableLite from 'vue3-table-lite'

export default {
    components: {
        VueTableLite,
    }
}
</script>

<template>
  <vue-table-lite />
</template>
linmasahiro commented 10 months ago

大概知道問題了,好像是因為套版包了VueTable.vue包vue3-table-lite,但VueTable.vue似乎沒有把slot的資訊傳到vue3-table-lite,但不確定VueTable.vue要怎麼改比較好。

現在正準備要看,你是說你另外寫了一個component叫做VueTable.vue,裡面是vue3-teble-lite對嗎? 上面這是你VueTable.vue的內容是嗎?我可以用這個結構try看看,不過你這樣再包一層的用意是什麼?

補充:我剛剛看你對VueTable的pageviewsSparklineData插槽插入apexchart,但你的VueTable.vue裡面並沒有定義名為pageviewsSparklineData的插槽,你如果沒在你自創的VueTable裡面定義pageviewsSparklineData插槽的話,你那種寫法是同無效

linmasahiro commented 10 months ago

Hi @jasonbau 我幫你修正好了,這是一個範例,你參考看看 https://codesandbox.io/s/determined-nash-wscc4w?file=/src/App.vue

最主要的關鍵是VueTable需要定義插槽,然後在將 apexchart 插入你 VueTable 中定義的插槽,之後才會從 VueTable 中將組件插入到 vue3-table-lite

jasonbau commented 10 months ago

Hi @linmasahiro 感謝你耶,老實說我也不知道為什麼再包一層,因為我是買template的,我也不太明白用意XD 我後來就直接import vue3-table-lite來做,因為多包一層好像沒甚麼特別意義,但無論如何很感謝你的協助,學到很多。