【BI看板】Superset时间过滤控件二次开发

有没有人发觉Superset时间过滤组件非常高级,但又有点复杂,没有选择时间区间的快捷方式。

Superset的时间过滤控件可以通过在代码中进行二次开发来进行定制。以下是一些可能有用的提示:

  1. 查找源代码:可以在Superset的源代码中找到时间过滤器的相关代码,在superset/assets/src/explore/components/controls目录下搜索时间控件的名称,比如DateFilterControl.jsx

  2. 深入理解时间控件:了解时间控件是如何工作的非常重要,可以通过阅读Superset的源代码和官方文档来学习。

  3. 编写自定义时间控件:可以使用React等工具编写自定义时间控件,然后将其与Superset集成。可以在前端开发人员手册中找到相关的信息。

  4. 集成自定义时间控件:集成自定义时间控件的过程取决于它的实现方式和您的Superset部署环境。可以参考官方文档中的信息来集成您的自定义时间控件。

  5. 测试:一旦自定义时间控件被集成,需要对其进行测试以确保它正常工作。这包括测试常见的时间过滤器用例,以及测试它在不同的浏览器和设备上是否正常显示。

过滤参数,入参time_range

【BI看板】Superset时间过滤控件二次开发_第1张图片

图表有两种接口

/superset/explore_json/?form_data

目录:\superset-2.0\superset\views\core.py

@api
    @has_access_api
    @handle_api_exception
    @event_logger.log_this
    @expose(
        "/explore_json///",
        methods=EXPLORE_JSON_METHODS,
    )
    @expose("/explore_json/", methods=EXPLORE_JSON_METHODS)
    @etag_cache()
    @check_resource_permissions(check_datasource_perms)
    def explore_json(
        self, datasource_type: Optional[str] = None, datasource_id: Optional[int] = None
    ) -> FlaskResponse:
        """Serves all request that GET or POST form_data

        This endpoint evolved to be the entry point of many different
        requests that GETs or POSTs a form_data.

        `self.generate_json` receives this input and returns different
        payloads based on the request args in the first block

        TODO: break into one endpoint for each return shape"""

        response_type = ChartDataResultFormat.JSON.value
        responses: List[Union[ChartDataResultFormat, ChartDataResultType]] = list(
            ChartDataResultFormat
        )
        responses.extend(list(ChartDataResultType))
        for response_option in responses:
            if request.args.get(response_option) == "true":
                response_type = response_option
                break

        # Verify user has permission to export CSV file
        if (
            response_type == ChartDataResultFormat.CSV
            and not security_manager.can_access("can_csv", "Superset")
        ):
            return json_error_response(
                _("You don't have the rights to ") + _("download as csv"),
                status=403,
            )

        form_data = get_form_data()[0]
        try:
            datasource_id, datasource_type = get_datasource_info(
                datasource_id, datasource_type, form_data
            )

            force = request.args.get("force") == "true"

            # TODO: support CSV, SQL query and other non-JSON types
            if (
                is_feature_enabled("GLOBAL_ASYNC_QUERIES")
                and response_type == ChartDataResultFormat.JSON
            ):
                # First, look for the chart query results in the cache.
                try:
                    viz_obj = get_viz(
                        datasource_type=cast(str, datasource_type),
                        datasource_id=datasource_id,
                        form_data=form_data,
                        force_cached=True,
                        force=force,
                    )
                    payload = viz_obj.get_payload()
                    # If the chart query has already been cached, return it immediately.
                    if payload is not None:
                        return self.send_data_payload_response(viz_obj, payload)
                except CacheLoadError:
                    pass

                # Otherwise, kick off a background job to run the chart query.
                # Clients will either poll or be notified of query completion,
                # at which point they will call the /explore_json/data/
                # endpoint to retrieve the results.
                try:
                    async_channel_id = async_query_manager.parse_jwt_from_request(
                        request
                    )["channel"]
                    job_metadata = async_query_manager.init_job(
                        async_channel_id, g.user.get_id()
                    )
                    load_explore_json_into_cache.delay(
                        job_metadata, form_data, response_type, force
                    )
                except AsyncQueryTokenException:
                    return json_error_response("Not authorized", 401)

                return json_success(json.dumps(job_metadata), status=202)

            viz_obj = get_viz(
                datasource_type=cast(str, datasource_type),
                datasource_id=datasource_id,
                form_data=form_data,
                force=force,
            )

            return self.generate_json(viz_obj, response_type)
        except SupersetException as ex:
            return json_error_response(utils.error_msg_from_exception(ex), 400)

