如何更改制作动态饼图的状态?

时间:2017-03-08 07:09:23

标签: javascript reactjs chart.js

我正在尝试制作一个动态饼图,它会随着滑块的变化而变化。 我已经设置了一切但我不能在其中引入状态,因为我是新手做出反应。我只是希望当有人滑动滑块时,饼图也会根据滑块的值而变化。任何人都可以帮助我吗?

<!DOCTYPE html>
<html>
	<head>
		<title>React Example without Babel </title>
		<script src="https://npmcdn.com/react@15.3.1/dist/react.min.js"></script>
		<script src="https://npmcdn.com/react-dom@15.3.1/dist/react-dom.min.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0-alpha1/JSXTransformer.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-with-addons.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
		<link href="http://getbootstrap.com/dist/css/bootstrap.css" rel="stylesheet">
		<style>
			.pie{
				fill:red;
			}
		</style>
	</head>
	<body>
		<div class="container">
			<div id="app"></div>
			<div class="col-lg-5" id="slider"></div>
			<div class="col-lg-6" id="pie_chart"></div>
		</div>
		<script type="text/jsx">
			
			class Header extends React.Component{
				render(){
					return (<div><h1 className='page-header'>{this.props.text}</h1></div>);
				}
			}
			ReactDOM.render(<Header text='Dynamic Pie Chart'/>,document.getElementById('app'));
			class Slider extends React.Component{
				render(){
					return (<div><input type='range' min='1' max='100' /></div>);
				}
			}
			ReactDOM.render(<Slider />,document.getElementById('slider'));
			var PropTypes = React.PropTypes;
			var PieChart = React.createClass({
			displayName: 'PieChart',
			propTypes: {
				className: PropTypes.string,
				size: PropTypes.number,
				slices: PropTypes.arrayOf(PropTypes.shape({
				color: PropTypes.string.isRequired, // hex color
				value: PropTypes.number.isRequired })).isRequired },
				getDefaultProps: function getDefaultProps() {
					return {
						size: 200 };
					},
				
  _renderPaths: function _renderPaths() {
    var radCircumference = Math.PI * 2;
    var center = this.props.size / 2;
    var radius = center - 1; // padding to prevent clipping
    var total = this.props.slices.reduce(function (totalValue, slice) {
      return totalValue + slice.value;
    }, 0);

    var radSegment = 0;
    var lastX = radius;
    var lastY = 0;

    return this.props.slices.map(function (slice, index) {
      var color = slice.color;
      var value = slice.value;

      // Should we just draw a circle?
      if (value === total) {
        return React.createElement('circle', {
          r: radius,
          cx: radius,
          cy: radius,
          fill: color,
          key: index
        });
      }

      if (value === 0) {
        return;
      }

      var valuePercentage = value / total;

      // Should the arc go the long way round?
      var longArc = valuePercentage <= 0.5 ? 0 : 1;

      radSegment += valuePercentage * radCircumference;
      var nextX = Math.cos(radSegment) * radius;
      var nextY = Math.sin(radSegment) * radius;

      // d is a string that describes the path of the slice.
      // The weirdly placed minus signs [eg, (-(lastY))] are due to the fact
      // that our calculations are for a graph with positive Y values going up,
      // but on the screen positive Y values go down.
      var d = ['M ' + center + ',' + center, 'l ' + lastX + ',' + -lastY, 'a' + radius + ',' + radius, '0', '' + longArc + ',0', '' + (nextX - lastX) + ',' + -(nextY - lastY), 'z'].join(' ');

      lastX = nextX;
      lastY = nextY;

      return React.createElement('path', { d: d, fill: color, key: index });
    });
  },

  /**
   * @return {Object}
   */
  render: function render() {
    var size = this.props.size;

    var center = size / 2;

    return React.createElement(
      'svg',
      { viewBox: '0 0 ' + size + ' ' + size },
      React.createElement(
        'g',
        { transform: 'rotate(-90 ' + center + ' ' + center + ')' },
        this._renderPaths()
      )
    );
  }
});

var slices = [
    { color: '#468966', value: 180 },
    { color: '#FFF0A5', value: 180 },
   
];

ReactDOM.render(<PieChart slices={slices} />, document.getElementById('pie_chart'));
		
			
		</script>
	</body>
</html>

2 个答案:

答案 0 :(得分:1)

嗨请检查它现在正在运行的代码。您必须将幻灯片更改值传递给州。我改变了一些代码。请检查。

    <!DOCTYPE html>
