So I have a large amount of data that I need to display all stored in separate CSV files. So I created two charts just fine in highcharts, one line, one area, but instead of copying and pasting the function over and over again I was hoping I could just iterate through it like so:
var library = ['data/data.csv', 'data/attendanceGroup.csv'];
var libraryLength = library.length;
var area =['#attendanceRoom','#attendanceGroup'];
var i = 0;
function areaChart(){
$(function () {
$.get(library[i], function(csv) {
$(area[i]).highcharts({
chart: {
type: 'area'
},
data: {
csv: csv
},
title: {
text: 'Attendance by Room'
},
yAxis: {
title: {
text: null
},
minorTickInterval: 'auto'
},
legend:{
align: 'left',
verticalAlign: 'top',
floating: true
},
});
});
});
}
for (i = 0; i < libraryLength; i++){
areaChart();
}
I was looking at this Manage multiple highchart charts in a single webpage using jQuery.extend() or Highcharts.setOptions but that sets options for each individual chart and then you just make them over and over again. I thought a better solution might be to just have the one function and then just re-run it for each individual chart especially since I'm pulling the data from .CSV files.
So is this possible? Or should I go with jQuery.extend()?
Thanks for any help in advance!
Just two things I would improve:
$(function () { }); - I would encapsulate whole JS, not only part with AJAX and Highcharts:
$(function () {
var library = ['data/data.csv', 'data/attendanceGroup.csv'];
...
for (i = 0; i < libraryLength; i++){
areaChart();
}
});
make library[i] and area[i] as arguments for areaChart():
$(function () {
var library = ['data/data.csv', 'data/attendanceGroup.csv'];
...
function areaChart(lib, area){
$.get(lib, function(csv) {
$(area).highcharts({
chart: {
type: 'area'
},
data: {
csv: csv
}
});
});
}
for (i = 0; i < libraryLength; i++){
areaChart(library[i], area[i]);
}
});
Of course, you can add more params to areaChart for example type, and pass on what kind of the chart should be rendered:
$(function () {
var library = ['data/data.csv', 'data/attendanceGroup.csv'];
var types = ['line', 'area'];
...
function areaChart(lib, area, type){
$.get(lib, function(csv) {
$(area).highcharts({
chart: {
type: type
},
data: {
csv: csv
}
});
});
}
for (i = 0; i < libraryLength; i++){
areaChart(library[i], area[i], types[i]);
}
});
Don't overdo with the params, no one likes to read 10params and control order etc. Instead you may consider passing one object param (renamed from areaChart to myChart):
myChart({
lib: library[i],
area: area[i],
type: types[i]
});
And in myChart() method:
function myChart(options) {
$.get(options.lib, function(csv) {
$(options.area).highcharts({
chart: {
type: options.type
},
data: {
csv: csv
}
});
});
}
My goal is to dynamically update the array table for google charts.
I am unable update the content of the Google Chart with the data I'm passing from my Java class. I use tempGraph2 to initialize the graph when the page load but when the user clicks on a file name, the java class passes a formatted string as follows but it is not updating the content of the chart:
[["Domain names","Domain Count"],["Positive-Female",6],["Positive- GenderNeutral",0],["Positive-Male",17],["Neutral-Female",6],["Neutral-GenderNeutral",0],["Neutral-Male",8],["Negative-Female",3],["Negative-GenderNeutral",0],["Negative-Male",19]]
The value is linked using ng-model as follows:
<div ng:model="tempGraph2"
qn:barcolumns="[
{type:'string', name: 'Categories'},
{type:'number', name: 'Counts'}]"
qn:bar="{
legend : {position: 'none'},
chart: { subtitle: 'popularity by percentage' },
chartArea: {height: 400},
backgroundColor: '#F7F7F7'}"></div>
<div ng:model="tempGraph2"
qn:tabcolumns="[
{type:'string', name: 'Categories'},
{type:'number', name: 'Counts'}]"
qn:options="{
backgroundColor: '#F7F7F7'}"></div>
<p> {{tempGraph}}</p>
<p>{{tempGraph2}}</p>
Even using the ng-model, the graph is not being updated but the {{tempGraph2}} output is. Below is the content of the javascript.
Question: Do I need to create something to redraw the graph after I pull in new data or is there another set of logic I need to be using.
app.js:
$scope.tempGraph2 = [['Domain names','Domain Count'],
["placeholder",6],];
$scope.selectJobRow = function(rowIndex) {
$scope.selectedJobRow = rowIndex;
if ($scope.selectedJobRow > -1) {
$scope.showProgress();
$scope.input.job = $scope.input.jobList[rowIndex];
var prepFile = {fileName: $scope.input.job.outputFile, data: "test"}
$http.post("file/graph", prepFile)
.success(function(data, status) {
$scope.input.graphData = data;
$scope.tempGraph2 = $scope.input.graphData.data;
$scope.hideProgress();
$scope.tempGraph = [
['Domain names','Domain Count'],
["Positive-Female",123],
["Positive-GenderNeutral",22],
["Positive-Male",4],
["Neutral-Female",6],
["Neutral-GenderNeutral",76],
["Neutral-Male",8],
["Negative-Female",3],
["Negative-GenderNeutral",98],
["Negative-Male",19]
];
})
.error(function(data, status) {
$scope.hideProgress();
alert("Failed!!!!");
});
}
}
angular.module('charts.table', [
])
.directive('qnOptions', [
function() {
return {
require: '?ngModel',
link: function(scope, element, attr, controller) {
var settings = {
is3D: true
};
var getOptions = function() {
return angular.extend({ }, settings, scope.$eval(attr.qnOptions));
};
// creates instance of datatable and adds columns from settings
var getDataTable = function() {
var columns = scope.$eval(attr.qnTabcolumns);
var data = new google.visualization.DataTable();
angular.forEach(columns, function(column) {
data.addColumn(column.type, column.name);
});
return data;
};
var init = function() {
var options = getOptions();
if (controller) {
var drawChart = function() {
//var data = getDataTable();
// set model
// data.addRows(controller.$viewValue);
var data = new google.visualization.arrayToDataTable(controller.$viewValue);
/*var data = new google.visualization.arrayToDataTable([
['Move', 'Percentage'],
["Positive-Female",6],
["Positive-GenderNeutral",0],
["Positive-Male",17],
["Neutral-Female",6],
["Neutral-GenderNeutral",0],
["Neutral-Male",8],
["Negative-Female",3],
["Negative-GenderNeutral",0]
]); */
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.Table(element[0]);
chart.draw(data);
};
controller.$render = function() {
drawChart();
};
}
if (controller) {
// Force a render to override
controller.$render();
}
};
// Watch for changes to the directives options
scope.$watch(getOptions, init, true);
scope.$watch(getDataTable, init, true);
}
};
}
]);
I can get the table to update from when I toggle between static data but not with dynamic data.
I am trying to integrate Kendo UI into AngularJS. I've come across an issue which I can't seem to solve. I am fairly new to AngularJS and am trying to follow the guidelines as best as possible.
The issue at hand is that I am unable to obtain a reference to my Kendo UI grid. I've already gone through a couple of similar SO questions, but none seem to resolve the issue. The main difference in my code is that I'm using controllerAs instead of $scope.
Datagrid Controller:
'use strict';
angular
.module('ayotaWebFeApp.datagrid')
.controller('DataGridController', DataGridController);
DataGridController.$inject = ['$scope','$routeParams', 'datagriddataservice'];
function DataGridController($scope, $routeParams, dataservice) {
console.info('DataGridController instantiated.');
var vm = this;
vm.grid = {};
vm.dataTitle = $routeParams.datatype;
activate();
$scope.$on('kendoWidgetCreated', function(event, widget) {
console.log('kendowidgetcreated event: ', event);
console.log('kendowidgetcreated widget: ', widget);
$scope.$apply();
});
function activate() {
console.info('Activate was called.');
return getDataFields().then(function() {
console.info('Loaded data fields for data type :'+$routeParams.datatype);
});
}
function initGridOptions(columnSpec) {
var restURL = '/api/data';
if($routeParams.ups) {
restURL += '/UPS/' + $routeParams.ups;
} else {
restURL += '/adm';
}
restURL += '/' + $routeParams.historical;
restURL += '/' + $routeParams.datatype;
console.info('Data REST url : ', restURL);
console.info('fields: ', columnSpec);
vm.dataGridOptions = {
name: 'grid',
columns : columnSpec['columns'],
dataSource: {
type: 'json',
transport: {
read: 'http://localhost:57713'+restURL
},
schema: {
model: {
fields : columnSpec['fields']
}
}
},
sortable: true,
filterable: true,
scrollable: true,
reorderable: true,
resizable: true,
selectable: 'single row',
columnMenu: true,
pageable: {
refresh: true,
buttonCount: 5
},
dataBound: onDataBound,
height: '100%'
};
console.info('vm.dataGridOptions : ', vm.dataGridOptions);
console.info('scope after datagridoptionsloaded: ', $scope);
console.info('vm.grid: ', vm.grid);
console.info('scope.vm.grid: ', $scope.vm.grid);
}
function getDataFields() {
return dataservice.getDataFields($routeParams.datatype)
.then(function(data) {
initGridOptions(data);
});
}
function onDataBound(ev) {
console.log('DATABOUND !');
//vm.grid = ev.sender;
var gh = $('.datagrid-grid').find('.k-grid-header');
var gc = $('.datagrid-grid').find('.k-grid-content');
//var rightPaddingHeader = gh.css("padding-right");
gh.hide();
gh.css('padding-right', '0px');
gc.css('overflow-y', 'auto');
gh.show();
//resizeGrid();
//unbind event
vm.grid.unbind('dataBound');
}
function resizeGrid() {
console.log('vm.grid.dataSource: ', vm.grid.dataSource);
// trigger layout readjustment
vm.grid.resize();
// force layout readjustment
vm.grid.resize(true);
//set new pagesize according to content height to avoid inner scrollbars
var gridContentWidget = $('.datagrid-grid .k-grid-content');
console.info('gridContentWidget.height(): ', gridContentWidget.height());
var rowHeight = $('.datagrid-grid .k-grid-content tr').first().height();
var newPageSize = Math.floor(gridContentWidget.height() / rowHeight);
console.info('Setting dataSource to new pageSize: ', newPageSize);
if(newPageSize != vm.grid.dataSource.pageSize())
vm.grid.dataSource.pageSize(newPageSize);
console.info('DataSource pageSize after set: ', vm.grid.dataSource.pageSize);
}
}
And the corresponding html
<div class="datagrid-container">
<h2>{{vm.dataTitle}}</h2>
<div class="datagrid-grid">
<div kendo-grid="vm.grid"
k-options="vm.dataGridOptions"
k-ng-delay="vm.dataGridOptions"
datagrid-resize />
</div>
</div>
Only in the onDataBound function can I get a reference through the event sender.
Any suggestions are highly appreciated.
try this:
vm.gridReference = $('div[kendo-grid]').data('kendoGrid');
I haven't yet figured out a decent way of getting a grid reference without throwing JQuery around but this will do for a quick and dirty.
Currently I am doing this:
$(function () {
// Create the chart
$.getJSON('db_cpu.php', function(data) {
var chart = new Highcharts.StockChart({
chart: {
renderTo: 'container'
},
rangeSelector: {
enabled: false
},
title: {
text: 'Database utilization'
},
series: data
}, function (chart) {
normalState = new Object();
normalState.stroke_width = null;
normalState.stroke = null;
normalState.fill = null;
normalState.padding = null;
//normalState.r = null;
normalState.style = hash('text-decoration', 'underline');
hoverState = new Object();
hoverState = normalState;
pressedState = new Object();
pressedState = normalState;
//pressedState.style = hash('text-decoration', 'none');
chart_1DButton = chart.renderer.button('1D', 52, 10, function () {
$.getJSON('db_memory.php', function (data) {
console.log(data);
chart.series[0].setData(data);
chart.redraw();
});
unselectButtons();
chart_1DButton.setState(2);
}, normalState, hoverState, pressedState);
chart_1DButton.add();
});
function unselectButtons() {
chart_1DButton.setState(0);
}
});
});
when I clicked on the button, my chart does not diplay any data. dp_cpu.php and db_memory.php outputs json formated data that has name and data in it already. For exmaple dp_cpu.php outputs this data:
[{"name":"ServerA","data":[[1375142940000,1.85],[1375143540000,2.07],[1375144140000,1.96],[1375144740000,1.9],[1375145340000,2.06],[1375145940000,2.03],[1375146540000,1.69],[1375147140000,2.6],[1375147740000,2.1],[1375148340000,1.68],[1375148940000,2.03],[1375149540000,1.83],[1375150140000,1.84],[1375150740000,2.01],[1375151340000,1.88],[1375151940000,1.6],[1375152540000,2.02],[1375153140000,1.27],[1375153740000,1.47],[1375154340000,2],[1375154940000,1.97],[1375155540000,2.51],[1375156140000,3.59],[1375156740000,4.06],[1375157340000,4.13],[1375157940000,4.15],[1375158540000,4.19],[1375159140000,4.13],[1375159740000,4.44],[1375160340000,4.14],[1375160940000,4.15],[1375161540000,5.01],[1375162140000,4.13],[1375162740000,5],[1375163340000,4.97],[1375163940000,5.04],[1375164540000,5.09],[1375165140000,5.14],[1375165740000,4.93],[1375166340000,4.43],[1375166940000,5],[1375167540000,4.93],[1375168140000,5.1],[1375168740000,5.05],[1375169340000,5],[1375169940000,5.12],[1375170540000,4.14],[1375171140000,4.13],[1375171740000,4.85],[1375172340000,4.19],[1375172940000,4.13],[1375173540000,4.17],[1375174140000,2.02],[1375174740000,1.62],[1375175340000,1.77],[1375175940000,2.01],[1375176540000,1.86],[1375177140000,1.85],[1375177740000,2.1],[1375178340000,2.03],[1375178940000,1.79],[1375179540000,2.09],[1375180140000,1.95],[1375180740000,1.73],[1375181340000,2.12],[1375181940000,2.07],[1375182540000,1.65],[1375183140000,2.1],[1375183740000,2.03],[1375184340000,1.63],[1375184940000,2.13],[1375185540000,1.93],[1375186140000,1.65],[1375186740000,2.19],[1375187340000,1.98],[1375187940000,1.69],[1375188540000,2.13],[1375189140000,1.93],[1375189740000,1.72],[1375190340000,2.15],[1375190940000,2.07],[1375191540000,1.7],[1375192140000,2.15],[1375192740000,2.03],[1375193340000,1.73],[1375193940000,2.71],[1375194540000,1.96],[1375195140000,1.72],[1375195740000,2.15],[1375196340000,2.15],[1375196940000,1.85],[1375197540000,2.2],[1375198140000,1.93],[1375198740000,1.8],[1375199340000,2.19],[1375199940000,1.98],[1375200540000,1.85],[1375201140000,2.27]]}]
I have some more info. when I do another getJSON as below example, It looks like I need to reset each series. This is really not convenient. I need to be able to read and external file and just show whatever in that file as chart and redraw the chart. Any ideas?
$.getJSON('db_memory.php', function (data) {
console.log(data);
chart.series[0].setData([[1375142940000,100],[1375143540000,2.07],[1375144140000,1.96],[1375144740000,1.9],[1376408000000,90.06]]);
chart.series[1].setData([[1375142940000,10],[1375143540000,20.07],[1375144140000,40.96],[1375144740000,50.9],[1376408000000,50.06]]);
chart.series[2].setData([[1375142940000,10],[1375143540000,20.07],[1375144140000,40.96],[1375144740000,50.9],[1376408000000,20.06]]);
chart.series[3].setData([[1375142940000,10],[1375143540000,20.07],[1375144140000,40.96],[1375144740000,50.9],[1375145340000,10.06]]);
});
I have tried something like this and it is partially working with one problem. After clicking the button, I get the chart but my button disappears:
$(function () {
// Create the chart
$.getJSON('db_pc.php', function(data) {
var chart = new Highcharts.StockChart({
chart: {
renderTo: 'container'
},
rangeSelector: {
enabled: false
},
title: {
text: 'Database utilization'
},
series: data
}, function (chart) {
normalState = new Object();
normalState.stroke_width = null;
normalState.stroke = null;
normalState.fill = null;
normalState.padding = null;
//normalState.r = null;
normalState.style = hash('text-decoration', 'underline');
hoverState = new Object();
hoverState = normalState;
pressedState = new Object();
pressedState = normalState;
//pressedState.style = hash('text-decoration', 'none');
chart_1DButton = chart.renderer.button('1D', 52, 10, function () {
$.getJSON('db_memory.php', function (data1) {
var chart = new Highcharts.StockChart({
chart: {
renderTo: 'container'
},
rangeSelector: {
enabled: false
},
title: {
text: 'Database utilization'
},
series: data1
});
});
unselectButtons();
chart_1DButton.setState(2);
}, normalState, hoverState, pressedState);
chart_1DButton.add();
});
function unselectButtons() {
chart_1DButton.setState(0);
}
});
});
You can use addSeries() then you will not need to reset data, but in case when you use setData, redrawing is called, so redraw() can be skipped.
You only add your button when the chart is created.
The problem is that when you use the following code
, new Highcharts.StockChart..., the chart will load again, so it's will render without your button.
So, you have two options, add a callback that will add the button again, or use serie.setData to change it's data dinamically.
I'd go with the second option.
Other problem is that the response is an array, you have to access it the following way data[0]
Finally will have the following code:
chart_1DButton = chart.renderer.button('1D', 52, 10, function () {
$.getJSON('db_memory.php', function (data) {
// update data
// chart.series[0].setData( data[0].data );
// update series' options
chart.series[0].update(data[0]);
});
unselectButtons();
chart_1DButton.setState(2);
}, normalState, hoverState, pressedState);
after looking at different options, I realized that what I need to do maybe better implemented using html/css type buttons:
https://gist.github.com/kix/3039177
And using jquery click event I can load any kind of chart to the div:
$(document).ready(function(){
$("#prof_d").click(function(){
web_cpu();
});
});