license: MIT
height: 420
"use strict";
var rs = ReStock.default;
var {PropTypes, Component} = React;
var { ChartCanvas, Chart, EventCapture } = rs;
var { CandlestickSeries, BarSeries } = rs.series;
var { financeEODDiscontiniousScale } = rs.scale;
var { MouseCoordinates } = rs.coordinates;
var { TooltipContainer, OHLCTooltip } = rs.tooltip;
var { XAxis, YAxis } = rs.axes;
var { fitWidth, TypeChooser } = rs.helper;
var xScale = financeEODDiscontiniousScale();
var defaultMagnification=1;
/**
Begin custom classes
**/
class MagnificationArea extends Component {
constructor(props) {
super(props);
this.dragStartPosition;
}
/**
* Begin capture
* @param e
* @returns {boolean}
*/
onMouseDown(yScale,e)
{
// IE is retarded and doesn't pass the event object
if (e == null)
e = window.event;
// for IE, left click == 1
// for Firefox, left click == 0
if ((e.button == 1 && window.event != null || e.button == 0) )
{
// grab the mouse position
// console.log('drag start ->', yScale.invert(e.clientY));
var currentValue=yScale.invert(e.clientY);
this.dragStartPosition=currentValue;
return false;
}
}
/**
* End Capture
* @param e
* @returns {boolean}
*/
onMouseUp(yScale,e)
{
// IE is retarded and doesn't pass the event object
if (e == null)
e = window.event;
// for IE, left click == 1
// for Firefox, left click == 0
if (this.dragStartPosition && (e.button == 1 && window.event != null || e.button == 0) )
{
this.dragStartPosition=undefined;
return false;
}
}
onMouseMove(yScale,e) {
if (this.dragStartPosition) {
var {magnification, onMagnify}=this.props;
var dragEndPosition= yScale.invert(e.clientY);
var mag = magnification+(1-(this.dragStartPosition/dragEndPosition));
/* sanity check */
mag>1?mag=1:mag;
mag<0?mag=0:mag;
onMagnify(mag);
return false;
}
}
/**
* Cancel if we have started capturing
*/
onMouseOut(yScale,e)
{
this.dragStartPosition=undefined;
}
render() {
var { chartConfig} = this.context;
var {yScale} = chartConfig;
var offset=5;
var startAt=chartConfig.width+offset; //width of chart + offset
var myWidth=70;
return (
<g className="draggable hover_group_drag" >
<rect x={startAt} y={0}
onMouseDown={this.onMouseDown.bind(this,yScale)}
onMouseUp={this.onMouseUp.bind(this,yScale)}
onMouseMove={this.onMouseMove.bind(this,yScale)}
onMouseOut={this.onMouseOut.bind(this,yScale)}
width={myWidth} height={chartConfig.height} fillOpacity="0" />
</g>
);
}
}
MagnificationArea.propTypes = {
magnification: PropTypes.number.isRequired,
onMagnify: PropTypes.func.isRequired
};
MagnificationArea.contextTypes = {
chartConfig: PropTypes.object.isRequired,
width: PropTypes.number.isRequired,
};
/***
Begin react-stockcharts plunkr
**/
class CandleStickChartWithZoomPan extends React.Component {
constructor(props) {
super(props);
console.log(props);
this.state = { magnification: 1 };
}
render() {
var { data, type, width } = this.props;
var {magnification}=this.state;
console.log(magnification);
return (
<ChartCanvas width={width} height={400}
margin={{left: 70, right: 70, top:10, bottom: 30}} type={type}
seriesName="MSFT"
data={data}
xAccessor={d => d.date} discontinous xScale={xScale}
allowedIntervals={["D", "W", "M"]}
xExtents={[new Date(2012, 0, 1), new Date(2012, 6, 2)]}>
<Chart id={1} yExtents={[d => [d.high+(d.high*(1-magnification)),d.low-(d.low*(1-magnification))]]}
yMousePointerDisplayLocation="right" yMousePointerDisplayFormat={d3.format(".2f")}>
<XAxis axisAt="bottom" orient="bottom"/>
<YAxis axisAt="right" orient="right" ticks={5} />
<CandlestickSeries />
{/* add our magnification class */}
<MagnificationArea
ref="magnificationArea1"
magnification={magnification}
onMagnify={(mag)=>{ this.setState({ magnification: mag });}}
/>
</Chart>
<Chart id={2} origin={(w, h) => [0, h - 150]} height={150} yExtents={d => d.volume}
yMousePointerDisplayLocation="left" yMousePointerDisplayFormat={d3.format(".4s")}>
<YAxis axisAt="left" orient="left" ticks={5} tickFormat={d3.format("s")}/>
<BarSeries yAccessor={d => d.volume} fill={(d) => d.close > d.open ? "#6BA583" : "#FF0000"} />
</Chart>
<MouseCoordinates xDisplayFormat={d3.time.format("%Y-%m-%d")} />
<EventCapture mouseMove={true} zoom={true} pan={true} />
<TooltipContainer>
<OHLCTooltip forChart={1} origin={[-40, 0]}/>
</TooltipContainer>
</ChartCanvas>
);
}
}
CandleStickChartWithZoomPan.propTypes = {
data: React.PropTypes.array.isRequired,
width: React.PropTypes.number.isRequired,
type: React.PropTypes.oneOf(["svg", "hybrid"]).isRequired,
};
CandleStickChartWithZoomPan.defaultProps = {
type: "svg",
};
CandleStickChartWithZoomPan = fitWidth(CandleStickChartWithZoomPan);
var parseDate = d3.time.format("%Y-%m-%d").parse;
d3.tsv("//rrag.github.io/react-stockcharts/data/MSFT.tsv", (err, data) => {
/* change MSFT.tsv to MSFT_full.tsv above to see how this works with lots of data points */
data.forEach((d, i) => {
d.date = new Date(parseDate(d.date).getTime());
d.open = +d.open;
d.high = +d.high;
d.low = +d.low;
d.close = +d.close;
d.volume = +d.volume;
// console.log(d);
});
/* change the type from hybrid to svg to compare the performance between svg and canvas */
ReactDOM.render(<TypeChooser type="hybrid">{type => <CandleStickChartWithZoomPan defaultMagnification={defaultMagnification} data={data} type={type} />}</TypeChooser>, document.getElementById("chart"));
});
TEST
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>React Stockcharts - CandleStickChartWithZoomPan Example</title>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.4.4/babel.min.js"></script>
<!-- <script type="text/javascript" src="//npmcdn.com/react-stockcharts@latest/dist/react-stockcharts.min.js"></script> -->
<script type="text/javascript" src="//rrag.github.io/react-stockcharts/dist/react-stockcharts.min.js"></script>
<style>
.draggable {
stroke-width: 4;
cursor: move;
}
.hover_group_drag:hover rect {
fill-opacity: .3;
stroke-width: 4;
opacity: .3;
fill: #000;
}
</style>
</head>
<body>
<div id="chart"></div>
<script>
// Use babel transform so the examples work on the browser
d3.xhr("./CandleStickChartWithZoomPan.jsx", "text/plain")
.get(function(err, data) {
var outputEl = document.getElementById('chart');
try {
var output = Babel.transform(data.responseText, { presets: ["es2015", "react", "stage-2"] }).code;
eval(output);
} catch (ex) {
outputEl.innerHTML = 'ERROR: ' + ex.message;
}
})
</script>
</body>
</html>