HighCharts: Basic Graphing

This entry is part 1 of 2 in the series React: Highcharts

HighCharts is a pretty cool graphing package. Below is an example of how you can create an universal React class for a HighCharts graph.

You will need to install the package. At the time of this writing I am using 5.0.6.

You will also need to import HighCharts and require the charts.

import Highcharts from "highcharts/highcharts.js";
window.Highcharts = Highcharts;
require("highcharts/highcharts-more.js")(Highcharts);

In the state I hold these values to manage how the chart loads and displays data.

getInitialState: function() {
	return {
		chartSettings: null, //Holds the chart settings data
		loaded: false,	//Determines if the chart has been loaded
		chart: null,	//The chart
		data: [],	//The data to utilize for the chart. It's most likely in series format
	};
},

In the component methods check to see when the class has been loaded with data or reset if needed.

componentDidUpdate: function() {
	if (!this.state.loaded) { //The chart hasn't been loaded with data so load it and refresh the chart
		this.setState({
			loaded: true,
			data: this.props.data
		}, () => { this.chart(); });
	}
},
componentWillReceiveProps: function(newprops) {
	if (this.state.loaded && this.props != newprops) { //The chart has been loaded but the data has changed. Refresh the chart after
		this.setState({
			data: newprops.data
		}, () => { this.chart(); });
	}
},

The class the render method is how the chart assigns to the UI.

render: function() {
	return (<div id={this.props.id}></div>
); },

You can create a “chart” method. Which you can use to manage the display of the chart. The main section of it is how to display the chart after you have modified the chart settings. You could also utilize a props for controlling whether to show the loading or not. Totally up to you.

this.setState({
	loaded: true,			//The data and chart has been loaded
	chart: new Highcharts.Chart(chartSettings) //Set the chart
}, () => {
	if (!this.props.data.length == 0) { //If no data is present yet then show a loading image
		this.state.chart.showLoading();
		this.state.chart.redraw();
	} else {			//The data has been loaded.
		this.state.chart.hideLoading();
		this.state.chart.redraw();
	}
});

In the “chart” method you should clean up your existing chart before generating a new one.

if (this.state.chart !== null) {
	this.state.chart.destroy();
	this.state.chart = null;
}

There are so many ways of controlling the chartsettings. I will try to cover a vast majority of the options. The basic definition looks like this.

chartSettings = $.extend(true, {},
	this.props.chartSettings,
	{
		chart: {
			renderTo: this.props.id,	//The id you passed into the class
			backgroundColor: "",
            		type: this.props.chart_type,	//By passing in the chart type it will be open to various types of charts.
            		height: 500,            	//You can specify the height of the graph if you want.
            		zoomType: "xy",            	//If you want to be able to zoom.	
            	},
            	credits: {
			enabled: false	//Turns off the powered by
		},
            	title: {
                	text: this.props.title,
                	style: { color: "white" }
            	},
            	subtitle: {
                	text: this.props.sub_title
            	},
		tooltip: {
		},
		plotOptions: {
		},
		series: thisInstance.state.data
	});

Tooltip has various options. One I like to use is the “formatter” functionality. This will allow you to modify what is displayed on hover.

tooltip: {
	formatter: function(){
		var pointIndex = this.point.index;
		var seriesName = this.point.series.name;
	}
}

There is also xAxis option. You can do a variety of different things. Depending on how you create your graph determines what options you should use. The type in xAxis can have a few different options. I show you “datetime” below. But you can also choose “linear” which is numerical data as well as “category” which allows you to put string data on the X axis.

xAxis: {
	type: "datetime",
	categories: this.props.categories,
	title: {
		enabled: true,
	},
	showLastLabel: true,
	showFirstLabel: true,
	tickInterval: 15,		//I chose to increment to x value by 15 days. But you can choose whatever you want
	labels: {
		formatter: function () {
			if (the type is a date == "date") {
				return Highcharts.dateFormat("%m/%d", this.value);	//You can format however you like
			} else {
				return this.value;
			}
		}
	}
},

There is also yAxis option. You can do a variety of different things. Depending on how you create your graph determines what options you should use. Here is an example.

yAxis: {
	allowDecimals: true,
	title: {
		align: "high"
	},
	labels: {
		overflow: "justify",
		formatter: function() {
			return this.value;
		}
	},
},

You can add onClick events to series points if you want.

plotOptions: {
	series: {
		point: {
			events: {
				click: function(e){
				}
			}
		}
	}
}

There are various graph types. For example “pie”, “bar”, “scatter”, etc. Here are a few different examples of a basic setup.

plotOptions: {
	pie: {
		allowPointSelect: true,		//When you click the pie slice it moves out slightly
		cursor: "pointer",
		shadow: false,
		dataLabels: {
			enabled: true,
			formatter:function(){
			},
			color: "white",
			style: {
				textShadow: false 
			}
		}
	},
	bar: {
		dataLabels: {
			enabled: true,
			allowOverlap: true,	//Labels will overlap. Turns this off if you don't want your labels to overlap.
		}
	},
	scatter: {
		dataLabels: {
			crop: false,		//Labels will not be hidden
		},
		marker: {
			radius: 3,
			states: {
				hover: {
					enabled: true
				}
			}
		},
		states: {
			hover: {
				marker: {
					enabled: false
				}
			}
		}
	}
}