1

我是一个非常活跃的 Dash 用户,我开始发现我的 Dash 使用有很多限制,我意识到关于如何将组件转换为 dash 的信息/内容是绝对有限的,有过时且非常简单的示例......并且我对 Javascript 或 React 几乎一无所知,我完全不知道如何转换组件。

我正在尝试将 Responsive Grid Layout 组件从 react.js 转换为 Plotly Dash 但我不知道在这种情况下我应该如何处理这些属性?组件链接: https ://github.com/STRML/react-grid-layout/blob/master/lib/ResponsiveReactGridLayout.jsx

由于我没有使用 react.js 的经验,我很困惑我应该做哪些修改才能将此组件转换为 Plotly Dash。

在上面的组件的情况下,我应该只在 Proptypes 上声明属性(如下所示)还是需要做更多的修改?

ResponsiveReactGridLayout.propTypes{
  //
  // Basic props
  //
  className: PropTypes.string,
  style: PropTypes.object,

  // This can be set explicitly. If it is not set, it will automatically
  // be set to the container width. Note that resizes will *not* cause this to adjust.
  // If you need that behavior, use WidthProvider.
  width: PropTypes.number,

  // If true, the container height swells and contracts to fit contents
  autoSize: PropTypes.bool,
  // # of cols.
  cols: PropTypes.number,

  // A selector that will not be draggable.
  draggableCancel: PropTypes.string,
  // A selector for the draggable handler
  draggableHandle: PropTypes.string,

  // Deprecated
  verticalCompact: function (props: Props) {
    if (
      props.verticalCompact === false &&
      process.env.NODE_ENV !== "production"
    ) {
      console.warn(
        // eslint-disable-line no-console
        "`verticalCompact` on <ReactGridLayout> is deprecated and will be removed soon. " +
          'Use `compactType`: "horizontal" | "vertical" | null.'
      );
    }
  },
  // Choose vertical or hotizontal compaction
  compactType: PropTypes.oneOf(["vertical", "horizontal"]),

  // layout is an array of object with the format:
  // {x: Number, y: Number, w: Number, h: Number, i: String}
  layout: function (props: Props) {
    var layout = props.layout;
    // I hope you're setting the data-grid property on the grid items
    if (layout === undefined) return;
    require("./utils").validateLayout(layout, "layout");
  },

  //
  // Grid Dimensions
  //

  // Margin between items [x, y] in px
  margin: PropTypes.arrayOf(PropTypes.number),
  // Padding inside the container [x, y] in px
  containerPadding: PropTypes.arrayOf(PropTypes.number),
  // Rows have a static height, but you can change this based on breakpoints if you like
  rowHeight: PropTypes.number,
  // Default Infinity, but you can specify a max here if you like.
  // Note that this isn't fully fleshed out and won't error if you specify a layout that
  // extends beyond the row capacity. It will, however, not allow users to drag/resize
  // an item past the barrier. They can push items beyond the barrier, though.
  // Intentionally not documented for this reason.
  maxRows: PropTypes.number,

  //
  // Flags
  //
  isBounded: PropTypes.bool,
  isDraggable: PropTypes.bool,
  isResizable: PropTypes.bool,
  // If true, grid items won't change position when being dragged over.
  preventCollision: PropTypes.bool,
  // Use CSS transforms instead of top/left
  useCSSTransforms: PropTypes.bool,
  // parent layout transform scale
  transformScale: PropTypes.number,
  // If true, an external element can trigger onDrop callback with a specific grid position as a parameter
  isDroppable: PropTypes.bool,

  // Resize handle options
  resizeHandles: resizeHandlesType,
  resizeHandle: resizeHandleType,

  //
  // Callbacks
  //

  // Callback so you can save the layout. Calls after each drag & resize stops.
  onLayoutChange: PropTypes.func,

  // Calls when drag starts. Callback is of the signature (layout, oldItem, newItem, placeholder, e, ?node).
  // All callbacks below have the same signature. 'start' and 'stop' callbacks omit the 'placeholder'.
  onDragStart: PropTypes.func,
  // Calls on each drag movement.
  onDrag: PropTypes.func,
  // Calls when drag is complete.
  onDragStop: PropTypes.func,
  //Calls when resize starts.
  onResizeStart: PropTypes.func,
  // Calls when resize movement happens.
  onResize: PropTypes.func,
  // Calls when resize is complete.
  onResizeStop: PropTypes.func,
  // Calls when some element is dropped.
  onDrop: PropTypes.func,

  //
  // Other validations
  //

  droppingItem: PropTypes.shape({
    i: PropTypes.string.isRequired,
    w: PropTypes.number.isRequired,
    h: PropTypes.number.isRequired
  }),

  // Children must not have duplicate keys.
  children: function (props: Props, propName: string) {
    var children = props[propName];

    // Check children keys for duplicates. Throw if found.
    var keys = {};
    React.Children.forEach(children, function (child) {
      if (keys[child.key]) {
        throw new Error(
          'Duplicate child key "' +
            child.key +
            '" found! This will cause problems in ReactGridLayout.'
        );
      }
      keys[child.key] = true;
    });
  },

  // Optional ref for getting a reference for the wrapping div.
  innerRef: PropTypes.any
};

