我正在使用React(与Rails)并使用一个名为AnyChart的图表库。但是,我在渲染器中使用的AnyChart代码会自动寻找一个<div id="container"></div>
元素以将图表附加到该元素上。如果我将图表代码与容器div一起放入渲染器中,则会出现错误,因为图表代码无法找到div,因为它尚未在DOM上。
我尝试使用Google搜索,但只发现了关于门户和裁判的内容,这些东西似乎不适用于我的问题。
我知道我可以将容器div移动到布局视图模板,但是我希望能够在图表下方的组件上呈现其他内容。这是我的整个StockContainer组件和InputField组件:
import React from 'react';
import InputField from '../components/InputField'
class StockContainer extends React.Component {
constructor(props){
super(props)
this.state = {
stockTicker: ''
}
this.handleStockTickerChange = this.handleStockTickerChange.bind(this);
this.handleClearForm = this.handleClearForm.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleClearForm(event){
event.preventDefault();
this.setState({
stockTicker: ''
});
}
handleStockTickerChange(event) {
this.setState({stockTicker: event.target.value});
}
handleSubmit(event){
event.preventDefault();
let body = {
symbol: this.state.stockTicker
}
console.log("Getting stock data for: " + body.symbol)
this.handleClearForm(event);
}
componentDidMount() {
}
render() {
var table, mapping, chart;
table = anychart.data.table();
table.addData([
['2015-12-25', 512.53, 514.88, 505.69, 507.34],
['2015-12-26', 511.83, 514.98, 505.59, 506.23],
['2015-12-27', 511.22, 515.30, 505.49, 506.47],
...sample data that will later be imported from an API
['2016-01-07', 510.93, 516.07, 506.00, 510.99],
['2016-01-08', 510.88, 515.93, 505.22, 509.95],
['2016-01-09', 509.12, 515.97, 505.15, 510.12],
['2016-01-10', 508.53, 516.13, 505.66, 510.42]
]);
// mapping the data
mapping = table.mapAs();
mapping.addField('open', 1, 'first');
mapping.addField('high', 2, 'max');
mapping.addField('low', 3, 'min');
mapping.addField('close', 4, 'last');
mapping.addField('value', 4, 'last');
// defining the chart type
chart = anychart.stock();
// set the series type
chart.plot(0).ohlc(mapping).name('ACME Corp.');
// setting the chart title
chart.title('AnyStock Demo');
// display the chart
chart.container('container');
chart.draw();
return(
<div>
<h1>Research/Add a Stock</h1>
<form onSubmit={this.handleSubmit}>
<InputField
label='Stock Symbol'
name='ticker'
content={this.state.stockTicker}
handleChange={this.handleStockTickerChange}
/>
<input type='submit' value='Get Info'/>
</form>
<div id="container"></div>
</div>
)
}
}
export default StockContainer;
import React from 'react';
const InputField =(props) =>{
return(
<label>{props.label}
<input
type='text'
name={props.name}
value={props.content}
onChange={props.handleChange}
/>
</label>
)
}
export default InputField
答案 0 :(得分:0)
就像上面评论中的Ishwor一样,您是否尝试过将chart.container()
和chart.draw()
方法移动到组件的componentDidMount()
挂钩中?
如果您可以为您的组件提供其余代码,我们也许可以提供帮助。
import React from 'react';
import InputField from '../components/InputField'
class StockContainer extends React.Component {
constructor(props){
super(props)
this.state = {
stockTicker: ''
}
let table = anychart.data.table();
table.addData([
['2015-12-25', 512.53, 514.88, 505.69, 507.34],
['2015-12-26', 511.83, 514.98, 505.59, 506.23],
['2015-12-27', 511.22, 515.30, 505.49, 506.47],
...sample data that will later be imported from an API
]);
// mapping the data
let mapping = table.mapAs();
mapping.addField('open', 1, 'first');
mapping.addField('high', 2, 'max');
mapping.addField('low', 3, 'min');
mapping.addField('close', 4, 'last');
mapping.addField('value', 4, 'last');
// defining the chart type
let chart = anychart.stock();
// set the series type
chart.plot(0).ohlc(mapping).name('ACME Corp.');
// setting the chart title
chart.title('AnyStock Demo');
// to be able to reference these later, if needed
this.table = table;
this.mapping = mapping;
this.chart = chart;
this.handleStockTickerChange = this.handleStockTickerChange.bind(this);
this.handleClearForm = this.handleClearForm.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
// draw the chart
this.drawMyAwesomeChart = this.drawMyAwesomeChart.bind(this);
}
componentDidMount() {
this.chart.container('container');
this.drawMyAwesomeChart()
}
componentDidUpdate() {
// do some checks here to see if you need to draw chart?
// this.drawMyAwesomeChart()
}
drawMyAwesomeChart() {
this.chart.draw();
}
}
然后,您可以绑定一个专门负责在股票报价变动时刷新图表的功能。我尚未对此进行全面测试,但是遵循这些思路的东西应该可以工作?
答案 1 :(得分:0)
尝试使用生命周期方法componentDidUpdate
答案 2 :(得分:0)
我知道它可以正常工作。这是我的代码:
import React from 'react';
import InputField from '../components/InputField'
const divStyle = {
// width: '100%',
// height: '100%'
};
class StockContainer extends React.Component {
constructor(props){
super(props)
this.state = {
stockTicker: '',
currentPrices: [],
show: false
}
this.handleStockTickerChange = this.handleStockTickerChange.bind(this);
this.handleClearForm = this.handleClearForm.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.getDataForStockChart = this.getDataForStockChart.bind(this);
}
handleClearForm(event){
// event.preventDefault();
this.setState({ stockTicker: '' });
}
handleStockTickerChange(event) {
this.setState({stockTicker: event.target.value});
}
getDataForStockChart(){
let arrayOfArrays = []
fetch(`https://api.iextrading.com/1.0/stock/${this.state.stockTicker}/chart/1y`)
.then(response => {
if (response.ok) {
return response;
} else {
let errorMessage = `${response.status} (${response.statusText})`,
error = new Error(errorMessage);
throw(error);
}
})
.then(response => response.json())
.then(body => {
body.forEach(obj => {
arrayOfArrays.push([obj["date"], obj["open"], obj["high"], obj["low"], obj["close"]]);
});
this.setState({
show: true,
currentPrices: arrayOfArrays
});
})
.catch(error => console.error(`Error in fetch: ${error.message}`));
}
componentDidUpdate(prevProps, prevState){
var table, mapping, chart;
if (this.state.currentPrices.length > 1 && this.state.show){
this.refs.myInput.innerHTML = '';
// node = this.myRef.current
table = anychart.data.table();
table.addData(this.state.currentPrices);
mapping = table.mapAs();
mapping.addField('open', 1, 'first');
mapping.addField('high', 2, 'max');
mapping.addField('low', 3, 'min');
mapping.addField('close', 4, 'last');
mapping.addField('value', 4, 'last');
chart = anychart.stock();
chart.plot(0).ohlc(mapping).name('Stock Chart');
chart.title('AnyStock Demo');
chart.container('container');
chart.draw();
this.setState({show: false})
this.handleClearForm(event);
}
}
// shouldComponentUpdate(nextProps, nextState){
// if (this.state.show)
// }
handleSubmit(event){
event.preventDefault();
this.getDataForStockChart();
this.handleClearForm();
}
render() {
return(
<div>
<h1>Research/Add a Stock</h1>
<form onSubmit={this.handleSubmit}>
<InputField
label='Stock Symbol'
name='ticker'
content={this.state.stockTicker}
handleChange={this.handleStockTickerChange}
/>
<input type='submit' value='Get Info'/>
</form>
<div id="container" ref="myInput" style={divStyle}></div>
</div>
)
}
}
export default StockContainer;