You must be logged in to post your query.
Home › Forums › Chart Support › Context error on this.chart.render()
Tagged: Context error
I’m getting an “Uncaught TypeError: Cannot read property ‘render’ of undefined” in my toggle data series function on line “this.chart.render();”. I think this is an error with my this context/binding/etc. Any help?
import React, { Component } from 'react';
import PageNumber from './common/pageNumber';
import { paginate } from '../utils/paginate';
import Filter from "./common/filter";
//import trump from '../images/trump.jpeg';/
import trump from "../images/48397172_587551211695038_9179185258694705152_n.png"
import '../style/graphPage.css';
import CanvasJSReact from '../utils/canvasjs.react';
import Calendar from "react-range-calendar";
import TweetRow from './tweetRow';
import AVLTree from 'avl';
import { LoadingButton } from './common/loadingButton';
import ToggleFilter from './common/toggleFilter';
import NavBar from "./common/navBar";
import TweetFilters from './common/tweetFilters';
// Create chart object
let CanvasJSChart = CanvasJSReact.CanvasJSChart;
// Establish our backend base URL
const baseURL = "http://localhost:8081";
class DataAnalyticsPage extends Component {
constructor(props) {
super(props);
this.state = {
months: [], // Possible months
selectedMonth: " -- select a month -- ", // Current selected month
options: {
theme: "light2",
animationEnabled: true,
zoomEnabled: true,
title:{
text: "Units Sold VS Profit"
},
subtitles: [{
text: "Click Legend to Hide or Unhide Data Series"
}],
axisX: {
title: "States"
},
axisY: {
title: "Units Sold",
titleFontColor: "#6D78AD",
lineColor: "#6D78AD",
labelFontColor: "#6D78AD",
tickColor: "#6D78AD"
},
axisY2: {
title: "Profit in USD",
titleFontColor: "#51CDA0",
lineColor: "#51CDA0",
labelFontColor: "#51CDA0",
tickColor: "#51CDA0"
},
toolTip: {
shared: true
},
legend: {
cursor: "pointer",
itemclick: this.toggleDataSeries
},
data: [{
type: "spline",
name: "US CPI",
showInLegend: true,
xValueFormatString: "MMM YYYY",
yValueFormatString: "#,##0 Units",
dataPoints: []
},
{
type: "spline",
name: "France CPI",
showInLegend: true,
xValueFormatString: "MMM YYYY",
yValueFormatString: "#,##0 Units",
dataPoints: []
},
{
type: "spline",
name: "Canada CPI",
showInLegend: true,
xValueFormatString: "MMM YYYY",
yValueFormatString: "#,##0 Units",
dataPoints: []
},
{
type: "spline",
name: "Germany CPI",
showInLegend: true,
xValueFormatString: "MMM YYYY",
yValueFormatString: "#,##0 Units",
dataPoints: []
},
{
type: "spline",
name: "UK CPI",
showInLegend: true,
xValueFormatString: "MMM YYYY",
yValueFormatString: "#,##0 Units",
dataPoints: []
},
{
type: "spline",
name: "US Unemployment",
axisYType: "secondary",
showInLegend: true,
xValueFormatString: "MMM YYYY",
yValueFormatString: "#,##0 Units",
dataPoints: []
},
{
type: "spline",
name: "France Unemployment",
axisYType: "secondary",
showInLegend: true,
xValueFormatString: "MMM YYYY",
yValueFormatString: "#,##0 Units",
dataPoints: []
},
{
type: "spline",
name: "Canada Unemployment",
axisYType: "secondary",
showInLegend: true,
xValueFormatString: "MMM YYYY",
yValueFormatString: "#,##0 Units",
dataPoints: []
},
{
type: "spline",
name: "Germany Unemployment",
axisYType: "secondary",
showInLegend: true,
xValueFormatString: "MMM YYYY",
yValueFormatString: "#,##0 Units",
dataPoints: []
},
{
type: "spline",
name: "UK Unemployment",
axisYType: "secondary",
showInLegend: true,
xValueFormatString: "MMM YYYY",
yValueFormatString: "#,##0 Units",
dataPoints: []
}
]}, // Graph options for CanvasJSReact graph
// Misc
loading: false, // Is the page currently loading
};
this.toggleDataSeries = this.toggleDataSeries.bind(this);
}
toggleDataSeries(e){
if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
}
else{
e.dataSeries.visible = true;
}
this.chart.render();
}
componentDidMount() {
this.getCPI();
this.getUnemployment();
// this.getApprovals();
}
getCPI() {
// Establish URl to backend
let dataURL = baseURL + "/CPI";
// Make backend calls
fetch(dataURL, {
method: 'GET' // The type of HTTP request.
})
.then(this.checkStatus)
.then(res => res.json()) // Convert the response data to a JSON.
.then(data =>
{
// Get current options and chart
let opts = this.state.options;
let chart = this.chart;
// Update data points
let USData = [];
let FranceData = [];
let GermanyData = [];
let UKData = [];
let CanadaData = [];
let months = [];
for (var i = 0; i < data.length; i++) {
months.push(<option key={i} value={data[i].date}>{data[i].date}</option>)
if (data[i].country.localeCompare("US") === 0) {
USData.push({
x: new Date(data[i].date),
y: data[i].CPI
});
} else if (data[i].country.localeCompare("France") === 0) {
FranceData.push({
x: new Date(data[i].date),
y: data[i].CPI
});
} else if (data[i].country.localeCompare("Germany") === 0) {
GermanyData.push({
x: new Date(data[i].date),
y: data[i].CPI
});
} else if (data[i].country.localeCompare("UK") === 0) {
UKData.push({
x: new Date(data[i].date),
y: data[i].CPI
});
} else if (data[i].country.localeCompare("Canada") === 0) {
CanadaData.push({
x: new Date(data[i].date),
y: data[i].CPI
});
};
}
// Update the current graph options
opts.data[0].dataPoints = USData;
opts.data[1].dataPoints = FranceData;
opts.data[2].dataPoints = CanadaData;
opts.data[3].dataPoints = GermanyData;
opts.data[4].dataPoints = UKData;
// Set state and rerender the graph
this.setState({
options: opts,
months: months
}, () => {
chart.render();
});
})
.then()
.catch(err => console.log(err)) // Print the error if there is one.
}
getUnemployment() {
// Establish URl to backend
let dataURL = baseURL + "/Unemployment";
// Make backend calls
fetch(dataURL, {
method: 'GET' // The type of HTTP request.
})
.then(this.checkStatus)
.then(res => res.json()) // Convert the response data to a JSON.
.then(data =>
{
// Get current options and chart
let opts = this.state.options;
let chart = this.chart;
// Update data points
let USData = [];
let FranceData = [];
let GermanyData = [];
let UKData = [];
let CanadaData = [];
for (var i = 0; i < data.length; i++) {
if (data[i].country.localeCompare("US") === 0) {
USData.push({
x: new Date(data[i].date),
y: data[i].rate
});
} else if (data[i].country.localeCompare("France") === 0) {
FranceData.push({
x: new Date(data[i].date),
y: data[i].rate
});
} else if (data[i].country.localeCompare("Germany") === 0) {
GermanyData.push({
x: new Date(data[i].date),
y: data[i].rate
});
} else if (data[i].country.localeCompare("UK") === 0) {
UKData.push({
x: new Date(data[i].date),
y: data[i].rate
});
} else if (data[i].country.localeCompare("Canada") === 0) {
CanadaData.push({
x: new Date(data[i].date),
y: data[i].rate
});
};
}
// Update the current graph options
opts.data[5].dataPoints = USData;
opts.data[6].dataPoints = FranceData;
opts.data[7].dataPoints = CanadaData;
opts.data[8].dataPoints = GermanyData;
opts.data[9].dataPoints = UKData;
// Set state and rerender the graph
this.setState({
options: opts
}, () => {
chart.render();
});
})
.then()
.catch(err => console.log(err)) // Print the error if there is one.
}
// ---------------------------------------- EVENT HANDLERS ---------------------------------------------- //
/**
* This function handles the event raised by PageNumber onPageChange
* @param {int} page - the page number being changed to
*/
// Handle the event raised by PageNumber onPageChange
handlePageChange = (page) => {
console.log('handling page = ' + page);
const curPage = this.state.currentPage;
const pageSize = this.state.pageSize;
// Store the current TweetRow items
let currentTweets = this.state.currentTweets;
const displayedTweets = paginate(currentTweets, curPage, pageSize);
let startIndex = (curPage - 1) * pageSize;
for (var i = 0; i < this.state.pageSize; i++) {
currentTweets[startIndex + i] = displayedTweets[i];
}
console.log(displayedTweets);
// Set state's active page and current TweetRow items
this.setState({ currentPage: page, currentTweets: currentTweets });
}
/**
* Called when a dataset is selected from the dropdown
* @param {event} e - Event that triggered this handler to be called. The data name is available
* at e.target.value
*/
handleSelectMonth = (e) => {
this.setState({ selectedMonth: e.target.value });
}
/**
*
* @param {*} tweet
* @param {*} added
* @param {*} id
*/
handleSearch = (e) => {
}
// ---------------------------------------- HELPER FUNCTIONS ---------------------------------------------- //
/**
* This function updates the tweets stored in this.state.currentTweets in order to cause the page to re-render
* Currently, I am creating a new TweetRow object to replace the existing one, but I don't know if this is correct
* And I'm obviously not getting the tweets to reload on pagechange
* @param {int} tweet - the embedded tweet's official Twitter id
* @param {boolean} added - has the tweet been added by the current user
* @param {int} id - the local id of the TweetRow object; ordered by however database returns values
*/
updateCurrentTweets(tweet, added, id) {
const curPage = this.state.currentPage;
const pageSize = this.state.pageSize;
// Store the current TweetRow items
let currentTweets = this.state.currentTweets;
let startIndex = (curPage - 1) * pageSize;
let insert = <TweetRow id={id} tweetId={tweet} added={added} onAdd={this.handleAdd}/>;
currentTweets[startIndex + id] = insert;
console.log('added is ' + added + '; id is ' + id);
this.setState( { currentTweets: currentTweets });
}
/**
* CheckStatus function ensures we get an okay response from the server
* @param {response} response - response from fetch
* @return {response} either returns the same input or throws an error
*/
checkStatus(response) {
if (response.ok) {
return response;
} else {
throw Error("Error in request: " + response.statusText);
}
}
render() {
const { selectedMonth, months, loading, options } = this.state;
console.log(months);
return (
<main className="main">
<NavBar/>
<section className="header">
<h1>Data Analytics Page</h1>
<p>Description, Description, Description, Description, Description, Description, Description...</p>
</section>
<CanvasJSChart
options={options}
onRef={ref => this.chart = ref}
/>
<section id="tweetSearch">
<select value={ selectedMonth } onChange={this.handleSelectMonth} className="dropdown" id="monthDropdown">
<option select key={-1} value={selectedMonth}> -- select a month -- </option>
{ months }
</select>
<section id="tweetFilters">
<TweetFilters/>
<LoadingButton
isLoading={loading}
search={this.handleSearch}
/>
</section>
</section>
</main>
);
}
}
export default DataAnalyticsPage;
In the code sample that you have shared, replacing this.chart.render()
with e.chart.render()
should work fine. Please take a look at this documentation page for more information to Hide Unhide Data Series on Legend Click.
If you are still facing any issue, kindly create a sample project reproducing the issue and share it with us over Google-Drive or Onedrive so that we can run the code locally, understand the scenario better and help you out.
___________
Indranil Deo
Team CanvasJS
Tagged: Context error
You must be logged in to reply to this topic.