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;
@jmings,
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.
this.chart.render()
e.chart.render()
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
You must be logged in to reply to this topic. Login/Register