Reactjs仪表板 - 带有参数数组的多个实例

时间:2016-08-17 21:20:47

标签: javascript reactjs

**最新小提琴 - http://jsfiddle.net/cfrapLma/28/

添加图表类型 - 有没有更好的方法来推动这一点 - 如果通过redux处理配置json - 下一步是什么?有没有人尝试过使用reactjs和d3制作仪表板应用程序?

我正在开发一个reactjs项目,我热衷于输出一组div持有者,它们将包含未来的图表参数,如宽度,高度,网址服务。

++如何推送和拉出多个参数来创建图表的不同实例,占位符..? ++这是创建仪表板组件的良好开端我需要为我想要吸收的图表,大小和服务创建配置json。

// config json?

 [{
        "width": 200,
        "height": 200,
        "type": "piechart",
        "serviceApi": "api.php?mode=GetCars"
    }, {
        "width": 100,
        "height": 100,
        "type": "barchart",
        "serviceApi": "api.php?mode=GetBoats"
    }]

我是否需要创建一个控制参数的配置json - 一个需要渲染的图表数组?

var MultipleCharts = React.createClass({
  render: function() {
    return (
      <div>
        <div className="holder1"><PieChart width={this.props.width} height={this.props.height} service={this.props.service}/></div>
        <div className="holder2"><PieChart width={this.props.width} height={this.props.height} service={this.props.service}/></div>
      </div>
    );
  }
});

^这是一种硬编码方法,我需要循环并推送配置json,以便每个图表具有不同的属性。

<div data-role="piechart" data-width=240 data-height=240 data-service="api.php?mode=GetCars">

//最新小提琴 http://jsfiddle.net/cfrapLma/24/

这是第一个原型构建 - 我是否会让reactjs处理一堆图表 - 好像这些信息来自配置json - 就像仪表板设置一样。

或者仪表板配置在模板上硬编码 - reactjs调用图表工具。

    <!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>React Charts</title>
    <script src="https://npmcdn.com/react@15.3.0/dist/react.js"></script>
    <script src="https://npmcdn.com/react-dom@15.3.0/dist/react-dom.js"></script>
    <script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
    <script src="https://npmcdn.com/jquery@3.1.0/dist/jquery.min.js"></script>
    <script src="https://npmcdn.com/remarkable@1.6.2/dist/remarkable.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
  </head>
  <body>

    <div id="example"></div>

    <script type="text/babel">

var config = [{
        "width": 200,
        "height": 200,
        "type": "piechart",
        "serviceApi": "api.php?mode=GetCars"
    }, {
        "width": 100,
        "height": 100,
        "type": "barchart",
        "serviceApi": "api.php?mode=GetBoats"
    }];


var MultipleCharts = React.createClass({
  render: function() {
    return (
      <div>
        <div className="holder1"><PieChart width={this.props.width} height={this.props.height} service={this.props.service}/></div>
        <div className="holder2"><BarChart width={this.props.width} height={this.props.height} service={this.props.service}/></div>
      </div>
    );
  }
});

var PieChart = React.createClass({
  componentDidMount: function() {
                var $this = $(ReactDOM.findDOMNode(this));
          console.log("rendered div now engage d3");
          // set el height and width etc.
  },
  render: function() {
    return (
      <div className="piechart" data-role="piechart" data-width={this.props.width} data-height={this.props.height} data-service={this.props.service}>pie.
       </div>
    );
  }
});




var BarChart = React.createClass({
  componentDidMount: function() {
                var $this = $(ReactDOM.findDOMNode(this));
          console.log("rendered div now engage d3");
          // set el height and width etc.
  },
  render: function() {
    return (
      <div className="barchart" data-role="barchart" data-width={this.props.width} data-height={this.props.height} data-service={this.props.service}>pie.
       </div>
    );
  }
});


ReactDOM.render(
  <MultipleCharts width="200" height="200" service="api.php?mode=GetCars"/>,
  document.getElementById('example')
);

    </script>


  </body>
</html>

3 个答案:

答案 0 :(得分:1)

因此,您可以创建的Fabric方法将返回基于config.type的相应组件。

然后,您可以在渲染方法中迭代所有配置。 并将config作为道具传递给您的组件MultipleCharts。

