Reputation: 567
Note: I'll be referring to the Highcharts demo column chart throughout this question. The demo chart shows monthly rainfall for 4 major cities.
I'm using WordPress to allow users to dynamically generate a Highcharts column chart.
Rather than have users enter all data points for a particular city (12 points: one for each month), I thought it'd be more intuitive to have users enter the data points for each month (4 points: one for each city).
In the screenshot below, you can see how I set up the data entry: users enter the month on the left and the month's rainfall for each city on the right:
Users then enter the name and choose a color for each city in a separate area of the page.
In the code that generates the demo chart, you can see that the data points are grouped by city:
series: [{
name: 'Tokyo',
data: [49.9, 71.5, 106.4, ...]
}, {
name: 'New York',
data: [83.6, 78.8, 98.5, ...]
} ...
However, the way I built things in WordPress, I can only figure out how to generate an array of data points for each month, such that I get this output:
// array #1
[49.9, 83.6, 48.9, 42.4]
// array #2
[71.5, 78.8, 38.8, 33.2]
// array #3
[106.4, 98.5, 39.3, 34.5]
// array #4
[129.2, 93.4, 41.4, 39.7]
// etc.
How do I create arrays of the nth values in each array? In other words, instead of looping through the values in each month, I want to just grab the first values for each month and drop them into a new array, then grab the 2nd values for each month and drop them into another array, and so on.
So, I should end up with this:
// array #1 (made up of 1st value of each array from above)
[49.9, 71.5, 106.4, 129.2]
// array #2 (made up of 2nd value of each array from above)
[83.6, 78.8, 98.5, 93.4]
// array #3 (made up of 3rd value of each array from above)
[48.9, 38.8, 39.3, 41.4]
// array #4 (made up of 4th value of each array from above)
[42.4, 33.2, 34.5, 39.7]
// etc.
I've managed to get pretty close with this code...
// outer loop: iterate through each month
foreach ( $column_data as $key => $column ) :
// get the X-axis labels (names of the month)
$x_label_array[$key] = $column['label'];
// create an empty array to accept values for each city
${'column_' . $key . '_array'} = array();
// inner loop: iterate through data points for each month
foreach ( $column['columns_4'] as $key_inner => $multi_column ) :
array_push( ${'column_' . $key_inner . '_array'}, (float)$multi_column['value'] );
endforeach;
endforeach;
...but for each iteration, it skips one more value in each successive array, such that I get this output:
// this is perfect!
Array(
[0] => 49.9
[1] => 71.5
[2] => 106.4
[3] => 129.2
)
// missing 1st value
Array(
[0] => 78.8
[1] => 98.5
[2] => 93.4
)
// missing 1st and 2nd values
Array(
[0] => 39.3
[1] => 41.4
)
// missing 1st, 2nd, and 3rd values
Array(
[0] => 39.7
)
Plus, the whole notion of using a new array for each loop seems pretty janky. Is there a better way? Is this possible in PHP, or should I restructure how I ask the user to enter the data?
Upvotes: 2
Views: 276
Reputation: 116
First of all, I like the idea of CMS controllable Highcharts! It's something I've done before too.
Rather than have users enter all data points for a particular city (12 points: one for each month), I thought it'd be more intuitive to have users enter the data points for each month (4 points: one for each city).
Personally, I think that's a bit counter intuitive. If you add another city, then a new value box pops up in 12 different places. Whereas you could have a nice ajax process or something at the end of the input screen which allows the WordPress CMS user to add another city dynamically, and entering the 12 new values in one place.
Anyway, I don't know your website so your way could be more intuitive. For your specific problem, you can think of your array of arrays as a matrix - you just need to make them officially an array of arrays rather than lots of single arrays.
Then you can use array_map to solve your problem:
$matrix = [
[49.9, 83.6, 48.9, 42.4],
[71.5, 78.8, 38.8, 33.2],
[106.4, 98.5, 39.3, 34.5],
[129.2, 93.4, 41.4, 39.7]
];
array_unshift($matrix, null);
$matrix = call_user_func_array('array_map', $matrix);
This guy provides a really good explanation of this above PHP process (better than I could!).
Upvotes: 3