DotNet HighCharts , Populates a pie with the result of a query - c#

I need to populate a pie with data which are the result of a query (LINQ To SQL)
The problem is i cannot manage to add a foreach inside this code to insert my data instead of the static Firefox,Chrome,IE ect ...
protected void Page_Load(object sender, EventArgs e)
{
//RepeaterVersionsForPie.DataSource = DAaccess.LibDataVersion.LibDataVersion.GetNumberOfCompaniesUsingEachVersions();
//RepeaterVersionsForPie.DataBind();
var test = DAaccess.LibDataVersion.LibDataVersion.GetNumberOfCompaniesUsingEachVersions();
Highcharts chart = new Highcharts("chart")
.InitChart(new Chart { PlotShadow = false })
.SetTitle(new Title { Text = "Browser market shares at a specific website, 2010" })
.SetTooltip(new Tooltip { Formatter = "function() { return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %'; }" })
.SetPlotOptions(new PlotOptions
{
Pie = new PlotOptionsPie
{
AllowPointSelect = true,
Cursor = Cursors.Pointer,
DataLabels = new PlotOptionsPieDataLabels
{
Color = ColorTranslator.FromHtml("#000000"),
ConnectorColor = ColorTranslator.FromHtml("#000000"),
Formatter = "function() { return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %'; }"
},
Point = new PlotOptionsPiePoint
{
Events = new PlotOptionsPiePointEvents
{
Click = "function() { alert (this.category +': '+ this.y); }"
}
}
}
})
.SetSeries(new Series
{
Type = ChartTypes.Pie,
Name = "Browser share",
Data = new Data(new object[]
{
new object[] { "Firefox", 45.0 },
new object[] { "IE", 26.8 },
new DotNet.Highcharts.Options.Point
{
Name = "Chrome",
Y = 12.8,
Sliced = true,
Selected = true
},
new object[] { "Safari", 8.5 },
new object[] { "Opera", 6.2 },
new object[] { "Others", 0.7 }
})
});
ltrChart.Text = chart.ToHtmlString();
}
Actually , i need to be able to insert something like this:
foreach ( var item in test )
{
new object[] { item.name, item.count}
}
But VS doesn't allow me to do such thing
Thanks in advance for your help ...

You could create an extension method for whatever type DAaccess.LibDataVersion.LibDataVersion.GetNumberOfCompaniesUsingEachVersions() returns and have it return the results in the Pie-shaped Series format.
public static class DotNetHighChartsExtensions
{
public static object[] ToPieChartSeries(this WhateverThatTypeIs data)
{
var returnObject = new List<object>();
foreach ( var item in data )
{
returnObject.Add(new object[] { item.name, item.count});
}
return returnObject.ToArray();
}
}
Then in your code where you have your static code, you'd just replace it with:
Data = new Data(test.ToPieChartSeries())
Alternatively, you could have the ToPieChartSeries method return the Data object that is being sought for by the Series object.
While I haven't worked with this DotNet.HighCharts project, I have worked with and built my own HighCharts objects for a couple of MVC projects. On the face of it, it looks like this are ultimately doing the same thing I did: Create a .NET object that could be serialized as JSON and recognized by the HighCharts javascript library.

SetSeries(new Series {
Type = ChartTypes.Pie,
Data = new Data(test.Select(d => new { Name = d.name, Y = d.count }).ToArray())
})

Related

How to send a response card using AWS Lambda in C#

