Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support React #24

Closed
tobiaslins opened this issue Nov 2, 2017 · 22 comments
Closed

Support React #24

tobiaslins opened this issue Nov 2, 2017 · 22 comments

Comments

@tobiaslins
Copy link
Contributor

tobiaslins commented Nov 2, 2017

Currently it is not possible to use this library with React (easily).

Some modifications are needed to use it.

I want to discuss what should happen in this repository and what not.

I already did small changes to use it as a simple React component.

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Frappe from 'frappe-charts/src/scripts/charts.js'

import 'frappe-charts/dist/frappe-charts.min.css' // to import styling

class Chart extends Component {
  componentDidMount() {
    const {title, data, type = 'bar', height = 250} = this.props
    this.c = new Frappe({
      parent: this.chart,
      title,
      data,
      type,
      height
    })
  }

  render() {
    return <div ref={chart => (this.chart = chart)}/>
  }
}

export default Chart

I created a demo repo for showcase: https://github.com/tobiaslins/frappe-charts-react-example

@achillesrasquinha
Copy link
Contributor

@tobiaslins, Could you add your credits to our README with reference to your example? 😄

@tobiaslins
Copy link
Contributor Author

tobiaslins commented Nov 6, 2017

@achillesrasquinha how do you want it to be added? :)

New section for example & credits?

I'll update my example as soon as you released the new version on NPM!
Edit: Already updated to use offical 0.0.4 release! Thanks :)

@tobiaslins
Copy link
Contributor Author

tobiaslins commented Nov 8, 2017

@achillesrasquinha @pratu16x7

I just started to use it within my current react project and figured out that I'll need to adapt it.
I want to update the chart as soon as the react properties where changed.

The strange thing is - if I call the method with the new labels and values with following code

this.c.update_values( [{ values: props.data.datasets[0].values }], props.data.labels)

The chart is rerendered with the labels and hover is working - but the actual bars are not shown and I'm getting errors.
First line are the values & second labels
image

image

Do you know what the problem could be?

My initial chart data was:

data: {
  labels: [],
  datasets: [{ color: 'red', values: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1] }]
},

Edit
I just recognized that it is rendering corretly if I initialize the chart with the same amount of values/labels. That is a problem in my opinion. It should be possible to run update_values with a complete different amount of data. (probably fill the missing data with zeros)

@viperfx
Copy link

viperfx commented Nov 10, 2017

Great work. React support would be an awesome addition to this lib 👍

What is possible right now with React with v0.0.4 of the lib?

@viperfx
Copy link

viperfx commented Nov 11, 2017

@tobiaslins just wondering if you have figured out click handler support within react? Say for handling clicks for the heat map squares?

@tobiaslins
Copy link
Contributor Author

@viperfx I'll update the react component in the following days. It is currently NOT updating on prop changes & not supporting click handlers atm.

@charlesrochati
Copy link

@tobiaslins

I've come to this solution (to update the chart on props changes):

import React from 'react'
import PropTypes from 'prop-types'
import Chart from 'frappe-charts/dist/frappe-charts.min.esm'
import 'frappe-charts/dist/frappe-charts.min.css'
class ChartBuilder extends React.Component {
  
  componentDidMount () {
    const { title, data, type, height } = this.props
    this.c = new Chart({ parent: this.chart, title, data, type, height });
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps && !nextProps.data || this.props.data !== nextProps.data) {
      const { title, data, type, height } = nextProps;
      this.c = new Chart({ parent: this.chart, title, data, type, height });
    }
  }

  render () {
    return (<div ref={ chart => (this.chart = chart) } />)
  }
}

export default ChartBuilder

Build a chart:

import React from 'react'
import PropTypes from 'prop-types'
import ChartBuilder from './ChartBuilder'
import { BAR } from './ChartType'
import { defaultChartPropTypes } from './defaults';

class BarChart extends React.Component {
    render() {
        return <ChartBuilder { ...this.props } />
    }
}

BarChart.defaultProps = {
    type: BAR
}

BarChart.propTypes = defaultChartPropTypes;

export default BarChart

We have to do a better check at this point:

 if (nextProps && !nextProps.data || this.props.data !== nextProps.data) {

But the chart gets updated properly.


How i used it:

import React, { Component } from 'react'
import { render } from 'react-dom'
import PropTypes from 'prop-types'
import BarChart from '../lib/BarChart'
import LineChart from '../lib/LineChart'
import PercentageChart from '../lib/PercentageChart'
import PieChart from '../lib/PieChart'
import ScatterChart from '../lib/ScatterChart'

class App extends React.Component {

  constructor() {
    super();

    this.state = {
        data: {
          labels: ['12am-3am', '3am-6pm', '6am-9am', '9am-12am',
            '12pm-3pm', '3pm-6pm', '6pm-9pm', '9am-12am'
          ],
          datasets: [
            {
              title: 'Some Data',
              color: 'light-blue',
              values: [25, 40, 30, 35, 8, 52, 17, -4]
            },
            {
              title: 'Another Set',
              color: 'violet',
              values: [25, 50, -10, 15, 18, 32, 27, 14]
            }
          ]
        }
    };
  }

  updateSomeProps() {

    const newData = {
      labels: ['12am-3am', '3am-6pm'],
      datasets: [
        {
          title: 'Some Data',
          color: 'light-blue',
          values: [25, 40]
        },
        {
          title: 'Another Set',
          color: 'violet',
          values: [25, 50]
        }
      ]
    }

    this.setState({ data: newData });
  }

  render () {
    return (
      <div>
        <button onClick={this.updateSomeProps.bind(this)}>Changing props example ...</button>

        <hr/>

        <BarChart title="Test Bar Chart" data={this.state.data} height={250} />
        <LineChart title="Test Line Chart" data={this.state.data} height={250} />
        <PercentageChart title="Test Percentage Chart" data={this.state.data} height={250} />
        <PieChart title="Test Pie Chart" data={this.state.data} height={250} />
        <ScatterChart title="Test Scatter Chart" data={this.state.data} height={250} />
      </div>
    )
  }
}

render(<App />, document.getElementById('app'))

@tobiaslins
Copy link
Contributor Author

@charlesrochati forgot to write here, already this this:
https://github.com/tobiaslins/frappe-charts-react-example/blob/master/src/chart.js

I'm just using their function update_values instead of reinitializing the whole chart (works with animation)

@charlesrochati
Copy link

charlesrochati commented Nov 16, 2017

@tobiaslins cool, just added it to my example:

import React from 'react'
import PropTypes from 'prop-types'
import Chart from 'frappe-charts/dist/frappe-charts.min.esm'
import 'frappe-charts/dist/frappe-charts.min.css'
class ChartBuilder extends React.Component {
  
  componentDidMount () {
    const { title, data, type, height } = this.props
    this.c = new Chart({ parent: this.chart, title, data, type, height });
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps && !nextProps.data || this.props.data !== nextProps.data) {
      this.c.update_values(nextProps.data.datasets, nextProps.data.labels)
    }
  }

  render () {
    return (<div ref={ chart => (this.chart = chart) } />)
  }
}

