将响应式网格布局转换为plot Dash



我是一个非常活跃的Dash用户,我已经开始在Dash使用中发现很多限制,我意识到关于如何将组件转换为Dash的信息/内容绝对有限,有过时的和非常简单的例子……而且我对Javascript或React几乎没有任何知识,我完全不知道如何转换组件。

我试图将响应式网格布局组件从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
};

任何帮助或参考都是非常欢迎的…

问候,莱昂纳多

实现自定义组件

如果您只想使用库中的组件,并通过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,
};

环境设置(如果您已经这样做了,请跳过)

要创建和编辑您的自定义组件,您需要按照说明设置cookecutter。

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

  • Installcookiecutter:pip install cookiecutter
  • 运行cookiecutterhttps://github.com/plotly/dash-component-boilerplate.git。这将生成您可以创建自定义组件的环境。
  • 在填写了您希望自定义组件的名称后,将目录更改为基于您提供的名称生成的目录。我选择了grid_layout这个名字,如果你在cookiecutter的提示下选择不同的值,你的结构会不一样。
  • 此时,您需要通过运行pip install -r requirements.txt来安装所需的python依赖项。你现在也可以使用npm i react-grid-layout来安装react-grid-layout

基本用法当一切安装完成后,我们可以在src/lib/components目录中编辑自定义组件。当我们做了一些更改(用上面列出的代码替换了示例代码)并且我们可以运行npm run build来持久化更改时,

在此之后,你可以运行python usage.py和你的dash应用程序使用您的自定义组件将运行。

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)

你也可以根据自己的喜好编辑。

最新更新