/api/v1/chart/data?form_data=

目录:\superset\charts\data\api.py

该接口还比较难找哈

class ChartDataRestApi(ChartRestApi):
    include_route_methods = {"get_data", "data", "data_from_cache"}

    @expose("//data/", methods=["GET"])
    @protect()
    @statsd_metrics
    @event_logger.log_this_with_context(
        action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.data",
        log_to_statsd=False,
    )
    def get_data(self, pk: int) -> Response:

chart = self.datamodel.get(pk, self._base_filters)
        if not chart:
            return self.response_404()

        try:
            json_body = json.loads(chart.query_context)
        except (TypeError, json.decoder.JSONDecodeError):
            json_body = None

        if json_body is None:
            return self.response_400(
                message=_(
                    "Chart has no query context saved. Please save the chart again."
                )
            )

        # override saved query context
        json_body["result_format"] = request.args.get(
            "format", ChartDataResultFormat.JSON
        )
        json_body["result_type"] = request.args.get("type", ChartDataResultType.FULL)
。。。。。
。。。。。
。。。。。
        # TODO: support CSV, SQL query and other non-JSON types
        if (
            is_feature_enabled("GLOBAL_ASYNC_QUERIES")
            and query_context.result_format == ChartDataResultFormat.JSON
            and query_context.result_type == ChartDataResultType.FULL
        ):
            return self._run_async(json_body, command)

        try:
            form_data = json.loads(chart.params)
        except (TypeError, json.decoder.JSONDecodeError):
            form_data = {}

        return self._get_data_response(
            command=command, form_data=form_data, datasource=query_context.datasource
        )

时间过滤控件

计算时间范围

venv38\Lib\site-packages\marshmallow\schema.py

【BI看板】Superset时间过滤控件二次开发_第2张图片

再往下,计算日期地方

data = processor(data, many=many, **kwargs)

【BI看板】Superset时间过滤控件二次开发_第3张图片

再往下在superset\common\query_object_factory.py,可以看到from_dttm和to_dttm

【BI看板】Superset时间过滤控件二次开发_第4张图片

        processed_extras = self._process_extras(extras)
        result_type = kwargs.setdefault("result_type", parent_result_type)
        row_limit = self._process_row_limit(row_limit, result_type)
        from_dttm, to_dttm = self._get_dttms(time_range, time_shift, processed_extras)
        kwargs["from_dttm"] = from_dttm
        kwargs["to_dttm"] = to_dttm
        return QueryObject(
            datasource=datasource_model_instance,
            extras=extras,
            row_limit=row_limit,
            time_range=time_range,
            time_shift=time_shift,
            **kwargs,
        )

进行定制或二次开发

如果需要对Superset中的时间过滤控件进行定制或二次开发,可以按照以下步骤进行:

  • 复制时间过滤控件的源代码

Superset中的时间过滤控件源代码位于superset/assets/src/explore/components/controls/DateFilterControl.jsx,可以将该文件复制到本地进行修改。

  • 修改时间过滤控件的样式或行为

可以根据需要修改时间过滤控件的样式或行为,比如修改日期格式、修改默认时间段等。修改完成后,可以运行npm run build命令进行编译。

  • 将修改后的时间过滤控件发布到Superset中

将修改后的时间过滤控件发布到Superset中有两种方法:

  • 将修改后的代码替换掉原来的文件,然后重新启动Superset;
  • 将修改后的代码打包成一个插件,然后通过Superset的插件机制进行安装和使用。

至此,定制化或二次开发Superset的时间过滤控件就完成了。

你可能感兴趣的:(软件研发,Python,python,大数据)