export default ChartBuilder

It doesn't work with both Percentage and Pie chart, the update_values function gets undefined. Did you noticed that?

@pratu16x7
Copy link
Contributor

@tobiaslins For the record, added progress on this to the readme. Cheers!

@pratu16x7
Copy link
Contributor

@viperfx So the click handler doesn't work with non axis charts yet. Please keep an eye on #70 for updates.

@klvenky
Copy link

klvenky commented Mar 9, 2018

@tobiaslins is there any update on the support for react??
I have tried to use the example above, however, I wasn't successful.
Can u please let me know if there is any info on that.
Thanks

@tobiaslins
Copy link
Contributor Author

@charlesrochati
Copy link

@klvenky try this https://www.npmjs.com/package/react-comps-svg-charts

@klvenky
Copy link

klvenky commented Mar 10, 2018

@tobiaslins I have actually tried using the same code in https://github.com/tobiaslins/frappe-charts-react-example. However, that didn't go well. I am getting errors while rendering the same example
@charlesrochati thanks for the suggestion. However, I am kind of using another library already. Thought of trying out frappe charts also

@tomholford
Copy link

@charlesrochati working for me, thanks

@aibrahim3546
Copy link

Is there any support for the latest version of Frappe Charts v1.1?

@mrdavey
Copy link

mrdavey commented May 2, 2019

I'm using the latest version of Frappe Charts and it was quite easy to use in React JS.

In my App render() {}:

        <div id="chart"></div>
        {!this.state.isLoading &&          
          <ChartRender chartData={this.state.chartData} />
        }

Then in the same file, under the App component:

const ChartRender = (props) => {
  let data = {
    labels: props.chartData.dates,
    datasets: [
      ...
    ]
  }

  let chart = new Chart("#chart", {
   ...
  });
  return null;
}

@AmnonSkladman
Copy link

I've tried using multiple solutions, including mrdavey's, and while I can see the chart in Elements (using Dev Inspector), it doesn't actually show up on the page. It's just...invisible? Here's my code:

import React, { Component } from 'react';
import { Chart } from 'frappe-charts/dist/frappe-charts.min.esm';

class AppChart extends Component {
  render() {
    document.addEventListener(
      'DOMContentLoaded',
      () => {
        const data = {
          labels: [
            '12am-3am',
            '3am-6pm',
            '6am-9am',
            '9am-12am',
            '12pm-3pm',
            '3pm-6pm',
            '6pm-9pm',
            '9am-12am'
          ],
          datasets: [
            {
              name: 'Some Data',
              type: 'bar',
              values: [25, 40, 30, 35, 8, 52, 17, -4]
            },
            {
              name: 'Another Set',
              type: 'line',
              values: [25, 50, -10, 15, 18, 32, 27, 14]
            }
          ]
        };

        const chart = new Chart('#chart', {
          title: 'My Awesome Chart',
          data: data,
          type: 'axis-mixed',
          height: 250,
          colors: ['#7cd6fd', '#743ee2']
        });

        return null;
      },
      false
    );

    return (
      <div>
        <div id="chart" style={{ opacity: '1', zIndex: '9999' }} />
      </div>
    );
  }
}

export default AppChart;

@asaf
Copy link

asaf commented Aug 26, 2019

@AmnonSkladman instead of using document.addEventListener wrap your code within a hook effect

e.g.,

function App() {
  useEffect(() => {
    const data = {
       ... data
    };

    const chart = new Chart("#chart", {
      title: "My Awesome Chart",
      data: data,
      type: "axis-mixed",
      height: 250,
      colors: ["#7cd6fd", "#743ee2"]
    });

    return () => {
      chart.unbindWindowEvents();
    };
  }, []);

  return (
  <div>
    <div id="chart" style={{ opacity: "1", zIndex: "9999" }} />
  </div>
  )
}

@sheshbabu
Copy link

@eokoneyo
Copy link

eokoneyo commented Nov 6, 2019

You might be better off dealing with frappe as a cjs module especially in react, doing the following below works for both SSR and CSR

const { Chart } = require('frappe-charts/dist/frappe-charts.min.cjs');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests