var { ChartCanvas, Chart, DataSeries, OverlaySeries, EventCapture } = ReStock;

var { CandlestickSeries, HistogramSeries, LineSeries, AreaSeries, StochasticSeries } = ReStock.series;
var { MouseCoordinates, CurrentCoordinate } = ReStock.coordinates;
var { EdgeContainer, EdgeIndicator } = ReStock.coordinates;

var { TooltipContainer, OHLCTooltip, MovingAverageTooltip, StochasticTooltip } = ReStock.tooltip;
var { StockscaleTransformer } = ReStock.transforms;

var { XAxis, YAxis } = ReStock.axes;
var { MACD, EMA, SMA, FullStochasticOscillator } = ReStock.indicator;
var { ChartWidthMixin, TypeChooser } = ReStock.helper;

window.Histogram = React.createClass({
	mixins: [ChartWidthMixin],
	propTypes: {
		data: React.PropTypes.array.isRequired,
		type: React.PropTypes.oneOf(["svg", "hybrid"]).isRequired,
	},
	getDefaultProps() {
		return {
			type: "svg"
		}
	},
	render() {
		var width = this.props.width || this.state !== null && this.state.width;
		if (!width) return <div />;
		var { data, type } = this.props;
		var dateFormat = d3.time.format("%Y-%m-%d");

		return (
			<ChartCanvas width={width} height={400}
				margin={{left:100, right: 100, top:30, bottom: 30}} initialDisplay={100}
				dataTransform={[ { transform: StockscaleTransformer } ]}
				data={data} type={type}>
				<Chart id={1}  yMousePointerDisplayLocation="right"
					 yMousePointerDisplayFormat={d3.format(".4s")}  >
			    <XAxis axisAt="bottom" orient="bottom" />
          <YAxis axisAt="right" orient="right" ticks={5} tickFormat={d3.format("s")} />		  
          <DataSeries id={1} yAccessor={(d) => d.close} >
						<LineSeries/>
					</DataSeries>
				</Chart>
				<CurrentCoordinate forChart={1} forDataSeries={1} />
				<Chart id={2} yMousePointerDisplayLocation="left" yMousePointerDisplayFormat={d3.format(".4s")} >
					<YAxis axisAt="left" orient="left" ticks={5}  />
					<DataSeries id={0} yAccessor={(d) => d.volume} >
						<HistogramSeries  baseAt={(xScale, yScale, d) => yScale(0)} fill={(d) => d.volume > 0 ? "#6BA583" : "red"} />
					</DataSeries>
				</Chart>
				<CurrentCoordinate forChart={2} forDataSeries={0} />
				<EdgeContainer>
					<EdgeIndicator itemType="last" orient="right"
						edgeAt="right" forChart={1} forDataSeries={1} />
					<EdgeIndicator itemType="first" orient="left"
						edgeAt="left" forChart={1} forDataSeries={1} />
					<EdgeIndicator itemType="first" orient="left"
						edgeAt="left" forChart={1} forDataSeries={1} />
				</EdgeContainer>
			
				<MouseCoordinates xDisplayFormat={dateFormat} type="crosshair" />
				<EventCapture mouseMove={true} zoom={true} pan={true} mainChart={1} defaultFocus={false} />
				<TooltipContainer>
					<OHLCTooltip forChart={1} />
					<MovingAverageTooltip forChart={1} onClick={(e) => console.log(e)} origin={[-38, 5]} />
				</TooltipContainer>
			</ChartCanvas>
		);
	}
});
<!DOCTYPE html>
<html lang="en">

  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=10">
    <title>React Stockcharts - CandleStickChartWithFullStochasticsIndicator Example</title>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.0-rc1/react-dom.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.25/browser.js"></script>
    <script type="text/javascript" src="//rrag.github.io/react-stockcharts/dist/react-stockcharts.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/flux/2.1.1/Flux.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
    <link rel="stylesheet" type="text/css" href="main.css">
   <script type="text/javascript">
      d3.select(self.frameElement).style("height", "800px");
    </script>
  </head>

  <body>
    <div id="chart"></div>
    <script type="text/babel" src="EventEmitterMixin.js"></script>
    <script type="text/babel" src="Histogram.jsx"></script>
    <script type="text/babel" src="Chart.jsx"></script>
    <script type="text/babel" src="Table.jsx"></script>
    <script type="text/babel" src="main.jsx"></script>
  </body>

</html>
var Histogram = window.Histogram;
var parseDate = d3.time.format("%d-%b-%Y").parse;
var EventEmitterMixin = window.EventEmitterMixin;

window.Chart = React.createClass({
	propTypes: {
		data: React.PropTypes.array.isRequired,
	},
	mixins:[EventEmitterMixin],
  getInitialState() {
      return { 
        data: [],
        currentIndex:2
      }
    },
  componentDidMount() {
    this.eventEmitter('on','rowChange', function(index){
            this.setState({ currentIndex: index});
    });
	},
   getTitle(currentIndex){
     return (this.props.data) ? this.props.data[currentIndex].split(',').splice(0,1): "Chart";
   },
   getData(currentIndex){
    var items = this.props.data;
    if(!items) return {};
    var dates = items[0].split(',').slice(2, items.length);
    var totals = items[1].split(',').slice(2, items.length);
    var volume = items[currentIndex].split(',').slice(2, items.length);
    var chartItems = [];
        for (var i = 0; i < volume.length; i++){
                 chartItems.push(
                    {   adjclose:0,
                        close:parseInt(totals[i]), 
                        date:new Date(parseDate(dates[i]).getTime()), 
                        high:0, 
                        low:0, 
                        open:0, 
                        volume:parseInt(volume[i]) }
                 );
        }

      return chartItems;

   },

  render() {
      
    return (
          <div>
          <h3 className="centered">{this.getTitle(this.state.currentIndex)}</h3>
          <Histogram data={this.getData(this.state.currentIndex)} type="hybrid" />
          </div>
    );
   }

});



var PnlChart = window.PnlChart;
var Table = window.Table;


var App = React.createClass({

  componentDidMount: function() {
  },
  render: function() {
    return (
      <div>
        <Table />
      </div>
    );
  }
});
          

React.render(<App/>, document.getElementById('chart'));



var EventEmitterMixin = window.EventEmitterMixin;
var Chart = window.Chart;
var numFormat = d3.format("0,000");

window.Table = React.createClass({
    mixins:[EventEmitterMixin],
    getInitialState() {
      return{
        data : "",
        currentID: 2
      }
    },
 componentDidMount() {
    var scope = this;
    
    this.eventEmitter('on','loadedData', function(data){
            this.setState({ data: data});
    });
    
    if (!this.state.data) {
       $.ajax({
          type: 'GET',
          url: 'tabledata.json',
          async: false,
          contentType: "application/json",
          dataType: 'json',
          success: function (data) {
              scope.eventEmitter('emit','loadedData', data);
          },
          error: function (e) {
              alert('error');
              console.log(e);
      
          }
      });
    }
  },
  onClick(e){
     var newId = e.currentTarget.id;
     if (this.state.currentID !== newId)
     this.eventEmitter('emit','rowChange', newId);
  },
  getTableData(items){
    let tableItems = [];
        for (let i = 0; i < items.length; i++){
                 let colArr = items[i].split(',');
                 tableItems.push(
                    <tr key={"pnl chart" + i} id={i} onClick={e => this.onClick(e)}>
                     { colArr.map((x, j) =>  
                        <td key={x+j}>{ isNaN(x) ? x : numFormat(x)}</td>
                     )}
                   </tr>
                 );
      }
      return tableItems;
  },

  render() {


    return (
         <div>
            { this.state.data ?
            <div>
            <table className="dataTable">
              <tbody>{this.getTableData(this.state.data.items)}</tbody>
            </table>
            <Chart data={this.state.data.items}  /> 
            </div>
            : " "}
         </div>
    );
   }

});

{"items":[
 "Manager,fYTD,14-Dec-2014,15-Jan-2015,15-Feb-2015,15-Mar-2015,15-Apr-2015,15-May-2015,15-Jun-2015,15-Jul-2015,15-Aug-2015,15-Sep-2015,15-Oct-2015,15-Nov-2015",
 "Totals,8109,7776,-698,-1026,297,5771,5838,1945,7178,899,5608,-2339,-3605",
 "Bob,837,-2653,5290,-8449,-2048,-8683,-3504,7339,-6802,-7573,7698,2953,-2834",
  "Jenny,-1679,-1899,-2233,-7443,-4745,-5438,6197,-2694,16,-5221,113,-2092,4905",
  "Core,1581,-4101,7754,-4133,698,-6748,5660,-6155,2387,5542,1423,7202,-9282",
  "Stephan,4902,6073,-1114,1785,-9006,-3780,-3543,6232,-605,-1531,-306,4317,-5800",
  "Qing,4117,7484,1882,8600,5062,-5327,4059,9199,7934,-3765,-9517,-2691,-6840",
  "Tommy,-7892,1310,2066,-4129,-8200,7636,9992,1332,-6087,1014,-6964,-4848,1677",
  "Jeremy,2072,5488,6390,-701,-25,-4517,5922,-7665,7975,4389,-1987,3390,3949",
  "Mark,-6657,-4508,-6629,-9002,-787,7386,-9094,-2110,-7647,-9531,-2391,3226,-9377",
  "Timothy,-3596,-6388,5319,-7081,507,3760,-5620,7796,-687,6193,7670,8613,4820",
  "Jenkins,-8647,2756,26,-5907,-3649,9075,3922,9992,-6073,3583,-3766,-6139,-5454",
  "Kat,1551,-7169,-4339,-1621,489,-285,9439,8796,6533,-6440,-5336,8429,8177",
  "Unknown,9049,-2703,2343,-4938,-3913,6634,1312,7613,-5454,-2917,7490,-692,9325"
]}
'use strict';

var GLOBAL = typeof window === 'undefined' ? global : window;

var _events = GLOBAL.EVENT_EMITTER = {};

var _signCnt = 0;

var EventEmitter = {
    mount(){
        this._eventIncluded = [];
        this._eventSign = '_eventTag_' + (_signCnt++);
    },
    unmount(){
        this._eventIncluded.forEach(event => delete _events[event][this._eventSign]);
        this._eventIncluded = [];
    },

    /**
     * on
     *
     * @param {string} event :Event name
     * @param {function} callback :Callback
     */
    on(event,callback){
        _events[event] || (_events[event] = {});
        callback.self = this; //save current `this` reference 
        if(_events[event][this._eventSign]){
            _events[event][this._eventSign].push(callback);
        }else{
            _events[event][this._eventSign] = [callback];
        }
        if( !~this._eventIncluded.indexOf(event) ){
            this._eventIncluded.push(event);
        }
    },

    /**
     * one
     *
     * @param {string} event :Event name
     * @param {function} callback :Callback
     */
    one(event,callback){
        var proxy = function(...data){
            EventEmitter.off.call(this,event,proxy);
            callback.apply(this,data);
        };
        EventEmitter.on.call(this,event,proxy);
    },

    /**
     * off
     *
     * @param {string} event :Event name
     * @param {function} callback :Callback
     * @param {boolean} removeAll :Should remove event of all components
     */
    off(event,callback,removeAll){
        if(!_events[event]) return ;
        
        if(removeAll){ //remove the event of all components
            if(!callback){
                _events[event] = {};
                var currentRegi = this._eventIncluded.indexOf(event);
                (~currentRegi) && this._eventIncluded.splice(currentRegi,1);
            }else{
                for(var _sign in _events[event]){
                    var index = _events[event][_sign].indexOf(callback);
                    (~index) && _events[event][_sign].splice(index,1);
        
                    if(!_events[event][_sign].length){
                        if(_sign == this._eventSign){
                            var currentRegi = this._eventIncluded.indexOf(event);
                            (~currentRegi) && this._eventIncluded.splice(currentRegi,1);
                        }
                        delete _events[event][_sign];
                    }
                }
            }
        }else{ //only remove the event of current component
            if(!_events[event][this._eventSign]) return ;
            if(!callback){
                if(_events[event][this._eventSign]){
                    delete _events[event][this._eventSign];
                    this._eventIncluded.splice(this._eventIncluded.indexOf(event),1);
                }
            }else if(_events[event][this._eventSign]){
                var index = _events[event][this._eventSign].indexOf(callback);

                (~index) && _events[event][this._eventSign].splice(index,1);
        
                if(!_events[event][this._eventSign].length){
                    delete _events[event][this._eventSign];
                    this._eventIncluded.splice(this._eventIncluded.indexOf(event),1);
                }
            }
        }
    },

    /**
     * emit
     *
     * @param {string} event :Event name
     */
    emit(event,...data){
        if(!_events[event]) return ;

        for(var _sign in _events[event]){
            var list = _events[event][_sign].slice(0); //might be removed by nested `off`
            list.forEach((cb)=>{
                cb.apply(cb.self,data); // `this` point to component which bind this callback
            });
            list = null;
        }
    },
};

window.EventEmitterMixin = {
    componentWillMount(){
        EventEmitter.mount.call(this);
    },
    componentWillUnmount(){
        EventEmitter.unmount.call(this);
    },
    eventEmitter(type,...data){
        EventEmitter[type].apply(this,data); 
    },
};


.centered{
  text-align:center;
}

table.dataTable {
  border-spacing: 0px;
	border-color: "grey";
	font-size:12px;

}

table.dataTable td, th {
  padding: 10px;
}
table.dataTable tr:nth-child(odd) {
 	background-color: #e0e0e0;

}
table.dataTable tr:first-child{
	background: #0288d1;
	color:#fff;
}
table.dataTable tr:hover {
 	background-color: #ffbf14;
}