简体   繁体   English

在 react.js 中过滤/更新已经呈现 chart.js

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

I'm new here, because I have decided to dive into programming, so I can fill free time between treatments in the hospital.我是新来的,因为我决定潜心研究编程,这样我就可以在医院治疗之间填补空闲时间。 I'm absolutely new in the programming field with no previous coding background.我是编程领域的新手,没有以前的编码背景。

The summary:摘要:

I am working on a simple page, where I fetch data from a Postgre database that is visualized using chart.js.我正在处理一个简单的页面,我从 Postgre 数据库中获取数据,该数据库使用 chart.js 进行可视化。 The page is a built-in cube.js playground, using a Reactjs template.该页面是一个内置的 cube.js 游乐场,使用 Reactjs 模板。 Currently, I can display various charts depending on my criteria.目前,我可以根据我的标准显示各种图表。 Like display monthly sales of a certain product in Australia.比如显示某种产品在澳大利亚的月销售额。 Or, I can display a second chart with daily sales in the countries I choose.或者,我可以显示第二张图表,其中包含我选择的国家/地区的每日销售额。 Or ignore all sales that were in a certain currency.或者忽略以某种货币计价的所有销售。 Right now, every new criterion means I have to use cube.js playground and generate a new chart on the page.现在,每一个新标准都意味着我必须使用 cube.js 游乐场并在页面上生成一个新图表。 What I would like to achieve is to be able to filter already rendered charts (by a dropdown button outside the chart or inside the chart, it doesn't matter too much) and having the chart updated.我想要实现的是能够过滤已经呈现的图表(通过图表外部或图表内部的下拉按钮,这并不重要)并更新图表。 Something like the pictures here , where the OP can filter charts based on the date, factory, etc.类似于这里的图片,OP 可以根据日期、工厂等过滤图表。

I've tried Chart.js Example with Dynamic Dataset , chart.js tutorial on Updating Charts and various others.我试过Chart.js Example with Dynamic Datasetchart.js tutorial on Updating Charts和其他各种。 But I can't seem to be able to implement any of those solutions in my code.但我似乎无法在我的代码中实现任何这些解决方案。

Here is my current code:这是我当前的代码:

ChartRenderer.js 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;

DashBoardPage.js仪表板页面.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;

At this moment, I have no clue how to implement the filter in react.js+chart.js.目前,我不知道如何在 react.js+chart.js 中实现过滤器。 I have also tried to update the array, but no success ( I followed also this tutorial ) I would be most grateful for any help.我也尝试过更新数组,但没有成功(我也遵循了本教程)我将非常感谢任何帮助。

Thank you in advance, stay healthy.提前谢谢你,保持健康。 Tatsu

I'd recommend using the <QueryBuilder/> component available in the Cube.js-React integration ;我建议使用Cube.js-React 集成中提供的<QueryBuilder/>组件 this component provides a similar interface as that in the Developer Playground.该组件提供了与 Developer Playground 中类似的界面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM