@figlinq/react-chart-editor
v0.51.0
Published
plotly.js chart editor react component UI
Downloads
20
Readme
react-chart-editor
This is Figlinq's fork of Plotly's React Chart Editor. See it in action here: https://create.figlinq.com/create/#/
Demo & Screenshots
Check out the live demo here.
Quick start
Check out the demo of the latest release of the DefaultEditor
at https://figlinq.github.io/react-chart-editor/ or run it locally with:
git clone [this repo]
cd react-chart-editor
cd examples/demo
yarn install
yarn watch
See more examples here.
Overview
This module's entry point is a React component called <PlotlyEditor />
which connects an instance of <EditorControls />
to a plotly.js-powered <Plot />
component care of react-plotly.js
. <PlotlyEditor />
accepts as children React components whose descendents are input elements wrapped via connectToContainer()
calls so as to bind them to the <Plot />
's figure's values. If no children are passed to the <PlotlyEditor />
, the <DefaultEditor />
is used. This module also exposes the building block components that comprise the <DefaultEditor />
so that developers can create their own customized editors.
Styling the <DefaultEditor />
and the built-in components
- Import editor styles with
import 'react-chart-editor/lib/react-chart-editor.min.css'
- Interested in theming?
Development Setup
This repo contains a dev app that depends on the components locally and is configured for hot reloading, for easy local development. A jest
-based test suite is also included.
cp accessTokens.tpl.js accessTokens.js # and edit to taste
yarn install
yarn watch
# hacking happens here
yarn test
Built-in Components
This module provides a number of nestable containers which are intended to contain fields that render widgets that have been connected to individual values in the figure via connector functions. Containers can also be connected to parts of the figure tree (e.g. layout
or specific traces in data
) such that their child fields map to the appropriate leaf values. A field must have a connected container as an ancestor in order to be bound to the figure. The <PlotlyEditor />
and connector functions use the React context
API to push configuration information to child components.
At a pseudo-code level it looks like this:
<PlotlyEditor {...etc}>
<ConnectedContainer {...etc}>
<Field attr="path.to.figure.value" {...etc} />
</ConnectedContainer>
</PlotlyEditor>
The custom editor example shows how to build a custom editor, and shows off all of the general-purpose containers and fields listed below.
General-purpose Containers
<PanelMenuWrapper />
: renders as a sidebar selector menu for<Panel />
s<PlotlyPanel />
: renders as a generic rectangular container with special handling for collapsing/expanding child<Fold />
s and optionally an 'add' button for creating them, has special visibility rules that depend on plotly figure<PlotlyFold />
: collapsable container within a<Panel />
, has special visibility rules that depend on plotly figure<PlotlySection />
: uncollapsable container within a<Panel />
or<Fold />
, has special visibility rules that depend on plotly figure<Panel/>
,<Fold/>
,<Section/>
: same asPlotlyPanel
,PlotlyFold
,PlotlySection
, but there are no special visibility rules, those containers always show, and always show their children, but Fold does not have the canDelete functionality as its context related<SingleSidebarItem/>
: wraps any item you would like to see appear in the sidebar menu.
General-purpose Fields
All Fields except <Info />
accept an attr
property to bind them to a key in the figure (see https://plot.ly/javascript/reference/ for exhaustive documentation of figure keys). This property can be a .
-delimited path to a leaf, starting at the context-appropriate point in the figure for the parent container (see connector functions below).
<Info />
: renders its children as HTML, useful for displaying help text<Numeric />
: renders as a text field with arrows and units, useful for numeric values<Radio />
: renders as a button group, useful for mutually-exclusive low-cardinality enumerable values<Dropdown />
: renders as a dropdown menu useful for mutually-exclusive high-cardinality enumerable values<Dropzone/>
: renders a dropzone component to drag and drop files to load<ColorPicker />
: renders as a popup color-picker, useful for CSS color hex value strings<ColorscalePicker />
: npm module react-colorscales<Flaglist />
: renders as a list of checkboxes, useful for+
-joined flag lists likedata[].mode
<TextEditor />
: renders as a WYSIWYG editor, useful for text likelayout.title
, takes props:latexOnly
,richTextOnly
,htmlOnly
if no format props given, defaults to theMultiFormat
text editor (latex && richText && html)
Widgets
Simple component that takes in props and renders.
<Button/>
: simple button component, useful when combined with<SingleSidebarItem/>
to add as menu item
Special-Purpose Containers
<TraceAccordion />
:<Panel />
whose children are replicated into<Folds />
connected to traces viaconnectTraceToPlot()
.<LayoutPanel />
:<Panel />
whose children are connected to thelayout
figure key<LayoutSection />
:<Section />
whose children are connected to thelayout
figure key<TraceRequiredPanel />
:<LayoutPanel />
renders<PanelEmpty />
if no trace data is set, can add extra conditions (i.e. an array of functions that will be run) with theextraConditions
prop and a matching array with extraEmptyPanelMessages to show when those conditions are not met.<AnnotationAccordion />
:<Panel />
whose children are replicated into<Folds />
connected to annotations viaconnectAnnotationToLayout()
. For use in a<LayoutPanel />
.<ShapeAccordion />
:<Panel />
whose children are replicated into<Folds />
connected to shapes viaconnectShapeToLayout()
. For use in a<LayoutPanel />
.<ImageAccordion />
:<Panel />
whose children are replicated into<Folds />
connected to images viaconnectImageToLayout()
. For use in a<LayoutPanel />
.<AxesFold />
:<Fold />
whose children are bound to axis-specific keys. For use in a<LayoutPanel />
; and automatically contains an<AxesSelector />
(see below).<TraceMarkerSection />
:<Section />
with trace-specific name handling. For use in containers bound to traces e.g. as children of<TraceAccordion />
.
Special-Purpose Fields
For use in containers bound to traces e.g. as children of <TraceAccordion />
:
<DataSelector />
: renders as a<Dropdown />
coupled todata[].*src
etc, triggersonUpdateTraces
when changed<TraceSelector />
: renders as a<Dropdown />
useful fordata[].type
<LineDashSelector />
: renders as a<Dropdown />
useful fordata[].line.dash
<LineShapeSelector />
: renders as a<Dropdown />
useful fordata[].line.shape
<SymbolSelector />
: renders as a<Dropdown />
useful fordata[].marker.symbol
<PositioningRef />
: renders as a<Dropdown />
useful forlayout.*.xref/yref
where the allowable values arepaper|[axis]
<ErrorBars/>
: renders a set of controls that control a trace's error bars (visibility
,type
,value
,valueminus
,array
,arrayminus
)
For use in containers bound to layout:
<FontSelector />
: renders as a<Dropdown />
whose options are rendered in the selected font<CanvasSize />
: renders as a<Numeric />
with visibility coupled tolayout.autosize
For use in containers bound to axes:
<AxesSelector />
: renders as a<Radio />
to select one or all axes. Must be in a container bound to a figure viaconnectAxesToPlot()
and sets that container's context such that its children are bound to either all axes or just the selected one.<AxesFold>
s automatically contain this component.<AxesRange />
: numeric with visibility coupled tolayout.*axis.autorange
For use in containers bound to annotations e.g. as children of <AnnotationAccordion />
:
<AnnotationRef />
: renders as a<Dropdown />
useful forlayout.annotations[].xref
,layout.annotations[].yref
<AnnotationArrowRef />
: renders as a<Dropdown />
useful forlayout.annotations[].axref
,layout.annotations[].ayref
<ArrowSelector />
: renders as a<Dropdown />
useful forlayout.annotations[].arrowhead
Connector functions
connectToContainer( Component )
: returns a field component that can be bound to a figure value via theattr
prop.connectTraceToPlot( Container )
: returns a wrapped container component that can be bound to a figure trace such that its children are bound to that trace's figure entry under thedata
key, e.g.<TraceAccordion />
above.connectLayoutToPlot( Container )
: returns a wrapped container component that can be bound to a figure such that its children are bound to that figure's layout under thelayout
key.connectAxesToLayout( Container )
: returns a wrapped container component that should contain an<AxesSelector />
field (see above) and can be bound to a figure such that its children are bound to that figure's axes entries under thelayout.*axis
keys.connectAnnotationToLayout( Container )
: returns a wrapped container component that can be bound to a figure annotation such that its children are bound to that annotation's figure entry under thelayout.annotations
key, e.g. the<Fold>
s in<AnnotationAccordion />
above.connectShapeToLayout( Container )
: returns a wrapped container component that can be bound to a shape such that its children are bound to that shape's figure entry under thelayout.shapes
key, e.g. the<Fold>
s in<ShapeAccordion />
above.connectImagesToLayout( Container )
: returns a wrapped container component that can be bound to an image such that its children are bound to that image's figure entry under thelayout.image
key, e.g. the<Fold>
s in<ImageAccordion />
above.
Action History
You can show/hide undo/redo buttons via showUndoRedo
prop of <PlotlyEditor />
.
You can trigger undo/redo actions programmatically by passing a ref to PlotlyEditor
or EditorControls
and calling undo
or redo
methods on the ref. E.g.:
const rceRef = useRef(null);
...
<EditModeController
ref={rceRef}
...
/>
...
rceRef.current.undo()
Use onAddToUndo
and onAddToRedo
hooks to trigger events when an action is added to undo or redo history in the <PlotlyEditor />
component.
<PlotlyEditor
...
onAddToUndo={() => { console.log('action added to undo') }}
onAddToRedo={() => { console.log('action added to redo') }}
/>
Mapbox Access Tokens
To use Satellite Maps in the Editor, Mapbox access tokens are required.
Once you have your tokens, you can provide it as a config prop to the <PlotlyEditor />
component: <PlotlyEditor config={{mapboxAccessToken: 'your token'}}/>
See also
License
© 2022 Figlinq, Inc. MIT License.