Hi I am developing a chatbot on amazon lex and I want to send a response card using the lambda function but on using response card function inside the close response format it gives the error of null exception. Can anyone tell the solution to it?
PS I am using FlowerOrder blueprint created by Nikki.
if (slots[greet] != null)
{
var validateGreet = ValidateUserGreeting(slots[greet]);
if (validateGreet.IsValid)
{
return Close(sessionAttributes,
"Fulfilled",
new LexResponse.LexMessage
{
ContentType = "PlainText",
Content = String.Format("Hello Kindly choose one option")
},
new LexResponse.LexResponseCard
{
Version = 1,
ContentType = "application/vnd.amazonaws.card.generic",
GenericAttachments =
{
new LexResponse.LexGenericAttachments
{
Buttons =
{
new LexResponse.LexButton
{
Text = "Shop Now",
Value = "Shop Now"
}
},
AttachmentLinkUrl = null,
Title = "Shopping",
SubTitle = "Sub Shopping",
ImageUrl = null
}
}
}
);
}
Exception:-
2020-06-09 17:31:20: Object reference not set to an instance of an object.: NullReferenceException at EVS_Test_Abbar_Lambda_Function.OrderWatchIntentProcessorTest.Process(LexEvent lexEvent, ILambdaContext context) in D:\AWS Project\Abbrar Projects\EVS_Test_Abbar_Lambda_Function\EVS_Test_Abbar_Lambda_Function\OrderWatchIntentProcessorTest.cs:line 52 at EVS_Test_Abbar_Lambda_Function.Function.FunctionHandler(LexEvent lexEvent, ILambdaContext context) in D:\AWS Project\Abbrar Projects\EVS_Test_Abbar_Lambda_Function\EVS_Test_Abbar_Lambda_Function\Function.cs:line 43
at lambda_method(Closure , Stream , Stream , LambdaContextInternal )
Here is the solution to it since if you look at the structure of JSON it contains many models and lists and each has to be handled separately.
LexResponse.LexResponseCard lexResponseCard = new LexResponse.LexResponseCard();
List<LexResponse.LexGenericAttachments> ListlexGenericAttachments = new List<LexResponse.LexGenericAttachments>();
LexResponse.LexGenericAttachments lexGenericAttachments = new LexResponse.LexGenericAttachments();
List<LexResponse.LexButton> ListlexButton = new List<LexResponse.LexButton>();
LexResponse.LexButton lexButton = new LexResponse.LexButton();
lexButton.Text = "Yes Now";
lexButton.Value = "Yes";
ListlexButton.Add(lexButton);
lexGenericAttachments.AttachmentLinkUrl = "Link";
//lexGenericAttachments.AttachmentLinkUrl = null;
lexGenericAttachments.Title = "Shopping";
lexGenericAttachments.SubTitle = "Sub Shopping";
lexGenericAttachments.ImageUrl = "Link";
//lexGenericAttachments.ImageUrl = null;
lexGenericAttachments.Buttons = ListlexButton;
ListlexGenericAttachments.Add(lexGenericAttachments);
lexResponseCard.Version = 0;
lexResponseCard.ContentType = "application/vnd.amazonaws.card.generic";
lexResponseCard.GenericAttachments = ListlexGenericAttachments;
return Close(sessionAttributes,
"Fulfilled",
new LexResponse.LexMessage
{
ContentType = "PlainText",
Content = String.Format("Hello Kindly choose one option")
},
lexResponseCard
);
It may be your capitalization of key names. For example you have ContentType but it should be contentType as camelcase beginning with lowercase letters.
return Close(sessionAttributes,
"Fulfilled",
new LexResponse.LexMessage
{
contentType = "PlainText",
content = String.Format("Hello Kindly choose one option")
},
new LexResponse.LexResponseCard
{
version = 1,
contentType = "application/vnd.amazonaws.card.generic",
GenericAttachments =
{
new LexResponse.LexGenericAttachments
{
Buttons =
{
new LexResponse.LexButton
{
text = "Shop Now",
value = "Shop Now"
}
},
attachmentLinkUrl = null,
title = "Shopping",
subTitle = "Sub Shopping",
imageUrl = null
}
}
}
);
try just one Lex Response Card .
return Close(sessionAttributes,
"Fulfilled"
new LexResponse.LexResponseCard
{
version = 1,
contentType = "application/vnd.amazonaws.card.generic",
GenericAttachments =
{
new LexResponse.LexGenericAttachments
{
Buttons =
{
new LexResponse.LexButton
{
text = "Shop Now",
value = "Shop Now"
}
},
attachmentLinkUrl = null,
title = "Shopping",
subTitle = "Sub Shopping",
imageUrl = null
}
}
}
);

Get list of files in a specific Netsuite folder

I'm trying to retrieve a list of files in a specific folder in the file cabinet. When I execute the search, I'm given all files in the specified folder and all folders underneath that folder. I've tried with FileSearchBasic and FileSearchAdvanced, both give me the same results.
Is there a way to get only files in the specified folder id?
var search = new FileSearchBasic
{
folder = new SearchMultiSelectField
{
#operator = SearchMultiSelectFieldOperator.anyOf,
#operatorSpecified = true,
searchValue = new[] { new RecordRef
{
internalId = "1234"
}}
}
};
var result = ns.search(search);
if (result.status.isSuccess)
{
foreach (var record in result.recordList)
{
if (record is File file)
{
Console.WriteLine($"{file.folder.internalId} - {file.name}");
}
}
}
This code results in the following list where folder 1236 is a sub folder of folder 1234
1234 - lodash.js
1234 - dt.timer.js
1234 - dt.search.js
1234 - dt.customer.js
1234 - dt.safeExecute.js
1236 - processRawLocationData.js
I was able to get only the files in the specified folder by performing a FolderSearchAdvanced() and using a file join rather than a FileSearchAdvanced(). It sort of makes sense since you have to do it this way in SuiteScript as well.
Still open to alternative methods.
var search = new FolderSearchAdvanced()
{
criteria = new FolderSearch()
{
basic = new FolderSearchBasic()
{
internalId = new SearchMultiSelectField()
{
#operator = SearchMultiSelectFieldOperator.anyOf,
searchValue = new[] { searchValue },
operatorSpecified = true
},
}
},
columns = new FolderSearchRow
{
basic = new FolderSearchRowBasic()
{
internalId = new[] { new SearchColumnSelectField() },
name = new [] { new SearchColumnStringField() }
},
fileJoin = new FileSearchRowBasic()
{
internalId = new[] { new SearchColumnSelectField() },
name = new[] { new SearchColumnStringField() },
modified = new[] { new SearchColumnDateField() },
documentSize = new[] { new SearchColumnLongField() }
}
}
};
var results = ns.search(search);
if (results.status.isSuccess)
{
foreach (var result in results.searchRowList)
{
if (result is FolderSearchRow row)
{
var fileId = row.fileJoin.internalId[0].searchValue.internalId;
var fileName = row.fileJoin.name[0].searchValue;
Console.WriteLine($"{fileId} - {fileName}");
}
}
}

looping through a C# collections

i have a class and method
public class Datas
{
public string Name { get; set; }
public int Value { get; set; }
}
public void Funnel()
{
string commandText = "select sc.stagename, count(cs.stages_id) as StageCount from currentstage cs inner join stagesconfig sc on cs.stages_id = sc.stages_id group by cs.stages_id,sc.stagename";
string constrings = WebConfigurationManager.ConnectionStrings["Data"].ToString();
SqlConnection myConn = new SqlConnection(constrings);
SqlCommand myComm = new SqlCommand(commandText, myConn);
myConn.Open();
List<Datas> fruitinfo = new List<Datas>();
SqlDataReader reader = myComm.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
fruitinfo.Add(new Datas
{
Name = reader.GetValue(0).ToString(),
Value = Convert.ToInt32(reader.GetValue(1))
});
}
}
how do you loop through fruitinfo list saving it in form of an array.the array must be similar to this form.intended to replace the items in Data parenthesis with fruitinfo looped list
Data = new Data(new object[]
{
new object[] { "Website visits", 10000 },
new object[] { "Downloads", 5000 },
new object[] { "Requested price list", 2000 },
new object[] { "Invoice sent", 1000 },
new object[] { "Finalized", 500 }
}),
var myArray = fruitinfo.Select(x => new object[] { x.Name, x.Value }).ToArray();
And the use it with your Data-object.
Data = new Data(myArray);
var myArray = fruitinfo.Select(d => new object[] { d.Name, d.Value }).ToArray();
I am not too sure why you need to produce an array of anonymous objects, but you can use a dictionary.
private static void Funnel()
{
var datas = new List<Datas>
{
new Datas { Name = "Website visits", Value = 10000 },
new Datas { Name = "Downloads", Value = 5000 },
new Datas { Name = "Requested price list", Value = 2000 },
new Datas { Name = "Invoice sent", Value = 1000 },
new Datas { Name = "Finalized", Value = 500 }
};
var data = datas.ToDictionary(datas1 => datas1.Name, datas1 => datas1.Value);
foreach (var item in data)
{
Console.WriteLine(string.Format("{0}, {1}",item.Key, item.Value));
}
var arry = data.ToArray();
foreach (var item in arry)
{
Console.WriteLine(string.Format("{0}, {1}", item.Key, item.Value));
}
}

