簡體   English   中英

在 react.js 中過濾/更新已經呈現 chart.js

[英]Filter/update already rendered chart.js in react.js

我是新來的,因為我決定潛心研究編程,這樣我就可以在醫院治療之間填補空閑時間。 我是編程領域的新手,沒有以前的編碼背景。

摘要:

我正在處理一個簡單的頁面,我從 Postgre 數據庫中獲取數據,該數據庫使用 chart.js 進行可視化。 該頁面是一個內置的 cube.js 游樂場,使用 Reactjs 模板。 目前,我可以根據我的標准顯示各種圖表。 比如顯示某種產品在澳大利亞的月銷售額。 或者,我可以顯示第二張圖表,其中包含我選擇的國家/地區的每日銷售額。 或者忽略以某種貨幣計價的所有銷售。 現在,每一個新標准都意味着我必須使用 cube.js 游樂場並在頁面上生成一個新圖表。 我想要實現的是能夠過濾已經呈現的圖表(通過圖表外部或圖表內部的下拉按鈕,這並不重要)並更新圖表。 類似於這里的圖片,OP 可以根據日期、工廠等過濾圖表。

我試過Chart.js Example with Dynamic Datasetchart.js tutorial on Updating Charts和其他各種。 但我似乎無法在我的代碼中實現任何這些解決方案。

這是我當前的代碼:

ChartRenderer.js

import React from "react";
import PropTypes from "prop-types";
import { useCubeQuery } from "@cubejs-client/react";
import Row from "react-bootstrap/Row";
import Spin from "react-bootstrap/Spinner";
import Col from "react-bootstrap/Col";
import { Statistic, Table } from "antd";
import { Line, Bar, Pie } from "react-chartjs-2";
const COLORS_SERIES = [
    "#931F1D",
    "#141446",
    "#7A77FF",
];
const commonOptions = {
    maintainAspectRatio: true,
};
const TypeToChartComponent = {
    line: ({ resultSet }) => {
        const data = {
            labels: resultSet.categories().map((c) => c.category),
            datasets: resultSet.series().map((s, index) => ({
                label: s.title,
                data: s.series.map((r) => r.value),
                borderColor: COLORS_SERIES[index],
                backgroundColor: COLORS_SERIES[index],
                fill: false,
                tension: 0.4,
            })),
        };
        const options = { ...commonOptions };
        return <Line data={data} options={options} />;
    },
    bar: ({ resultSet }) => {
        const data = {
            labels: resultSet.categories().map((c) => c.category),
            datasets: resultSet.series().map((s, index) => ({
                label: s.title,
                data: s.series.map((r) => r.value),
                backgroundColor: COLORS_SERIES[index],
                fill: false,
            })),
        };
        const options = {
            ...commonOptions,
            scales: {
                xAxes: [
                    {
                        stacked: true,
                    },
                ],
            },
        };
        return <Bar data={data} options={options} />;
    },
    area: ({ resultSet }) => {
        const data = {
            labels: resultSet.categories().map((c) => c.category),
            datasets: resultSet.series().map((s, index) => ({
                label: s.title,
                data: s.series.map((r) => r.value),
                backgroundColor: COLORS_SERIES[index],
                fill: true,
            })),
        };
        const options = {
            ...commonOptions,
            scales: {
                yAxes: [
                    {
                        stacked: true,
                    },
                ],
            },
        };
        return <Line data={data} options={options} />;
    },
    pie: ({ resultSet }) => {
        const data = {
            labels: resultSet.categories().map((c) => c.category),
            datasets: resultSet.series().map((s) => ({
                label: s.title,
                data: s.series.map((r) => r.value),
                backgroundColor: COLORS_SERIES,
                hoverBackgroundColor: COLORS_SERIES,
                borderColor: COLORS_SERIES,
                hoverBorderColor: "white",
                hoverOffset: 10,
            })),
        };
        const options = { ...commonOptions };
        return <Pie data={data} options={options} />;
    },
    number: ({ resultSet }) => {
        return (
            <Row
                type="flex"
                justify="space-around"
                align="middle"
                style={{ height: "100%" }}
            >
                <Col align="left">
                    {resultSet.seriesNames().map((s) => (
                        <Statistic value={resultSet.totalRow()[s.key]} />
                    ))}
                </Col>
            </Row>
        );
    },
    table: ({ resultSet, pivotConfig }) => {
        return (
            <Table
                pagination={false}
                columns={resultSet.tableColumns(pivotConfig)}
                dataSource={resultSet.tablePivot(pivotConfig)}
            />
        );
    },
};


const TypeToMemoChartComponent = Object.keys(TypeToChartComponent)
    .map((key) => ({
        [key]: React.memo(TypeToChartComponent[key]),
    }))
    .reduce((a, b) => ({ ...a, ...b }));

