I have a nested JSON of multiple levels. The last level has the "series data" that is to be added to the highcharts options to render the chart data of interest.
I am sniffing the JSON and populating the options in each level which is set as a watched model in the controller and modifying the chart data, which is watched inside of the directive and chart updated on the change of these models.
I am looking to structure this as a reusable component and wondering on the best practice to do so. Seems to me, the "JSON selection" part and the "chart rendering" part can be best as their own directives that communicate amongst each other.
Do you concur or suggest an alternative approach?
Controller:
app.controller('MyCtrl',function($scope,Data,ForwardChart){
http.get('scripts/lib/bds2.json').success(function(api_data){
$scope.r_api_data = api_data.res;
var available_options = [];
var chosen_options= [];
var current_json = $scope.r_api_data;
for (var i=0; i<2; i++){
var json_options = _.keys(current_json);
available_options.push(json_options);
chosen_options.push(json_options[0]);
current_json = current_json[json_options[0]];
}
$scope.plot_data = function(){
var bdfs_chart = {
series : Data.get_serieses($scope.r_api_data,$scope.chosen_options)
};
$scope.bdfs_chart = $.extend(true,angular.copy(ForwardChart),bdfs_chart);
};
$scope.chosen_options = [];
$scope.available_options = available_options;
$scope.$watch('chosen_options', function(){
$scope.plot_data();
},true);
$scope.chosen_options = chosen_options;
})
});
Directive:
app.directive('intchart', function(){
return {
restrict: 'E',
template: '<div class="hc-bars"></div>',
scope: {
chartData: "=chartId"
},
link: function(scope, element, attrs){
var chartsDefaults = {
chart: {
renderTo: element[0],
type: attrs.type || null,
height: attrs.height,
width: attrs.width
},
colors: attrs.color.split(",")
};
var chart = {};
scope.$watch(function() { return scope.chartData; }, function(value){
var chart_json = {};
if (chart.hasOwnProperty('series') && chart.series.length>0){
for (var i = 0; i < value.series.length; i++) {
chart.series[i].setData(value.series[i].data);
}
} else{
$.extend(true, chart_json, chartsDefaults, value);
chart = new Highcharts.Chart(chart_json);
}
}, true);
}
}
})
function() { return scope.chartData; }
as a watcher target, it is valid to just put the string "chartData", and of course easier to read. \$\endgroup\$chosen_options
from thecurrent_json
object, this might usually work but is not guaranteed to. stackoverflow.com/questions/5525795/… \$\endgroup\$