passing json values to highcharts from .net code behind

var Javascriptxvalue= $.parseJSON($("#hdnXaxis").val());
var Javascriptyvalue= $.parseJSON($("#hdnYaxis").val());
$(document).ready(DrawMyGraph1);
function DrawMyGraph1() {
chart = new Highcharts.Chart(
{
chart: {
type: 'column',
renderTo: 'container3',
defaultSeriesType: 'area'
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
categories: Javascriptxvalue,
labels: {
enabled: false
}
},
yAxis: {
title: {
text: 'No of Patients'
}
},
credits: {
enabled: false
},
tooltip: {
formatter: function () {
return this.series.name + ' - ' + Highcharts.numberFormat(this.y, 0);
}
},
series: Javascriptyvalue
});
}
c# code
void FastMovingStocksBarChart(string date1, string date2, string selperiod, string sql)
{
DataSet dschart = new DataSet();
dschart = _obj_MIS.DoctorpatientreportChart(date1, date2, selperiod,sql);
List lstXaxis = new List();
List lstcolors = new List();
lstcolors.Add("#3366DD");
//lstcolors.Add("#FFEE22");
//lstcolors.Add("#33BBCC");
lstcolors.Add("#CC0022");
//lstcolors.Add("#FF0000");
lstcolors.Add("#339900");
lstcolors.Add("#FF7700");
lstcolors.Add("#33BBCC");
lstcolors.Add("#99EEEE");
lstcolors.Add("#6699FF");
lstcolors.Add("#9966BB");
lstcolors.Add("#99BB66");
lstcolors.Add("#FF7700");
lstcolors.Add("#FFEE22");
lstcolors.Add("#FFCBB9");
lstcolors.Add("EAEC93");
lstcolors.Add("D7FBE6");
lstcolors.Add("FFCACA");
for (int i = 0; i < dschart.Tables[0].Rows.Count; i++)
{
lstXaxis.Add(dschart.Tables[0].Rows[i]["Doctor Name"].ToString());
}
List<ChartEx> lstseries = new List<ChartEx>();
int count = 0;
for (int i = 0; i < dschart.Tables[0].Rows.Count; i++)
{
ChartEx oEx = new ChartEx();
oEx.name = dschart.Tables[0].Rows[i]["Doctor Name"].ToString();
//oEx.data.Add(Convert.ToInt32(dschart.Tables[0].Rows[i]["Patients"]));
oEx.data = new List<int>() { Convert.ToInt32(dschart.Tables[0].Rows[i]["Patients"]) };
oEx.color = lstcolors[count];
lstseries.Add(oEx);
count++;
if (count >= lstcolors.Count)
count = 0;
}
//Convert X axis data to JSON
JavaScriptSerializer oSerializer1 = new JavaScriptSerializer();
hdnXaxis.Value = oSerializer1.Serialize(lstXaxis);
//Convert Y axis data to JSON
JavaScriptSerializer oSerializer2 = new JavaScriptSerializer();
hdnYaxis.Value = oSerializer1.Serialize(lstseries);
}
I am not getting the values for "Javascriptxvalue" and "Javascriptyvalue" inside the chart function
can anyone help me
Regards
Prabhu
Presumably, 'hdnXaxis' is the id of a HiddenFieldControl server control? Perhaps the id is not what you think
var Javascriptxvalue= $.parseJSON($("#"+ <%= hdnXaxis.ClientId %>).val());
Instead of passing strings via an input, you could use server tags to directly inject the values into the page. Like this:
<%= "alert('" + MyPublicProperty + "')" %>
This should alert you to the value of the property defined in your code behind. You could then set it to a js variable like so:
<%= "var Javascriptxvalue = '" + xProperty + "';" %>
You will need to run this bit of code directly in an aspx/ascx/razor page to set the variables though, I think it's better than relying on a control with a particular id though.

Use of DotNet HighCharts dll to make charts in code behind

I just discovered the DotNetHighCharts dll to make charts:
http://dotnethighcharts.codeplex.com/
I added the dll to my project and put a sample code to get a pie in my Page_Load event ( i'm not working with MVC right now, so i just took what was in the controller of the demo )
protected void Page_Load(object sender, EventArgs e)
{
Highcharts chart = new Highcharts("chart")
.InitChart(new Chart { PlotShadow = false })
.SetTitle(new Title { Text = "Browser market shares at a specific website, 2010" })
.SetTooltip(new Tooltip { Formatter = "function() { return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %'; }" })
.SetPlotOptions(new PlotOptions
{
Pie = new PlotOptionsPie
{
AllowPointSelect = true,
Cursor = Cursors.Pointer,
DataLabels = new PlotOptionsPieDataLabels
{
Color = ColorTranslator.FromHtml("#000000"),
ConnectorColor = ColorTranslator.FromHtml("#000000"),
Formatter = "function() { return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %'; }"
}
}
})
.SetSeries(new Series
{
Type = ChartTypes.Pie,
Name = "Browser share",
Data = new Data(new object[]
{
new object[] { "Firefox", 45.0 },
new object[] { "IE", 26.8 },
new DotNet.Highcharts.Options.Point
{
Name = "Chrome",
Y = 12.8,
Sliced = true,
Selected = true
},
new object[] { "Safari", 8.5 },
new object[] { "Opera", 6.2 },
new object[] { "Others", 0.7 }
})
});
}
}
}
the problem is that northing appears in my page with this
Is there anything to add ?
Thanks in advance
I'm not familiar with the library but all this code appears to be doing is creating an object in the code behind. You will need to do something to cause this to render in to the page.
Looking at their example code behind code there is a line
ltrChart.Text = chart.ToHtmlString();
This is the bit you are missing. You need to call ToHtmlString() on your chart object and assign this string to a literal or placeholder in the page.
To create the literal just add this code somewhere on the page....
<asp:Literal ID="ltrChart" runat="server"></asp:Literal>
...and your chart should appear there.
Based on their example you need to send the HTML to the client side with the line
Response.Write(result);
It works to me, though it prints it at the top of the screen and I wish I could set the position for it.

Categories