const renderChart =
    (Component) =>
    ({ resultSet, error }) =>
        (resultSet && <Component resultSet={resultSet} />) ||
        (error && error.toString()) || <Spin animation="grow text-primary" />;

const ChartRenderer = ({ vizState }) => {
    const { query, chartType } = vizState;
    const component = TypeToMemoChartComponent[chartType];
    const renderProps = useCubeQuery(query);
    return component && renderChart(component)(renderProps);
};

ChartRenderer.propTypes = {
    vizState: PropTypes.object,
    cubejsApi: PropTypes.object,
};

ChartRenderer.defaultProps = {
    vizState: {},
    cubejsApi: null,
};

export default ChartRenderer;

儀表板頁面.js

import React from "react";
import Col from "react-bootstrap/Col";
import DateRangePicker from 'react-bootstrap-daterangepicker';
import ChartRenderer from "../components/ChartRenderer";
import Dashboard from "../components/Dashboard";
import DashboardItem from "../components/DashboardItem";

const DashboardItems = [
    {
        id: 0,
        name: "Sold by customers today",
        vizState: {
            query: {
                measures: ["PostgreSqlTable.amount"],
                timeDimensions: [
                    {
                        dimension: "PostgreSqlTable.added",
                        granularity: "day",
                        dateRange: "Today",
                    },
                ],
                order: {},
                dimensions: [],
                filters: [
                    {
                        member: "PostgreSqlTable.operation",
                        operator: "contains",
                        values: ["Sell"],
                    },
                ],
            },
            chartType: "number",
        },
    },
    {
        id: 1,
        name: "Bought by customers today",
        vizState: {
            query: {
                measures: ["PostgreSqlTable.amount"],
                timeDimensions: [
                    {
                        dimension: "PostgreSqlTable.added",
                        dateRange: "Today",
                    },
                ],
                order: {},
                filters: [
                    {
                        member: "PostgreSqlTable.operation",
                        operator: "contains",
                        values: ["Buy"],
                    },
                ],
            },
            chartType: "number",
        },
    },
    {
        id: 2,
        name: "Money in the wallet",
        vizState: {
            query: {
                measures: ["PostgreSqlTable.amount"],
                timeDimensions: [
                    {
                        dimension: "PostgreSqlTable.added",
                    },
                ],
                order: {
                    "PostgreSqlTable.amount": "desc",
                },
                dimensions: ["PostgreSqlTable.currency"],
                filters: [
                    {
                        member: "PostgreSqlTable.currency",
                        operator: "equals",
                        values: ["EUR"],
                    },
                ],
            },
            chartType: "number",
        },
    },
    {
        id: 3,
        name: "Monthly sales filtered by week",
        vizState: {
            query: {
                measures: ["PostgreSqlTable.amount"],
                timeDimensions: [
                    {
                        dimension: "PostgreSqlTable.added",
                        granularity: "week",
                        dateRange: "This month",
                    },
                ],
                order: {
                    "PostgreSqlTable.amount": "desc",
                },
                dimensions: ["PostgreSqlTable.operation"],
                filters: [
                    {
                        member: "PostgreSqlTable.operation",
                        operator: "notContains",
                        values: ["Register"],
                    },
                ],
                limit: 5000,
            },
            chartType: "line",
        },
    },
    {
        id: 4,
        name: "Countries with most customers",
        vizState: {
            query: {
                measures: ["PostgreSqlTable.count"],
                timeDimensions: [
                    {
                        dimension: "PostgreSqlTable.added",
                    },
                ],
                order: {
                    "PostgreSqlTable.count": "desc",
                },
                dimensions: ["PostgreSqlTable.country"],
                limit: 5,
            },
            chartType: "pie",
        },
    },
];


const DashboardPage = () => {
    const dashboardItem = (item) => (
        <Col className="col-4">
            <DashboardItem title={item.name}>
                <ChartRenderer vizState={item.vizState} />
                
            </DashboardItem>
        </Col>
    );

    const Empty = () => (
        <div
            style={{
                textAlign: "center",
                padding: 12,
            }}
        >
            <h2>
                No items added
            </h2>
        </div>
    );

    return DashboardItems.length ? (
        <Dashboard dashboardItems={DashboardItems}>
            {DashboardItems.map(dashboardItem)}
        </Dashboard>
    ) : (
        <Empty />
    );
};

export default DashboardPage;

目前,我不知道如何在 react.js+chart.js 中實現過濾器。 我也嘗試過更新數組,但沒有成功(我也遵循了本教程)我將非常感謝任何幫助。

提前謝謝你,保持健康。

我建議使用Cube.js-React 集成中提供的<QueryBuilder/>組件 該組件提供了與 Developer Playground 中類似的界面。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM