AG-420 Improve React implementation

This commit is contained in:
Sean Landsman
2017-05-19 15:58:12 +01:00
parent a438cb6169
commit a3a0336f6b
4 changed files with 115 additions and 66 deletions

View File

@@ -21,12 +21,9 @@ export default class extends Component {
}
}
shouldComponentUpdate(nextProps, nextState) {
return nextProps.selectedSymbol !== this.props.selectedSymbol;
}
componentWillReceiveProps(nextProps, nextState) {
if (nextProps.selectedSymbol !== this.props.selectedSymbol) {
if (nextProps.selectedSymbol &&
nextProps.selectedSymbol !== this.props.selectedSymbol) {
let stockDetail = this.exchangeService.getTickerDetail(nextProps.selectedSymbol);
this.setState({
@@ -38,15 +35,23 @@ export default class extends Component {
}
}
shouldComponentUpdate(nextProps, nextState) {
return nextProps.selectedSymbol !== this.props.selectedSymbol;
}
render() {
return (
<div>
<StockPriceDeltaPanel pricingDelta={this.state.pricingDelta}/>
<StockTimestampPanel timestamp={this.state.timestamp}
exchangeName={this.props.exchangeName}/>
<StockSummaryPanel tickerSummary={this.state.tickerSummary}/>
<StockHistoricalChartPanel historicalData={this.state.historicalData} />
</div>
);
if (!this.props.selectedSymbol) {
return null;
} else {
return (
<div>
<StockPriceDeltaPanel pricingDelta={this.state.pricingDelta}/>
<StockTimestampPanel timestamp={this.state.timestamp}
exchangeName={this.props.exchangeName}/>
<StockSummaryPanel tickerSummary={this.state.tickerSummary}/>
<StockHistoricalChartPanel historicalData={this.state.historicalData}/>
</div>
);
}
}
}

View File

@@ -6,10 +6,32 @@ export default class extends Component {
constructor(props) {
super(props);
this.state = {
tooltip: {display: false, data: {key: '', value: ''}},
width: 0
this.margin = {
top: 20,
right: 20,
bottom: 50,
left: 0
};
this.renderingWidth = this.props.graphWidth - this.margin.left - this.margin.right;
this.renderingheight = this.props.graphHeight - this.margin.top - this.margin.bottom;
this.x = d3.scaleTime()
.range([0, this.renderingWidth]);
this.y = d3.scaleLinear()
.rangeRound([this.renderingheight, 0]);
this.line = d3.line()
.x(d => this.x(d.date))
.y(d => this.y(d.price));
}
static get defaultProps() {
return {
graphHeight: 320,
graphWidth: 400
}
}
componentDidMount() {
@@ -26,55 +48,56 @@ export default class extends Component {
}
let data = this.props.historicalData;
let parseTime = d3.timeParse("%d-%m-%y");
let parseTime = d3.timeParse("%d-%m-%Y");
data.forEach((datum) => {
datum.date = parseTime(datum.date);
datum.price = +datum.price;
});
d3.select(this.refs.historyGraph).selectAll("svg").remove();
let svg = d3.select(this.refs.historyGraph).append('svg');
// clear out any previous graph
d3.select(this.refs.historyGraph)
.selectAll("svg")
.remove();
svg.attr('height', '250')
.attr('width', '400');
// create a new one
let svg = d3.select(this.refs.historyGraph)
.append('svg')
.attr('height', this.props.graphHeight)
.attr('width', this.props.graphWidth);
let margin = {top: 20, right: 20, bottom: 30, left: 0},
width = +svg.attr('width') - margin.left - margin.right,
height = +svg.attr('height') - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
let g = svg.append("g")
.attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");
this.x.domain(d3.extent(data, d => d.date));
let x = d3.scaleTime()
.rangeRound([0, width]);
this.y.domain(d3.extent(data, d => d.price));
let y = d3.scaleLinear()
.rangeRound([height, 0]);
let scale = d3.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([0, this.renderingWidth]);
let line = d3.line()
.x(function (d) {
return x(d.date);
})
.y(function (d) {
return y(d.price);
});
// Add the x Axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (this.renderingheight + 20 ) + ")")
.call(d3.axisBottom(scale).tickFormat(d3.timeFormat("%Y-%m-%d")))
.selectAll("text")
.attr("y", 0)
.attr("x", 9)
.attr("dy", ".35em")
.attr("transform", "rotate(55)")
.style("text-anchor", "start");
x.domain(d3.extent(data, function (d) {
return d.date;
}));
y.domain(d3.extent(data, function (d) {
return d.price;
}));
// Add the y Axis
svg.append("g")
.call(d3.axisLeft(this.y));
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.call(d3.axisLeft(y))
.call(d3.axisLeft(this.y))
.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("y", 9)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Price ($)");
@@ -86,13 +109,12 @@ export default class extends Component {
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1.5)
.attr("d", line);
.attr("d", this.line);
}
render() {
let containerStyle = {
marginTop: 5,
height: 500
marginTop: 5
};
if (!this.props.historicalData) {

View File

@@ -14,6 +14,19 @@ export default class extends Component {
this.onRowClicked = this.onRowClicked.bind(this);
}
componentWillReceiveProps(nextProps) {
if (nextProps.selectedExchange !== this.props.selectedExchange) {
this.setState({
selectedSymbol: null
})
}
}
shouldComponentUpdate(nextProps, nextState) {
return nextProps.selectedExchange !== this.props.selectedExchange ||
nextState.selectedSymbol !== this.state.selectedSymbol;
}
onRowClicked(selectedSymbol) {
this.setState({
selectedSymbol
@@ -25,7 +38,7 @@ export default class extends Component {
<div>
<div style={{float: "left", marginRight: 25}}>
<LiveUpdatesGrid selectedExchange={this.props.selectedExchange}
onRowClicked={this.onRowClicked} />
onRowClicked={this.onRowClicked}/>
</div>
<div style={{float: "left"}}>
<StockDetailPanel selectedSymbol={this.state.selectedSymbol}

View File

@@ -10,29 +10,38 @@ export default class extends Component {
currentPrice: null,
delta: null,
deltaPercentage: null
}
};
}
shouldComponentUpdate(nextProps, nextState) {
return !isEqual(this.props.pricingDelta, nextProps.pricingDelta);
componentDidMount() {
this.updatePriceDelta(this.props.pricingDelta);
}
componentWillReceiveProps(nextProps, nextState) {
if (!isEqual(this.props.pricingDelta, nextProps.pricingDelta)) {
let pricingDelta = nextProps.pricingDelta;
let delta = pricingDelta.currentPrice - pricingDelta.previousPrice;
let deltaPercentage = (pricingDelta.currentPrice - pricingDelta.previousPrice) / pricingDelta.currentPrice;
this.setState({
currentPrice: pricingDelta.currentPrice,
delta,
deltaPercentage
})
this.updatePriceDelta(nextProps.pricingDelta);
}
}
updatePriceDelta(pricingDelta) {
let delta = pricingDelta.currentPrice - pricingDelta.previousPrice;
let deltaPercentage = (pricingDelta.currentPrice - pricingDelta.previousPrice) / pricingDelta.currentPrice;
this.setState({
currentPrice: pricingDelta.currentPrice,
delta,
deltaPercentage
})
}
shouldComponentUpdate(nextProps, nextState) {
return !isEqual(this.props.pricingDelta, nextProps.pricingDelta) ||
!isEqual(this.state, nextState);
}
numberFormatter(input) {
return input.toFixed(2);
return input ? input.toFixed(2) : null;
}
render() {