block by timelyportfolio 4acc0624527bfc9fa78ce15144b90b21

react + antd from R with reactR

Full Screen

Just because we use R does not mean we can’t play with the awesome JavaScript tools React and antd-design.

Example

bl.ock

Code

nearly all JavaScript from this ant-design example

library(htmltools)
library(reactR)
library(pipeR)

antd <- htmlDependency(
  name = "antd",
  version = "2.13.10",
  src = c(href="https://unpkg.com/antd/dist/"),
  script = "antd.min.js",
  stylesheet = "antd.min.css"
)

### steps with button ####
steps_button <- list(
  list(
    title= 'Data',
    content= 'Raw Data'
  ),
  list(
    title= 'Model',
    content= 'Code for Model'
  ),
  list(
    title= 'Plot',
    content= 'Beautiful Plot'
  )
) %>>% jsonlite::toJSON(auto_unbox=TRUE)

content_data <- tags$pre(
  HTML(paste0(
    capture.output(str(iris,max.level=1)),
    collapse="<br/>"
  ))
)

content_model <- tags$pre("lm(Petal.Width~Petal.Length, data=iris)")

content_plot <- HTML(
  svglite::htmlSVG({plot(lm(Petal.Length~Petal.Width,data=iris),which=1)},standalone=FALSE)
)

tagList(
  tags$div(id="stepapp", style="width:30%;"),
  steps_button %>>%
    {
      sprintf(
'
const steps = %s;

steps[0].content = %s;
steps[1].content = %s;
steps[2].content = <img src="%s" />

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      current: 0,
    };
  }
  next() {
    const current = this.state.current + 1;
    this.setState({ current });
  }
  prev() {
    const current = this.state.current - 1;
    this.setState({ current });
  }
  render() {
    const { current } = this.state;
    return (
      <div>
        <antd.Steps current={current} size="small">
          {steps.map(item => <antd.Steps.Step key={item.title} title={item.title} />)}
        </antd.Steps>
      <div className="steps-content">{steps[this.state.current].content}</div>
      <div className="steps-action">
        {
          this.state.current < steps.length - 1
          &&
          <antd.Button type="primary" onClick={() => this.next()}>Next</antd.Button>
        }
        {
          this.state.current === steps.length - 1
          &&
          <antd.Button type="primary" onClick={() => message.success("Processing complete!")}>Done</antd.Button>
        }
        {
          this.state.current > 0
          &&
          <antd.Button style={{ marginLeft: 8 }} type="ghost" onClick={() => this.prev()}>
            Previous
          </antd.Button>
        }
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.querySelector("#stepapp"));
      ',
      .,
      content_data,
      content_model,
      base64enc::dataURI(rsvg::rsvg_png(charToRaw(content_plot)),mime="image/png")
    )
  } %>>%
    babel_transform() %>>%
    HTML %>>%
    tags$script()
) %>>%
  attachDependencies(
    list(
      html_dependency_react(offline=FALSE),
      antd
    )
  ) %>>%
  browsable()