&#13;
&#13;
var config = [{
    "width": 200,
    "height": 200,
    "type": "piechart",
    "serviceApi": "api.php?mode=GetCars"
}, {
    "width": 100,
    "height": 100,
    "type": "barchart",
    "serviceApi": "api.php?mode=GetBoats"
}];

var MultipleCharts = React.createClass({
    getChart: function(config) {
        switch (config.type) {

            case 'piechart':
                return <PieChart width={config.width} height={config.height} service={config.service} />
            case 'barchart':
                return <BarChart width={config.width} height={config.height} service={config.service} />
        }
    },

    render: function () {
        var config = this.props.config;
        
        return (
            <div>
                {config.map((chartConfig, index) => {
                    return (
                        <div key={index} className={'holder' + index}>
                            {this.getChart(chartConfig)}
                        </div>
                    )
                })}
            </div>
        );
    }
});

var PieChart = React.createClass({
    componentDidMount: function () {
        var $this = $(ReactDOM.findDOMNode(this));
        console.log("rendered div now engage d3");
        // set el height and width etc.
    },
    render: function () {
        return (
            <div className="piechart" data-role="piechart" data-width={this.props.width} data-height={this.props.height}
                data-service={this.props.service}>pie.
            </div>
        );
    }
});

var BarChart = React.createClass({
    componentDidMount: function () {
        var $this = $(ReactDOM.findDOMNode(this));
        console.log("rendered div now engage d3");
        // set el height and width etc.
    },
    render: function () {
        return (
            <div className="barchart" data-role="barchart" data-width={this.props.width} data-height={this.props.height}
                data-service={this.props.service}>pie.
            </div>
        );
    }
});

ReactDOM.render(
    <MultipleCharts config={config} />,
    document.getElementById('example')
);
&#13;
&#13;
&#13;

请尽量避免在React组件中使用data- *属性。

答案 1 :(得分:1)

根据@ Sergey的回答,我添加了一些修改以使其真正动态。现在有一个typeMapping对象,它从字符串映射到组件。如果要添加新组件,只需将其添加到那里即可。为方便起见,我使用的是ES6,如果需要,我希望你能将它翻译成ES5。

var config = [{
  "type": "PieChart",
  "width": 200,
  "height": 200,
  "serviceApi": "api.php?mode=GetCars"

}, {
  "type": "BarChart",
  "width": 100,
  "height": 100,
  "serviceApi": "api.php?mode=GetBoats"
}];

var MultipleCharts = React.createClass({
    getChart: function(config) {
      const { type, ...props } = config;
      return React.createElement(typeMapping[type], props);
    },

    render: function () {
        var config = this.props.config;
        
        return (
            <div>
                {config.map((chartConfig, index) => {
                    return (
                        <div key={index} className={'holder' + index}>
                            {this.getChart(chartConfig)}
                        </div>
                    )
                })}
            </div>
        );
    }
});

var PieChart = React.createClass({
    componentDidMount: function () {
        var $this = $(ReactDOM.findDOMNode(this));
        console.log("rendered div now engage d3");
        // set el height and width etc.
    },
    render: function () {
        return (
            <div className="piechart" data-role="piechart" data-width={this.props.width} data-height={this.props.height}
                data-service={this.props.serviceApi}>pie.
            </div>
        );
    }
});

var BarChart = React.createClass({
    componentDidMount: function () {
        var $this = $(ReactDOM.findDOMNode(this));
        console.log("rendered div now engage d3");
        // set el height and width etc.
    },
    render: function () {
        return (
            <div className="barchart" data-role="barchart" data-width={this.props.width} data-height={this.props.height}
                data-service={this.props.serviceApi}>bar.
            </div>
        );
    }
});

// Allowed types
const typeMapping = {
  PieChart, // In ES6, it is the same as "PieChart": PieChart, 
  BarChart,
};

ReactDOM.render(
  <MultipleCharts config={config} />,
  document.getElementById('example')
);
.piechart{
  background: pink;
  width: 100px;
  height: 50px;
  border: 1px solid black;
}

.barchart{
  background: green;
  width: 100px;
  height: 50px;
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://npmcdn.com/react@15.3.1/dist/react.js"></script>
<script src="https://npmcdn.com/react-dom@15.3.1/dist/react-dom.js"></script>

<div id="example"></div>

答案 2 :(得分:0)

enter image description here

好吧,所以使用create-react-app作为基础..

我试图开始切割文件。当我尝试将PieChart / BarChart部件放入各自的文件时出现错误 - 我是否需要将它们修改为类?

/src/App.css

.App {
  text-align: center;
}

.App-logo {
  animation: App-logo-spin infinite 20s linear;
  height: 80px;
}

.App-header {
  background-color: #222;
  height: 150px;
  padding: 20px;
  color: white;
}

.App-intro {
  font-size: large;
}

@keyframes App-logo-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/src/App.js

import React, { Component } from 'react';
import './App.css';

import BarChart from './BarChart';
import PieChart from './PieChart';
import LineChart from './LineChart';

// Allowed types
const typeMapping = {
  PieChart, // In ES6, it is the same as "PieChart": PieChart, 
  BarChart,
  LineChart
};

class App extends Component {

  getChart(config) {
    const { type, ...props } = config;
    return React.createElement(typeMapping[type], props);
  }

  render() {
      var config = this.props.config;

      return (
          <div>
              {config.map((chartConfig, index) => {
                  return (
                      <div key={index} className={'holder' + index}>
                          {this.getChart(chartConfig)}
                      </div>
                  )
              })}
          </div>
      );
  }
}

export default App;

/src/BarChart.js

//barchart
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
var $ = require("jquery");

class BarChart extends Component {
    componentDidMount() {
        var $this = $(ReactDOM.findDOMNode(this));
        console.log("rendered div now engage d3", $this);
        // set el height and width etc.
    }

    render() {
        return (
            <div className="barchart" data-role="barchart" data-width={this.props.width} data-height={this.props.height}
                data-service={this.props.serviceApi}>bar.
            </div>
        );
    }
};

export default BarChart;

/src/Index.css

body {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
}

.piechart{
  background: pink;
  width: 100px;
  height: 50px;
  border: 1px solid black;
}

.barchart{
  background: green;
  width: 100px;
  height: 50px;
  border: 1px solid black;
}

.linechart{
  background: purple;
  width: 100px;
  height: 50px;
  border: 1px solid black;
}

/src/Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';

var config = [{
  "type": "PieChart",
  "width": 200,
  "height": 200,
  "serviceApi": "api.php?mode=GetCars"
}, {
  "type": "BarChart",
  "width": 100,
  "height": 100,
  "serviceApi": "api.php?mode=GetBoats"
}, {
  "type": "LineChart",
  "width": 100,
  "height": 100,
  "serviceApi": "api.php?mode=GetBoats"
}];

ReactDOM.render(
  <App config={config} />,
  document.getElementById('root')
);

/src/LineChart.js

//linechart
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
var $ = require("jquery");

class LineChart extends Component {
    componentDidMount() {
        var $this = $(ReactDOM.findDOMNode(this));
        console.log("rendered div now engage d3", $this);
        // set el height and width etc.
    }

    render() {
        return (
            <div className="linechart" data-role="linechart" data-width={this.props.width} data-height={this.props.height}
                data-service={this.props.serviceApi}>line.
            </div>
        );
    }
};

export default LineChart;

/src/PieChart.js

    //piechart
    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    var $ = require("jquery");

    class PieChart extends Component {
        componentDidMount() {
            var $this = $(ReactDOM.findDOMNode(this));
            console.log("rendered div now engage d3", $this);
            // set el height and width etc.



            var dataset = {
              apples: [53245, 28479, 19697, 24037, 40245],
            };

            var width = 460,
                height = 300,
                radius = Math.min(width, height) / 2;

            var color = d3.scale.category20();

            var pie = d3.layout.pie()
                .sort(null);

            var arc = d3.svg.arc()
                .innerRadius(radius - 100)
                .outerRadius(radius - 50);

            var svg = d3.select($this[0]).append("svg")
                .attr("width", width)
                .attr("height", height)
                .append("g")
                .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

            var path = svg.selectAll("path")
                .data(pie(dataset.apples))
              .enter().append("path")
                .attr("fill", function(d, i) { return color(i); })
                .attr("d", arc);


        }

        render() {
            return (
                <div className="piechart" data-role="piechart" data-width={this.props.width} data-height={this.props.height}
                    data-service={this.props.serviceApi}>pie.
                </div>
            );
        }
    };

    export default PieChart;