1
votes

I am currently successfully plotting wind speed and wind direction using a standard line graph for wind speed and a scatter plot for wind direction.

The current windSpeed and windDirection DOM objects look like this:

windDirection = "[202,229,218,208,230]";
windSpeed = "[9,13.4,12,9.7,6.6]";

In reality both those variables hold hundreds, if not thousands, of data points. Each windDirection data point corresponds to the windSpeed data point at the same location, and there are an equal number of windDirection and windSpeed data points in the data set.

The goal is to plot this data onto a wind rose which has the standard N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW wind rose labels. Very much like shown in the Highcharts Polar Wind Rose demo @ highcharts.com but utilizing the existing DOM objects rather than creating HTML tables for the data.

Using two data series like shown below did not produce the desired output.

series: [{
            data: windDirection
        },{
            data: windSpeed
        }
]

I proceeded to create a data point pair from my data which follows the Highcharts API Reference for series.data example which produced output like this:

data: [[windDirection1,windSpeed1], [windDirection2,windSpeed2], and so on]

That approach failed as well. You can view it at JSFiddle: http://jsfiddle.net/02v3tduo/19/

Ideally I would like to avoid creating a copy of windDirection and windSpeed in the DOM because both data sets are fairly large already.

I did see this question/answer at SO Highcharts: Wind Rose chart with JSON data but I am not sure that the same answer applies in my case. The proposed answer seems very cumbersome when dealing with large data sets as each of the data series would need to be constructed prior to showing the chart.

I don't know how to proceed at this point. I realize that my data probably needs to be binned into 5-10 degree bins so it doesn't look as "scattered" for the lack of a better term. I can deal with the binning after the wind rose works properly.

2

2 Answers

4
votes

In general, it's not clear what you are asking for. However I'll try to answer..

First of all, you are creating string instead of array, any specific reason for that? Simply use:

windDirectionJSON = JSON.parse(windDirection);
windSpeedJSON = JSON.parse(windSpeed);
windDataJSON = [];
for (i = 0; i < windDirectionJSON.length; i++) {
    windDataJSON.push([ windDirectionJSON[i], windSpeedJSON[i] ]);
}

Now, define array of categories to be displayed on xAxis:

var categories = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'];

Then, play around with xAxis:

    xAxis: {
        min: 0,
        max: 360, // max = 360degrees
        type: "",
        tickInterval: 22.5, // show every 16th label
        tickmarkPlacement: 'on',
        labels: {
            formatter: function () {
                return categories[this.value / 22.5] + '°'; // return text for label
            }
        }
    },

And working example: http://jsfiddle.net/02v3tduo/21/

Note: it's good idea to sort your data points by wind-direction, to start from 0. Like this: http://jsfiddle.net/02v3tduo/22/

windDataJSON.sort(function(a,b) { return a[0] - b[0]; });
1
votes

I have a simple way: You can refer to series data

// Parse the data from an inline table using the Highcharts Data plugin
Highcharts.chart('container', {
    
    chart: {
        polar: true,
        type: 'column'
    },

    title: {
        text: 'Wind rose for South Shore Met Station, Oregon'
    },

    subtitle: {
        text: 'Source: or.water.usgs.gov'
    },

    pane: {
        size: '85%'
    },

    legend: {
        align: 'right',
        verticalAlign: 'top',
        y: 100,
        layout: 'vertical'
    },

    xAxis: {
        tickmarkPlacement: 'on',
        type:'category'
    },

    yAxis: {
        min: 0,
        endOnTick: false,
        showLastLabel: true,
        
        
        reversedStacks: false
    },

   
		series: [{
				"data": [
					["ios1", 12],
					["ios2", 12],
					["ios3", 12],
					["ios4", 91],
					["ios5", 11],
					["ios6", 12],
					["ios7", 18],
					["ios8",19],
					["ios9",12],
					["ios10",34],
					["ios11",11],
					["ios12",71],
					["ios13", 66],
					["ios14", 21],


				],
				"type": "column",
				"name": "<40G"
			}, {
				"data": [
					["ios1", 12],
					["ios2", 33],
					["ios3", 12],
					["ios4", 10],
					["ios5", 11],
					["ios6", 13],
					["ios7", 9],
					["ios8",20],
					["ios9",13],
					["ios10",74],
					["ios11",21],
					["ios12",72],
					["ios13", 67],
					["ios14", 22],

				],
				"type": "column",
				"name": "40-100G,"
			}, {
				"data": [
					["ios1", 12],
					["ios2", 34],
					["ios3", 23],
					["ios4", 11],
					["ios5", 31],
					["ios6", 14],
					["ios7", 10],
					["ios8", 21],
					["ios9", 14],
					["ios10", 21],
					["ios11", 21],
					["ios12", 73],
					["ios13", 68],
					["ios14", 23],

				],
				"type": "column",
				"name": "100-500G,"
			}, {
				"data": [
					["ios1", 12],
					["ios2", 45],
					["ios3", 14],
					["ios4", 12],
					["ios5", 31],
					["ios6", 15],
					["ios7", 11],
					["ios8", 22],
					["ios9", 15],
					["ios10", 22],
					["ios11", 21],
					["ios12", 74],
					["ios13", 69],
					["ios14", 24],

				],
				"type": "column",
				"name": ">500G"
			}],
    plotOptions: {
        series: {
            stacking: 'normal',
            shadow: false,
            groupPadding: 0,
            pointPlacement: 'on'
        }
    }
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>

<div id="container" style="min-width: 420px; max-width: 600px; height: 400px; margin: 0 auto"></div>