Simple bar chart in jQuery HighCharts and MVC 2 application? - asp.net

I'm trying to create a very simple bar chart using the results of a JSon action method in MVC. I get the actual bar chart, but I don't understand the options and all that well enough, so I'm basically guessing what to do. I used the example on the HighCharts site as an example for how to get data from server code and create a chart. The difference is my chart is simpler than the example. I don't have categories for each user (as in the fruit example), I only have a user and a number of hours logged.
Here's the HighCharts jQuery code:
function getHighChart() {
var actionUrl = '<%= Url.Action("GetChartData") %>';
var customerId = $('#customersId').val();
var startdate = $('.date-pickStart').val();
var enddate = $('.date-pickEnd').val();
var options = {
chart: {
renderTo: 'chart-container',
defaultSeriesType: 'bar'
},
title: {
text: 'Statistik'
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'Timmar'
}
},
series: []
}
jQuery.getJSON(actionUrl,
{ customerId: customerId, startdate: startdate, enddate: enddate }, function (items) {
var series = {
data: []
};
$.each(items, function (itemNo, item) {
series.name = item.Key;
series.data.push(parseFloat(item.Value));
});
options.series.push(series);
var chart = new Highcharts.Chart(options);
});
}
And here's the action method returning JSon:
public JsonResult GetChartData(string customerId, string startdate, string enddate)
{
int intcustomerId = Int32.Parse(customerId);
var emps = from segment in _repository.TimeSegments
where
segment.Date.Date >= DateTime.Parse(startdate) &&
segment.Date.Date <= DateTime.Parse(enddate)
where segment.Customer.Id == intcustomerId
group segment by segment.Employee
into employeeGroup
select new CurrentEmployee
{
Name = employeeGroup.Key.FirstName + " " + employeeGroup.Key.LastName,
CurrentTimeSegments = employeeGroup.ToList(),
CurrentMonthHours = employeeGroup.Sum(ts => ts.Hours)
};
Dictionary<string, double > retVal = new Dictionary<string, double>();
foreach (var currentEmployee in emps)
{
retVal.Add(currentEmployee.Name, currentEmployee.CurrentMonthHours);
}
return Json(retVal.ToArray(), JsonRequestBehavior.AllowGet);
}
I was able to create a pie chart, but now when I want to create a simple bar I'm not able to work out what is what in the jQuery code, so the results I get is a bar where first of all the only user listed in the legend is the last one in the array. Secondly, the tooltip shows x = [The user's name], y = 29, instead of [The user's name]: 29, which I got in the pie chart.
How would I create such a simple bar chart in HighCharts from this JSon?

I use:
//Controller action:
public JsonResult GetData(int id)
{
Dictionary<int, double> data = this.repository.GetData(id);
return Json(data.ToArray(), JsonRequestBehavior.AllowGet);
}
View:
<script>
var chart1;
$(document).ready(function () {
chart1 = new Highcharts.Chart({
chart: {
renderTo: 'chart-container-1',
defaultSeriesType: 'scatter',
events: {
load: requestData
}
},
options...
,
series: [{
name: 'some data',
data: []
}]
});
}
);
function requestData() {
$.ajax({
url: '/ControllerName/GetData?id=#(Model.Id)',
success: function (items) {
$.each(items, function (itemNo, item) {
chart1.series[0].addPoint([item.Key,item.Value], false);
});
chart1.redraw();
},
cache: false
});
}
</script>
<div id="chart-container-1"></div>
So basically I use addPoint('array of x,y',false for not redrawing chart)

Well, I worked it out myself after all... I thought I should post it in case some other HighCharts newbie like me is interested:
Here's the jQuery that worked:
function getHighChart() {
var actionUrl = '<%= Url.Action("GetChartData") %>';
var customerId = $('#customersId').val();
var customerName = $('#customersId option:selected').text();
var startdate = $('.date-pickStart').val();
var enddate = $('.date-pickEnd').val();
//define the options
var options = {
chart: {
renderTo: 'chart-container',
defaultSeriesType: 'column'
},
title: {
text: 'Hours worked for ' + customerName
},
xAxis: {
categories: [customerName]
},
yAxis: {
title: {
text: 'Hours'
}
},
series: []
};
//Calls the JSON action method
jQuery.getJSON(actionUrl,
{ customerId: customerId, startdate: startdate, enddate: enddate }, function (items) {
$.each(items, function (itemNo, item) {
var series = {
data: []
};
series.name = item.Key;
series.data.push(parseFloat(item.Value));
options.series.push(series);
});
var chart = new Highcharts.Chart(options);
});
}
If someone can find faults in this and point me to a better way to do it, I'll gladly hand over the answer credit, otherwise I'll accept my own answer...

Related

Multiseries line chart on highcharts

i have to create a multiseries line chart which is to need view each series with the value of site id and each series with different position .Just now i'am stuck that can only view one series with one query.
And here is the aspx.vb page
Public Class WaterTreament
Public position As Integer
Public value As Double
Public timestamp As String
End Class
<WebMethod()>
Public Shared Function GetWaterTreament() As List(Of WaterTreament)
Using con As New SqlConnection("Data Source=DESKTOP-B8TBSJH1;Initial Catalog=SAY;Integrated Security=SSPI")
Using cmd As New SqlCommand("select position,dtimestamp ,value from telemetry_log_table where siteid ='S1-21' AND dtimestamp BETWEEN '2021-02-02' AND '2021-02-03' and position='62'and value>0 order by dtimestamp asc")
cmd.Connection = con
Dim wtp As New List(Of WaterTreament)()
con.Open()
Using dr As SqlDataReader = cmd.ExecuteReader()
While dr.Read()
wtp.Add(New WaterTreament() With {
.position = Convert.ToInt32(dr("position").ToString()),
.value = Convert.ToDouble(dr("value").ToString()),
.timestamp = dr("dtimestamp").ToString()
})
End While
End Using
con.Close()
Return wtp
End Using
End Using
End Function
Here is the script for highcharts.
$(document).ready(function () {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "WebForm1.aspx/GetWaterTreament",
data: "{}",
dataType: "json",
success: OnSuccess_,
error: OnErrorCall_
});
function OnSuccess_(response) {
debugger;
var aData = response.d;
var arr = [];
var arr2 = [];
var timestamp = [];
$.map(aData, function (item, index) {
var i = [item.value];
var obj = {};
var obj1 = {};
var obj2 = {};
obj.name = item.position;
obj.y = item.value;
obj.y1 = item.timestamp;
obj2.data = item.timestamp;
arr.push(obj.y);
arr2.push(obj.y1);
timestamp.push(obj2.data);
console.log(obj2);
});
var myJsonString = JSON.stringify(arr);
var jsonArray = JSON.parse(JSON.stringify(arr));
//Second Value
var myJsonString1 = JSON.stringify(arr2);
var jsonArray1 = JSON.parse(JSON.stringify(arr2));
//third Value
var myJsonString2 = JSON.stringify(timestamp);
var jsonArray2 = JSON.parse(JSON.stringify(timestamp));
//alert(jsonArray);
DreawChart(jsonArray, jsonArray1, jsonArray2);
}
function OnErrorCall_(response) {
alert("Whoops something went wrong!");
}
});
function DreawChart(seriesData1, seriesData2, seriesData3) {
Highcharts.chart('container', {
// $('#container').highcharts({
title: {
text: 'SITE ID'
},
yAxis: {
title: {
text: 'Values',
}
},
xAxis: {
categories: seriesData3
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
series: {
label: {
connectorAllowed: false
},
}
},
series: [{
type: 'line',
name: 'PH',
data: seriesData1
},
{
type: 'line',
name: 'CHLORINE',
data: seriesData1
},
],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
});
}`
What is your issue here exactly?
You may want to try official Highcharts .NET wrapper: dotnet.highcharts.com.
Sample chart and source code in C# with multiple series: https://dotnet.highcharts.com/Highcharts/Demo/Gallery?demo=LineBasic&theme=default

Fullcalendar io takes time to generate calendar only in IE

Here is the ajax code, am doubting the resource section because it has 645 data's in the array. when i put small amount of static data's it works. Chrome, firefox and safari works fin only in IE it takes time to generate the calendar.
any one can help me on this please.
//get vehicle to calendar
$.ajax({
method: "GET",
url: '#Url.Action("WP", "WeeklyPlan")',
cache: false,
data: {
}, success: function (data) {
resource = []
events = []
var vehiclesWithReserations = data.vehicles;
if (vehiclesWithReserations == null) {
hideLoader();
toastr.warning(data.message);
return;
} else if (vehiclesWithReserations.length == 0) {
hideLoader();
}
var holidayList = data.holidays;
$.each(vehiclesWithReserations, function (i, v) {
resource.push({
id: v.FuhrparkFahrzeugID,
title: v.ModellName,
field: v.LocationId,
zuteilung: v.ZutName,
nvx: v.NVX
});
for (var q = 0; q < v.Reservations.length; q++) {
events.push({
id: v.Reservations[q].ReservationID,
resourceId: v.FuhrparkFahrzeugID,
start: moment(v.Reservations[q].DateFrom).toDate(),
end: moment(v.Reservations[q].DateTo).toDate()
})
}
});
generatecalender(holidayList);
}

jQuery Autocomplete Component

I'm facing a strange issue with autocomplete.
First issue:
based on the tutorial found here, only the first letter of the found items is showing in the list of autocomplete items
Here is an illustration:
My action at debug time
Dummy data returned, always the same regardless of the search pattern just for testing
In the rendered view, this is what happens:
The Javascript for autocomplete of this scenario is as follows:
$("#Email").autocomplete('#Url.Action("FindEmail", "Administration")',
{
dataType: 'json',
parse: function(data) {
var rows = new Array();
for (var i = 0; i < data.length; i++) {
rows[i] = {
data: data[i].Value,
value: data[i].Value,
result: data[i].Value
};
}
return rows;
},
width: 300,
minLength: 3,
highlight: false,
multiple: false
});
Second issue:
I've changed my code to work with a more comfortable Ajax call for me that depends on Model mapping rather than sending a q and limit parameters as in the previous tutorial, and as I've seen in many other tutorials, but the Ajax call isn't firing, not even giving me an error.
My code for this scenario is based on this Stack Overflow Answer
Here is my controller and view code related:
//[HttpPost]
[SpecializedContextFilter]
[Authorize]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public JsonResult FindEmail(RegistrationModel model) //Notice the use of model instead of string q and string limit
{
//Just a dummy implementation
var rez = new List<ValueModel>
{
new ValueModel {Description = "atest1#test.com", Value = "atest1#test.com"},
new ValueModel {Description = "atest2#test.com", Value = "atest2#test.com"},
new ValueModel {Description = "atest3#test.com", Value = "atest3#test.com"},
new ValueModel {Description = "atest4#test.com", Value = "atest4#test.com"}
};
//var retValue = rez.Select(r => new { email = r.Value }).OrderBy(x => x).Take(10);
//return Json(retValue, JsonRequestBehavior.AllowGet);
return Json(rez, JsonRequestBehavior.AllowGet);
}
View JavaScript:
$("#Email").autocomplete({
source: function(request, response) {
$.ajax({
url: '#Url.Action("FindEmail", "Administration")',
type: "POST",
dataType: "json",
data: { email: $("#Email").val(), conferenceId: $("#ConferenceId").val() },
success: function(data) {
response($.map(data, function(item) {
return { label: item.Value, value: item.Value, id: item.Value };
}));
},
select: function(event, ui) {
$("input[type=hidden]").val(ui.item.id);
}
});
}
});
Firefox console view:
I've tried a lot of codes for the second scenario, most of them are Stack Overflow answers, but nothing is happening!
I'm my missing anything ?
Note: jQuery plugins are included, Ajax is already working in the same page, so I'm not sure whats the problem
Thanks for any help.
Here is a full working example, see screen grab.
These are the steps that I had take to get the second example working.
Script-references/Markup/Js
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-ui-1.8.24.min.js"></script>
<input id="ConferenceId" value="1" />
<div class="ui-widget">
<label for="Email">Email: </label>
<input id="Email">
</div>
<script type="text/javascript">
$("#Email").autocomplete({
source: function (request, response) {
$.ajax({
url: '#Url.Action("FindEmail", "Administration")',
type: "POST",
dataType: "json",
data: { email: $("#Email").val(), conferenceId: $("#ConferenceId").val() },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Value, value: item.Value, id: item.Value };
}));
},
select: function (event, ui) {
$("input[type=hidden]").val(ui.item.id);
}
});
}
});
</script>
Models
public class RegistrationModel
{
public string Email { get; set; }
public string ConferenceId { get; set; }
}
public class ValueModel
{
public string Description { get; set; }
public string Value { get; set; }
}
Controller Action
I had to add the [HttpPost] attribute.
[HttpPost]
public JsonResult FindEmail(RegistrationModel model) //Notice the use of model instead of string q and string limit
{
//Just a dummy implementation
var rez = new List<ValueModel>
{
new ValueModel {Description = "atest1#test.com", Value = "atest1#test.com"},
new ValueModel {Description = "atest2#test.com", Value = "atest2#test.com"},
new ValueModel {Description = "atest3#test.com", Value = "atest3#test.com"},
new ValueModel {Description = "atest4#test.com", Value = "atest4#test.com"}
};
return Json(rez, JsonRequestBehavior.AllowGet);
}
Screen grab

Highchart with webservice in ASP.net

What I would like to do is to get a simple string array (of numbers) into the Highchart from a webservice. For some reason, the chart is not even rendered and I cannot get any values through this.
In the Highchart's documentation I've found this example of sending data cross domains:
http://docs.highcharts.com/#cross-domain-data
This is their example (using php):
The serverside php file:
<?php
header("content-type: application/json");
$array = array(7,4,2,8,4,1,9,3,2,16,7,12);
echo $_GET['callback']. '('. json_encode($array) . ')';
?>
The JavaScript calling the callback function using jQuery.
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
type: 'spline'
},
series: [{}]
};
var url = "http://url-to-your-remote-server/jsonp.php?callback=?";
$.getJSON(url, function(data) {
options.series[0].data = data;
var chart = new Highcharts.Chart(options);
});
});
And now this is how my WebService.cs looks like:
public WebService () {
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod(Description = "ID:2")]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetSomeValues() {
string[] values = { "3", "5", "6", "7", "3"};
string[][] jaggedTable = new string[values.Count()][];
int i = 0;
foreach (var value in values)
{
jaggedTable[i] = new string[] { value + "" };
i++;
}
JavaScriptSerializer js = new JavaScriptSerializer();
string strJSON = js.Serialize(jaggedTable);
return strJSON;
}
And the Default.aspx:
<script type="text/javascript">
$(document).ready(function () {
var options = {
chart: {
renderTo: 'container',
type: 'spline'
},
series: [{}]
};
var url = "WebService.asmx/GetSomeValues";
$.getJSON(url, function (data) {
options.series[0].data = data;
var chart = new Highcharts.Chart(options);
});
});
</script>
UPDATE: I've just seen that I'm getting in the console this error:
GET http://localhost:53566/WebService.asmx/GetSomeValues 500 (Internal Server Error)
jquery.min.js:130
c.extend.ajax jquery.min.js:130
c.extend.get jquery.min.js:122
c.extend.getJSON jquery.min.js:122
(anonymous function) highchart.aspx:23
c.extend.ready jquery.min.js:26
Where the anonymous function is:
$.getJSON(url, function (data) {
options.series[0].data = data;
var chart = new Highcharts.Chart(options);
});
What am I doing wrong?

Trying to show a value and description in Jquery UI Autocomplete, not showing data, what am I doing wrong?

I have been all over looking to try and solve my issue. I am thinking it may be on my back end but not sure. I am trying to use autocomplete to fill in a textbox but show in the drop down a description with the value.
My Method for grabbing the Data:
[WebMethod]
public static ArrayList GetQueries(string id)
{
queries q;
var cs = Global.CS;
var con = new SqlConnection(cs);
var da = new SqlDataAdapter(querystring, con);
var dt = new DataTable();
da.Fill(dt);
ArrayList rows = new ArrayList(dt.Rows.Count);
for (int i = 0; i < dt.Rows.Count; i++)
{
var val = dt.Rows[i]["Query_ID"];
var des = dt.Rows[i]["Description"];
q = new queries();
q.label = val.ToString();
q.value = val.ToString() + " -- " + des.ToString();
var json = new JavaScriptSerializer().Serialize(q);
rows.Add(json);
}
return rows;
}
public class queries
{
public string label { get; set; }
public string value { get; set; }
}
It is returning an arraylist.
My JQuery Method to get data and autocomplete.
$("[id$=QueryManager]").change(function () {
var id = $("[id$=QueryManager] :selected").val();
$.ajax({
type: 'POST',
url: 'Upload.aspx/GetQueries',
data: JSON.stringify({ id: id }),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
fillit(data);
},
error: function (ex) {
alert('Request Status: ' + ex.status + '\n\nStatus Text: ' + ex.statusText + '\n\n' + ex.responseText);
}
});
});
function fillit(data) {
$("#QueryTxt").autocomplete({
delay: 0,
minLength: 0,
source: function (data, response) {
response($.map(data, function (item) {
return {
label: item.label,
value: item.value
}
}));
}
});
};
I have tried it with both the serialize and without to no results. When this code runs it shows that autocomplete is working (via the box showing up below) but there is no data in it.
I am not sure what I am doing wrong, any help is appreciated.
What I'm doing below is that on the "Select" event I take the values returned from the query and set the text of the drop down to the description and Id value from the data brought back. Then I set a dummy textbox's value as the description. "colDescName" is just a variable I was using as my textbox id.
$("#" +colDescName).autocomplete({
minLength: 2,
select: function( event, ui )
{
var rowElement=event.target.id;//Drop down Id
setTimeout(function()
{
$("#"+rowElement).val(ui.item.value+':'+ui.item.id)
},100);//need a slight delay here to set the value
$("#TextBoxId").val(ui.item.value);
//ui.item.value is the description in the drop down.
//ui.item.id is the Id value from the drop down
},
source: function (request, response) {
var term = request.term;
if (term in cache) {
response(cache[term]);
return;
}
lastXhr = $.getJSON("Upload.aspx/GetQueries", request, function (data, status, xhr) {
cache[term] = data;
if (xhr === lastXhr) {
response(data);
}
}).error(function () {
console.log("error");
});
}
});
What object is "$("[id$=QueryManager]")" that you have the change method on? Would you need the change event if you can use the above code?
EDIT
OK an easier way is set your textbox "$("#QueryTxt")" to an autocomplete box before executing any change events on your "QueryManager" manager dropdown. Then when a change event does occur in your "QueryManager" , call:
$(this).autocomplete('search', 'your data here');
That will then execute the search function and call the autocomplete's url with your required data

Resources