I'm trying to reorder my chart after inserting some data from a json file. I've tried to sort the data array without success.
There's any plugin or easy way to reorder the stacks and show the tallest first?
Heres my code:
var ChartHelper = {
data: [],
labels: [],
datarray: [],
init: function() {
this.setupChart();
this.bindEvents();
},
bindEvents: function() {
// Load the Visualization API and the corechart package.
google.charts.load('current', {'packages':['bar']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(ChartHelper.drawChart);
if (document.addEventListener) {
window.addEventListener('resize', ChartHelper.resizeChart);
}
else if (document.attachEvent) {
window.attachEvent('onresize', ChartHelper.resizeChart);
}
else {
window.resize = ChartHelper.resizeChart;
}
},
drawChart: function() {
// Create the data table.
var data = new google.visualization.DataTable();
ChartHelper.data = google.visualization.arrayToDataTable(ChartHelper.datarray);
// Set chart options
ChartHelper.options = {
title: 'Usuários influentes',
width: '100%',
height: 900,
chartArea: {width: '85%', top: 50,left:10},
stacked: true
};
// Instantiate and draw our chart, passing in some options.
ChartHelper.chart = new google.charts.Bar(document.getElementById('myChart'));
ChartHelper.chart.draw(ChartHelper.data, google.charts.Bar.convertOptions(ChartHelper.options));
},
getBrands: function() {
$.ajax({
url: "./data/brands.json",
dataType: 'json',
async: false,
success: function(data) {
ChartHelper.brands = [];
$.each( data, function( key, val ) {
if(ChartHelper.labels.indexOf(val.name) === -1){
ChartHelper.labels.push( val.name );
ChartHelper.brands.push(val);
}
});
}
});
// push brands
Object.keys(ChartHelper.brands).filter(function(index) {
ChartHelper.datarray.push([ChartHelper.brands[index].name]);
});
},
getUsers: function() {
$.ajax({
url: "./data/users.json",
dataType: 'json',
async: false,
success: function(data) {
ChartHelper.users = [];
$.each( data, function( key, val ) {
ChartHelper.users.push(val);
ChartHelper.setupDatasets(val,key);
});
}
});
// push users
var users = [];
Object.keys(ChartHelper.users).filter(function(index) {
users.push(ChartHelper.users[index].login.username);
});
users.unshift('Marcas');
ChartHelper.datarray.unshift(users);
},
getInteractions: function() {
$.ajax({
url: "./data/interactions.json",
dataType: 'json',
async: false,
success: function(data) {
ChartHelper.interactions = [];
$.each( data, function( key, val ) {
ChartHelper.interactions.push(val);
});
}
});
},
setupDatasets: function(user,i) {
var totalInte;
var userdata = [];
var j = i+1;
$.each(ChartHelper.labels, function( key, val ){
totalInte = 0;
$.each(ChartHelper.interactions, function( key2, val2 ){
if(user.id == val2.user) {
Object.keys(ChartHelper.brands).filter(function(index) {
if(ChartHelper.brands[index].id == val2.brand && ChartHelper.brands[index].name == val)
totalInte++;
});
}
});
if(totalInte > 0)
userdata = totalInte;
else
userdata = '';
ChartHelper.datarray[key][j] = totalInte;
});
},
setupChart: function() {
ChartHelper.datarray = [];
this.getBrands();
this.getInteractions();
this.getUsers();
},
getRandColor: function(){
var brightness = 4;
var rgb = [Math.random() * 256, Math.random() * 256, Math.random() * 256];
var mix = [brightness*51, brightness*51, brightness*51]; //51 => 255/5
var mixedrgb = [rgb[0] + mix[0], rgb[1] + mix[1], rgb[2] + mix[2]].map(function(x){ return Math.round(x/2.0)})
return "rgb(" + mixedrgb.join(",") + ")";
},
resizeChart: function() {
ChartHelper.chart.draw(ChartHelper.data, ChartHelper.options);
}
};
$(document).ready(function() {
// ready
ChartHelper.init();
});
Tried many options for different charts and I'm still reading the docs to find a solution, please help me!
Here's a demo:
DEMO
sort the data table before drawing the chart...
// sort data table on value column
ChartHelper.data.sort([{column: 1}]);
ChartHelper.chart.draw(ChartHelper.data, google.charts.Bar.convertOptions(ChartHelper.options));
Related
Can anyone tell me why this will not update the data object in the AJAX? If I have multiple features in the geojson, it tends to only save one of the features records when looping through all the geojson features. So if geojsonFeatures has 3 records, 3 records will be pushed into ajaxDeferred but the data will be the same for all three records.
data: {
id: updatedLayerGeojsonId,
table: updatedLayerGeojsonTable,
geom: updatedLayerGeojsonGeometry
}
var geojsonFeatures = geojson.features;
var ajaxDeferred = [];
for(var a = 0; a < geojsonFeatures.length; a++){
updatedLayerGeojson = geojsonFeatures[a].geometry;
updatedLayerGeojson.crs = {
"type": "name",
"properties": {
"name": "epsg:4326"
}
};
updatedLayerGeojsonGeometry = JSON.stringify(updatedLayerGeojson);
updatedLayerGeojsonId = geojsonFeatures[a].properties.gid;
updatedLayerGeojsonTable = geojsonFeatures[a].properties.layer_table;
ajaxDeferred.push(
$.ajax({
url: window.location.origin + '/csrfToken',
success: function(response) {
$.ajax({
url: '/maplayers/saveEditedLayerRecord',
type:"post",
data: {
id: updatedLayerGeojsonId,
table: updatedLayerGeojsonTable,
geom: updatedLayerGeojsonGeometry
},
beforeSend: function(xhr, settings){
xhr.setRequestHeader('X-CSRF-Token', response._csrf);
},
success: function(data){
if(data){
numberOfEditedLayersCompleted++;
if(numberOfEditedLayers == numberOfEditedLayersCompleted){
removeLayers();
editableLayers.clearLayers();
editedLayer = false;
numberOfEditedLayers = 0;
numberOfEditedLayersCompleted = 0;
}
}
},
cache: false
});
}
})
);
I'm using the materialize autocomplete plugin to create multiple tags input with autocomplete. Plugin works fine, yet only with data passed as an array defined in advance. If data is passed from ajax call, plugin does not show dropdown with options as if there were no results. There are results in fact, they are cached (using cache option) and are shown as dropdown only after re-typing search phrase.
To sum up, autocomplete plugin does not wait for the ajax to complete its request and deliver data and that is why dropdown is not shown at first try.
Is there any way to get this plugin to show suggestions in dropdown once these are retrieved trough ajax call?
Plugin initialization:
autocomplete = $('#multipleInput').materialize_autocomplete({
cacheable: true,
throttling: true,
multiple: {
enable: true,
maxSize : 5
},
appender: {
el: '.ac-users'
},
dropdown: {
el: '#multipleDropdown'
},
getData: function (value, callback) {
callback(value,getAjaxDropdowValuesAutocomplete(value));
}
});
Function to get values from DB:
function getAjaxDropdowValuesAutocomplete(value){
var returnArray = [],
dataArray,
innerObject = {},
postParamsObj = {"search" : value};
$.ajax({
type: "POST",
url: '/search-elements',
data: postParamsObj,
success: function( msg ) {
dataArray = msg['data'];
for(var i = 0;i < dataArray.length; i++){
innerObject = {};
innerObject["id"] = dataArray[i][0];
innerObject["text"] = dataArray[i][1] + " " + dataArray[i][2];
returnArray.push(innerObject);
}
// returnArray format [{ 'id': '1', 'text': 'Johnny Bravo' }]
},
error : function(msg){
}
});
return returnArray;
}
You could try initializing the autocomplete during the success callback of the ajax request instead of the other way around. That way you're sure to have the data before it tries to start binding the autocomplete events. e.g.
function getAjaxDropdowValuesAutocomplete(value) {
var returnArray = [],
dataArray,
innerObject = {},
postParamsObj = {"search": value};
$.ajax({
type: "POST",
url: '/search-elements',
data: postParamsObj,
success: function (msg) {
dataArray = msg['data'];
for (var i = 0; i < dataArray.length; i++) {
innerObject = {};
innerObject["id"] = dataArray[i][0];
innerObject["text"] = dataArray[i][1] + " " + dataArray[i][2];
returnArray.push(innerObject);
}
// returnArray format [{ 'id': '1', 'text': 'Johnny Bravo' }]
autocomplete = $('#multipleInput').materialize_autocomplete({
cacheable: true,
throttling: true,
multiple: {
enable: true,
maxSize: 5
},
appender: {
el: '.ac-users'
},
dropdown: {
el: '#multipleDropdown'
},
getData: returnArray
});
},
error: function (msg) {
}
});
return returnArray;
}
I have a select2 list which having huge data. So, basically on scrolling we're populating data through pagination( adding 10 records on each scroll). In Select2, version 3.4.8, its working fine and able to load data through asp.net web method. Below is the code
$("#ddlEntity").select2({
width: 200,
dropdownAutoWidth: true,
loadMorePadding: 200
initSelection: function (element, callback) {
var data = { id: ID, text: Value };
callback(data);
},
query: timedelayfunction(function (query) {
var res = AjaxRequest( URL , 'GetOnDemandWebMethod', { searchFilter : query.term, pageCounter: query.page, uid:$('#uid').val() });
var data = { more: (res.d[0] != undefined ? res.d[0].MoreStatus : false), results: [] }, i;
for (i = 0; i < res.d.length; i++) {
data.results.push({ id: res.d[i].ID, text: res.d[i].Value });
}
query.callback(data);
}, 200)
});
After moving Select2, version 4.0.3, same functionality is breaking. Can anyone help on this.
Thanks in Advance.
Finally, I've resolved it at my end and after tweaking web method response as JSON serialised array string and select2 v4 with data portion as json string worked for me.
for others it would be simple as like below code
$('#ddlEntity').select2({
width: 200,
allowClear: true,
placeholder: {
id: -1,
text: "Select any."
},
ajax: {
type:"POST",
url: '',
contentType: "application/json; charset=utf-8",
async: false,
dataType: 'json',
data: function (params) {
return "{'searchFilter':'" + (params.term || "") + "','searchPage':'" + (params.page || 1) + "'}";
},
processResults: function (res, params) {
var jsonData = JSON.parse(res.d);
params.page = params.page || 1;
var data = { more: (jsonData[0] != undefined ? jsonData[0].MoreStatus : false), results: [] }, i;
for (i = 0; i < jsonData.length; i++) {
data.results.push({ id: jsonData[i].ID, text: jsonData[i].Value });
}
return {
results: data.results,
pagination: {
more: data.more
}
};
}
}
});
I know this has been asked before but I really can't get my head round this. I have tried everything to get rid of this error but it just won't go away. Here is my code and I am given the following error message when generating my chart: All series on a given axis must be of the same data type.
C#
public static object[][] GetBarData()
{
string strSQL = #"SELECT [Expected Month] , ISNULL([0],0) AS [0],
ISNULL([0.10],0) AS [10],
ISNULL([0.25],0) AS [25],
ISNULL([0.50],0) AS [50],
ISNULL([0.75],0) AS [75],
ISNULL([0.90],0) AS [90],
ISNULL([1.00],0) AS [100]
FROM (
SELECT MONTH(D.expected_date) AS [Expected Month], P.probability AS [Category], COUNT(O.id) AS [Customers]
FROM opportunity_probability P
INNER JOIN opportunity_detail D ON D.probability_id = P.id
INNER JOIN opportunities O ON D.opportunity_id = O.id
INNER JOIN (SELECT opportunity_id FROM opportunity_detail GROUP BY opportunity_id) T ON T.opportunity_id = O.customer_id
GROUP BY P.probability, MONTH(D.expected_date)
) ST
PIVOT (
SUM([Customers])
FOR [Category] IN ([0],[0.10],[0.25],[0.50],[0.75],[0.90],[1.00])
) PIV";
DataTable dt = MIDB.DataAccess.LoadDTFromSQL(System.Configuration.ConfigurationManager.ConnectionStrings["MIDB"].ConnectionString, strSQL);
return dtToArray(dt, new Object[9] { "Period", "0%", "10%", "25%", "50%", "75%", "90%", "100%", "Customers" });
}
public static object[][] dtToArray(DataTable dt, Object[] header)
{
Object[][] obj = new Object[dt.Rows.Count + 1][];
obj[0] = header;
int k = header.Length;
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow row = dt.Rows[i];
obj[i + 1] = new object[k];
for (int j = 0; j < dt.Columns.Count; j++)
{
if (dt.Columns[j].DataType == Type.GetType("System.Decimal"))
{
obj[i + 1][j] = Convert.ToDouble(row[j]);
}
else if (dt.Columns[j].DataType == Type.GetType("System.Int32"))
{
obj[i + 1][j] = Convert.ToInt32(row[j]);
}
else if (dt.Columns[j].DataType == Type.GetType("System.DateTime"))
{
obj[i + 1][j] = GenericMethods.jsMilliseconds(Convert.ToDateTime(row[j]));
}
else
{
obj[i + 1][j] = row[j].ToString();
}
}
}
return obj;
}
google.load("visualization", "1.1", {
packages: ["bar", "corechart"]
});
ASPX Page
$(document).ready(function () {
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: 'PipelineChart.aspx/GetChartData',
success:
function (response) {
genCharts(response.d);
}
});
})
$(window).resize(function () {
getDataPost();
});
function getDataPost() {
$(document).ready(function () {
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: 'PipelineChart.aspx/GetChartData',
success:
function (response) {
genCharts(response.d);
}
});
})
}
function genCharts(obj) {
drawBar(obj[0]);
}
function drawBar(obj) {
var data = google.visualization.arrayToDataTable(obj);
var options = {
width: '100%',
height: '600',
isStacked: true
}
var chart = new google.visualization.BarChart(document.getElementById('Bar'));
chart.draw(data, options)
}
google.setOnLoadCallback(drawBar);
I have an $.ajax function on my page to populate a facility dropdownlist based on a service type selection. If I change my service type selection back and forth between two options, randomly the values in the facility dropdownlist will remain the same and not change. Is there a way to prevent this? Am I doing something wrong?
Javascript
function hydrateFacilityDropDownList() {
var hiddenserviceTypeID = document.getElementById('<%=serviceTypeID.ClientID%>');
var clientContractID = document.getElementById('<%=clientContractID.ClientID%>').value;
var serviceDate = document.getElementById('<%=selectedServiceDate.ClientID%>').value;
var tableName = "resultTable";
$.ajax({
type: 'POST',
beforeSend: function () {
},
url: '<%= ResolveUrl("AddEditService.aspx/HydrateFacilityDropDownList") %>',
data: JSON.stringify({ serviceTypeID: TryParseInt(hiddenserviceTypeID.value, 0), clientContractID: TryParseInt(clientContractID, 0), serviceDate: serviceDate, tableName: tableName }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
a(data);
}
,error: function () {
alert('HydrateFacilityDropDownList error');
}
, complete: function () {
}
});
}
function a(data) {
var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
var tableName = "resultTable";
if (facilityDropDownList.value != "") {
selectedFacilityID = facilityDropDownList.value;
}
$(facilityDropDownList).empty();
$(facilityDropDownList).prepend($('<option />', { value: "", text: "", selected: "selected" }));
$(data.d).find(tableName).each(function () {
var OptionValue = $(this).find('OptionValue').text();
var OptionText = $(this).find('OptionText').text();
var option = $("<option>" + OptionText + "</option>");
option.attr("value", OptionValue);
$(facilityDropDownList).append(option);
});
if ($(facilityDropDownList)[0].options.length > 1) {
if ($(facilityDropDownList)[0].options[1].text == "In Home") {
$(facilityDropDownList)[0].selectedIndex = 1;
}
}
if (TryParseInt(selectedFacilityID, 0) > 0) {
$(facilityDropDownList)[0].value = selectedFacilityID;
}
facilityDropDownList_OnChange();
}
Code Behind
[WebMethod]
public static string HydrateFacilityDropDownList(int serviceTypeID, int clientContractID, DateTime serviceDate, string tableName)
{
List<PackageAndServiceItemContent> svcItems = ServiceItemContents;
List<Facility> facilities = Facility.GetAllFacilities().ToList();
if (svcItems != null)
{
// Filter results
if (svcItems.Any(si => si.RequireFacilitySelection))
{
facilities = facilities.Where(f => f.FacilityTypeID > 0).ToList();
}
else
{
facilities = facilities.Where(f => f.FacilityTypeID == 0).ToList();
}
if (serviceTypeID == 0)
{
facilities.Clear();
}
}
return ConvertToXMLForDropDownList(tableName, facilities);
}
public static string ConvertToXMLForDropDownList<T>(string tableName, T genList)
{
// Create dummy table
DataTable dt = new DataTable(tableName);
dt.Columns.Add("OptionValue");
dt.Columns.Add("OptionText");
// Hydrate dummy table with filtered results
if (genList is List<Facility>)
{
foreach (Facility facility in genList as List<Facility>)
{
dt.Rows.Add(Convert.ToString(facility.ID), facility.FacilityName);
}
}
if (genList is List<EmployeeIDAndName>)
{
foreach (EmployeeIDAndName employeeIdAndName in genList as List<EmployeeIDAndName>)
{
dt.Rows.Add(Convert.ToString(employeeIdAndName.EmployeeID), employeeIdAndName.EmployeeName);
}
}
// Convert results to string to be parsed in jquery
string result;
using (StringWriter sw = new StringWriter())
{
dt.WriteXml(sw);
result = sw.ToString();
}
return result;
}
$get return XHR object not the return value of the success call and $get function isn't synchronous so you should wait for success and check data returned from the call
these two lines do something different than what you expect
var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
change to something similar to this
var facilityDropDownList;
$.ajax({
url: '<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>',
type: 'get',
dataType: 'html',
async: false,
success: function(data) {
facilityDropDownList= data;
}
});