<html>
    <head>
        <title>React Example without Babel </title>
        <script src="https://npmcdn.com/react@15.3.1/dist/react.min.js"></script>
        <script src="https://npmcdn.com/react-dom@15.3.1/dist/react-dom.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0-alpha1/JSXTransformer.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-with-addons.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
        <link href="http://getbootstrap.com/dist/css/bootstrap.css" rel="stylesheet">
        <style>
            .pie{
                fill:red;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <div id="app"></div>
            <div class="col-lg-5" id="slider"></div>
            <div class="col-lg-6" id="pie_chart"></div>
        </div>
        <script type="text/jsx">

            class Header extends React.Component{
                render(){
                    return (<div><h1 className='page-header'>{this.props.text}</h1></div>);
                }
            }
            ReactDOM.render(<Header text='Dynamic Pie Chart'/>,document.getElementById('app'));
            class Slider extends React.Component{
                render(){
                    return (<div><input type='range' min='1' max='100' onChange = {this.props.sliderEvent} /></div>);
                }
            }

            var PropTypes = React.PropTypes;
            var PieChart = React.createClass({
            displayName: 'PieChart',
            propTypes: {
                className: PropTypes.string,
                size: PropTypes.number,
                slices: PropTypes.arrayOf(PropTypes.shape({
                color: PropTypes.string.isRequired, // hex color
                value: PropTypes.number.isRequired })).isRequired },
                getDefaultProps: function getDefaultProps() {
                    return {
                        size: 200 };
                    },

  _renderPaths: function _renderPaths() {
    var radCircumference = Math.PI * 2;
    var center = this.props.size / 2;
    var radius = center - 1; // padding to prevent clipping
    var total = this.props.slices.reduce(function (totalValue, slice) {
      return totalValue + slice.value;
    }, 0);

    var radSegment = 0;
    var lastX = radius;
    var lastY = 0;

    return this.props.slices.map(function (slice, index) {
      var color = slice.color;
      var value = slice.value;

      // Should we just draw a circle?
      if (value === total) {
        return React.createElement('circle', {
          r: radius,
          cx: radius,
          cy: radius,
          fill: color,
          key: index
        });
      }

      if (value === 0) {
        return;
      }

      var valuePercentage = value / total;

      // Should the arc go the long way round?
      var longArc = valuePercentage <= 0.5 ? 0 : 1;

      radSegment += valuePercentage * radCircumference;
      var nextX = Math.cos(radSegment) * radius;
      var nextY = Math.sin(radSegment) * radius;

      // d is a string that describes the path of the slice.
      // The weirdly placed minus signs [eg, (-(lastY))] are due to the fact
      // that our calculations are for a graph with positive Y values going up,
      // but on the screen positive Y values go down.
      var d = ['M ' + center + ',' + center, 'l ' + lastX + ',' + -lastY, 'a' + radius + ',' + radius, '0', '' + longArc + ',0', '' + (nextX - lastX) + ',' + -(nextY - lastY), 'z'].join(' ');

      lastX = nextX;
      lastY = nextY;

      return React.createElement('path', { d: d, fill: color, key: index });
    });
  },

  /**
   * @return {Object}
   */
  render: function render() {
    var size = this.props.size;

    var center = size / 2;

    return React.createElement(
      'svg',
      { viewBox: '0 0 ' + size + ' ' + size },
      React.createElement(
        'g',
        { transform: 'rotate(-90 ' + center + ' ' + center + ')' },
        this._renderPaths()
      )
    );
  }
});


class App extends React.Component{
    constructor(props){
  super(props);
  this.state = {
    slices : [
      { color: '#468966', value: 180 },
      { color: '#FFF0A5', value: 180 },
     ]
    };  
  //this.handleSliderEvent = this.bind.handleSliderEvent(this);
  }
  handleSliderEvent(e){
        var slices1 = (360 * e.target.value)/100;
      var slices2 = 360 - slices1;
      var array1 = [
        { color: '#468966', value: slices1 },
        { color: '#FFF0A5', value: slices2 }
        ];
        console.log(array1)
      this.setState({slices: array1});

  }
    render(){
    return(
        <div>
      <Slider sliderEvent = {this.handleSliderEvent.bind(this)}/>
      <PieChart slices = {this.state.slices} />
      </div>
    )
  }
}
ReactDOM.render(<App/>, document.getElementById('pie_chart'));


        </script>
    </body>
</html>

通过这个小提琴,它有你的代码的工作版本。

https://jsfiddle.net/oyqzms4c/

答案 1 :(得分:0)

您好请检查以下代码。它应该工作。

<!DOCTYPE html>
<html>
    <head>
    <script src="https://npmcdn.com/react@15.3.1/dist/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://unpkg.com/react@15.0.1/dist/react-with-addons.js"></script>
<script src="https://unpkg.com/react-dom@15.0.1/dist/react-dom.js"></script>
<script src="https://npmcdn.com/rd3@0.6.3/build/public/js/react-d3.js"></script>
        <link href="http://getbootstrap.com/dist/css/bootstrap.css" rel="stylesheet">




    </head>
    <body>
        <div class="container">
        <h1 class="page-header">Dynamic Pie Chart</h1>
        <div id="slider" class="col-lg-6"></div>
        <div id="container" class="col-lg-6">

</div>
</div>
  </div>
    </body>
    <script type="text/babel">



class Chart extends React.Component{
  render() {
  var PieChart = rd3.PieChart;
    //var pieData = [ {label: "First", value: 50}, {label: "Second", value: 50 }];
    return  (
        <PieChart
      data={this.props.data}
      width={450}
      height={400} 
      radius={110}
      sectorBorderColor="white"
      />
  )}
}
class Slider extends React.Component{
    render(){
        return (<div><input type='range' min='0' max='100' onChange = {this.props.sliderEvent} /></div>);
    }
}

class App extends React.Component{
            constructor(props){
                super(props);
                this.state = {
                    pieData : [
                        {label: "First", value: 50}, {label: "Second", value: 500 }
                    ]
                };  
        }
        handleSliderEvent(e){
        var slices1 = (360 * e.target.value)/100;
            var slices2 = 360 - slices1;

            var array1 = [
                { label: "First", value: slices1 },
                { label: "Second", value: slices2 }
            ];

            this.setState({pieData: array1},function(){
      console.log(this.state);

      });

        }
        render(){
        return(<div className="row">
                <Slider sliderEvent = {this.handleSliderEvent.bind(this)}/>
                <div className='col-lg-6'>
                    <Chart data = {this.state.pieData} />
                </div>
                </div>)
            }
        }
        ReactDOM.render(<App/>, document.getElementById('container'));


    </script>
</html>

当您将状态传递给组件时,它将作为道具在组件中可用。所以你必须使用那些道具。