非常欢迎任何帮助或参考...

问候,莱昂纳多

4

1 回答 1

3

实现自定义组件

如果您只想使用库中的组件以及通过npm(如react-grid-layout)提供的包,则无需重新实现这些库中的组件。您可以简单地安装它们npm并在您的自定义组件中使用它们。

ResponsiveGridLayout使用( )的示例组件src/lib/components/GridLayout.react.js

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import RGL, {WidthProvider} from 'react-grid-layout';
import '../../../node_modules/react-grid-layout/css/styles.css';
import '../../../node_modules/react-resizable/css/styles.css';

const ResponsiveGridLayout = WidthProvider(RGL);

export default class GridLayout extends Component {
    render() {
        const {id, setProps} = this.props;
        const layout = [
            {x: 0, y: 0, w: 3, h: 3, i: 'a'},
            {x: 0, y: 1, w: 3, h: 3, i: 'b'},
        ];

        return (
            <div id={id}>
                <ResponsiveGridLayout rowHeight={30}>
                    {layout.map((item) => (
                        <div key={item.i} data-grid={item}>
                            <span>{item.i}</span>
                        </div>
                    ))}
                </ResponsiveGridLayout>
            </div>
        );
    }
}

GridLayout.defaultProps = {};

GridLayout.propTypes = {
    /**
     * The ID used to identify this component in Dash callbacks.
     */
    id: PropTypes.string,

    /**
     * Dash-assigned callback that should be called to report property changes
     * to Dash, to make them available for callbacks.
     */
    setProps: PropTypes.func,
};

环境设置(如果您已经完成,请跳过)

要创建和编辑您的自定义组件,您需要按照说明设置cookiecutter dash-component-boilerplate

但是要重申几个要点中所说的内容,您需要:

  • 安装cookiecutterpip install cookiecutter
  • 运行 cookiecutter https://github.com/plotly/dash-component-boilerplate.git。这将生成您可以创建自定义组件的环境。
  • 填写名称后,您希望自定义组件让您将目录更改为根据您提供的名称生成的目录。我已经选择了名称grid_layout,如果您在提示后选择不同的值,您的结构会有所不同cookiecutter
  • 此时您需要通过运行pip install -r requirements.txt. 您现在也可以react-grid-layout使用npm i react-grid-layout.

基本用法

src/lib/components安装完所有内容后,我们可以在目录中编辑自定义组件。当我们进行了一些更改(将示例代码替换为上面列出的代码)并且我们感到满意时,我们可以运行npm run build以保持更改。

在此之后,您可以运行python usage.py并且使用您的自定义组件的仪表板应用程序将运行。

usage.py是一个常规Dash应用程序,它导入在构建过程之后从组件生成的react组件,看起来像这样:

import grid_layout
import dash
from dash.dependencies import Input, Output
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([grid_layout.GridLayout(id="grid-layout")])


if __name__ == "__main__":
    app.run_server(debug=True)

您也可以根据需要编辑它。

于 2021-02-10T17:00:10.777 回答