I want to sent a line chart in the body of the E-mail using ASP.Net and C#. I have written a code to show the chart in a div tag. I want to sent the line chart in mail. How to do this?
My Code: jQuery
var chartData;
google.load("visualization", "1", { packages: ["corechart"] });
function Chart() {
$.ajax({
url: "HHT_Tracking.aspx/GetData",
data: "",
dataType: "json",
type: "POST",
contentType: "application/json; chartset=utf-8",
success: function (data) {
chartData = data.d;
},
error: function () {
alert("Error loading data! Please try again.");
}
}).done(function () {
//google.setOnLoadCallback(drawChart);
drawChart();
});
};
function drawChart() {
var data = google.visualization.arrayToDataTable(chartData);
var options = {
title: "Server Monitoring Date Wise",
pointSize: 5,
vAxis: { slantedText: true, slantedTextAngle: 90, title: 'MINUTES' }
};
var lineChart = new google.visualization.LineChart(document.getElementById('chartDiv'));
lineChart.draw(data, options);
}
Source Code:
<tr>
<td>
<div id="chartDiv" style="width: 100%; height: 700px"></div>
</td>
</tr>
Assuming that you are using System.Web.UI.DataVisualization for your charting, the chart class has a method SaveImage that you can use for saving that chart as a graphic (e.g. png) into a memory stream. Use that stream to spit out data-uri which you can then use in your HTML formatted email body.
For example:
Charting.Chart myChart = new Charting.Chart();
System.IO.MemoryStream imgStream = new System.IO.MemoryStream();
myChart.SaveImage(imgStream, Charting.ChartImageFormat.Png);
return "<img class='chartImage' src='data:image/png;base64, " + System.Convert.ToBase64String(imgStream.ToArray()) + "' />";
This code will return an img tag with data-uri as its src which you can then use in your HTML body of email.
Flow code:
The head tag:
<head runat="server">
<title></title>
<script type="text/javascript"
src="https://www.google.com/jsapi?autoload={
'modules':[{
'name':'visualization',
'version':'1',
'packages':['corechart']
}]
}"></script>
<script type="text/javascript">
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses'],
['2004', 1000, 400],
['2005', 1170, 460],
['2006', 660, 1120],
['2007', 1030, 540]
]);
var options = {
title: 'Company Performance',
curveType: 'function',
legend: { position: 'bottom' }
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
var txtBase64 = document.getElementById('txtBase64Image');
google.visualization.events.addListener(chart, 'ready', function () {
txtBase64.value = chart.getImageURI();
});
chart.draw(data, options);
}
</script>
</head>
Body tag:
<body>
<form id="form1" runat="server">
<div id="curve_chart" style="width: 900px; height: 500px"></div>
<%--If you want, you can textbox visible false.--%>
<asp:TextBox ID="txtBase64Image" runat="server" Width="600" TextMode="MultiLine"></asp:TextBox><br/>
<asp:Button ID="Button1" runat="server" Text="Send Mail" OnClick="Button1_Click" />
</form>
</body>
After c# code:
public Image Base64ToImage(string base64String)
{
var imageBytes = Convert.FromBase64String(base64String);
using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
var image = Image.FromStream(ms, true);
return image;
}
}
Button click: Send to mail chart. Look EmailSender https://github.com/serkomut/Serkomut.MailSender
protected void Button1_Click(object sender, EventArgs e)
{
var split = txtBase64Image.Text.Split(',')[1];
var image = Base64ToImage(split);
var stream = new MemoryStream();
image.Save(stream, ImageFormat.Jpeg);
stream.Position = 0;
var result = new EmailSender()
.FromHost("smtp.gmail.com")
.Credential("sendermail#gmail.com", "mailPassword")
.FromTo(new Message
{
From = "sendermail#gmail.com",
To = "tomail#gmail.com"
})
.Subject("Subject")
.Body("Content text...")
.Attachment(new Attachment(stream, "chart_image.jpg", "image/jpg"))
.Send();
}
Related
It's my first practice at getting data from a partial view but I don't know what's going wrong in my code. I cant get any data.
In my main view folder I created a partial view named Fault_statPartial and in my main view I call it like below:
<div>
#{ Html.RenderPartial("Fault_statPartial"); }
</div>
and in my partial view I have a button and when I click on it, it's supposed to return data. Here is the partial view code:
#model string
<html>
<head>
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
</head>
<body>
<script src="#Url.Content("~/Scripts/KndoTst/jquery.min.js")"></script>
<script src="#Url.Content("~/Scripts/KndoTst/kendo.all.min.js")"></script>
<script src="#Url.Content("~/Scripts/KndoTst/jquery.maskedinput.js")"></script>
#section Scripts{
<script src="#Url.Content("~/Scripts/KndoTst/jquery.min.js")"></script>
<script src="#Url.Content("~/Scripts/KndoTst/kendo.all.min.js")"></script>
<script src="#Url.Content("~/Scripts/KndoTst/jquery.maskedinput.js")"></script>
<button type="button" class="buttonForMonthlydailyYearly" id="faultstat" >FaultStat</button>
<script type="text/javascript">
var turbineName = [];
var finalResultYear = [];
var data = [];
var data_wind = [];
var finalResultWind = [];
//DropDownList
var drp = "s";
var topTenResultOfMonth = null;
var topTenResultOfYear = null;
var topTenResultOfDay = null;
var selcted;
var tmp;
var tmpString;
$("#faultstat").click(function (e) {
debugger;
tmp = $("#multiselect").val();
tmpString = tmp.toString();
$.ajax({
dataType: "json",
type: "POST",
url: "#Url.Action("faultStatstics","Ranking")",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ "id": tmpString }),
success: function (result) {
debugger;
var productionResult = result.sumOfDay[0].m_energy_prod;
var productionMonthresult = result.sumOfMonth;
var productionofYear = result.sumofyear;
// debugger;
$("#production").empty();
$("#production").append(productionResult);
$("#monthProduction").empty();
$("#monthProduction").append(productionMonthresult);
$("#yearProduction").empty();
$("#yearProduction").append(productionofYear);
}
});
});
</script>
}
</body>
</html>
Starting from here: How do I display a Json random number in a real-time Flot chart?, I managed to display a random number on a flot chart. The x axes is the current time's second. The problem I have is that now on my chart is shown only a point (current value). What I want is to display a real time line according to the values of the random number. How could I do this? I hope I made myself understood.
Here is my cod:
In C#:
if (method == "rnd")
{
//Current second
this.Page.Response.ContentType = "application/json1";
DateTime now = DateTime.Now;
int sec = now.Second;
Random rnd = new Random();
int nr = rnd.Next(1, 100); // creates a number between 1 and 99
var str = "{\"sec\":" + sec.ToString() + ",\"val\":" + nr.ToString() + "}";
var json2 = new JavaScriptSerializer().Serialize(str);
this.Page.Response.Write(json2);
}
My ASP page:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="MultiTrenduri.aspx.cs" Inherits="WebApplication2.MultiTrenduri" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/jquery-1.8.3.min.js"></script>
<script src="Scripts/flot/jquery.flot.min.js"></script>
<script src="Scripts/flot/jquery.flot.time.js"></script>
<script src="Scripts/flot/jquery.flot.symbol.js"></script>
<script src="Scripts/flot/hashtable.js"></script>
<script src="Scripts/flot/jquery.flot.axislabels.js"></script>
<script src="Scripts/flot/jquery.numberformatter-1.2.3.min.js"></script>
<link href="Flot/examples.css" rel="stylesheet" />
<script type="text/javascript">
var sc = [], num = [];
function test2() {
$.ajax({
type: 'POST',
url: ('ajax.aspx?meth=') + "rnd",
contentType: 'application/json2; charset=utf-8',
dataType: 'json',
async: true,
cache: false,
global: false,
timeout: 120000,
success: function (data, textStatus, jqXHR) {
var obj = jQuery.parseJSON(data);
$('#azi').html(obj.sec);
$('#nr').html(obj.val);
var sc = [], num = [];
sc.push(obj.sec);
num.push(obj.val);
data = [[[sc, num]]];
//var afis = [[[data]]];
//$('#afs').text(afis.join(" * "));
//show the data in a list in body
var items = [];
$.each(data, function (key, val1) {
items.push("<li><a href=#'" + key + "'>" + val1 + "</a></li>");
});
$( "<ul/>", {
"class": "my-new-list",
html: items.join( "" )
}).appendTo( "body" );
//START: PLOT IN TIMP REAL
$(function () {
var plot = $.plot("#placeholder", data,
{
series: {
shadowSize: 0 // Drawing is faster without shadows
},
points: { show: true },
line: { show: true },
yaxis: {
min: 0,
max: 100
},
xaxis: {
show: true
}
});
// plot.setData(data); //to reset data
// plot.draw(); //to redraw chart
});
// plot.draw();
//END: PLOT IN TIMP REAL
},
error: function (jqXHR, textStatus, errorThrown) {
window.alert(errorThrown);
}
});
}
window.setInterval(test2, 1000);
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="azi"></div>
<div id="nr"></div>
<div class="demo-container">
<div id="placeholder" class="demo-placeholder">
</div>
</div>
</div>
</form>
</body>
</html>
Maybe is someone which needs to do the same. This is how I managed to do it.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script src="Scripts/jquery-1.8.3.min.js"></script>
<script src="Scripts/flot/jquery.flot.min.js"></script>
<script src="Scripts/flot/jquery.flot.time.js"></script>
<script src="Scripts/flot/jquery.flot.symbol.js"></script>
<script src="Scripts/flot/hashtable.js"></script>
<script src="Scripts/flot/jquery.flot.axislabels.js"></script>
<script src="Scripts/flot/jquery.numberformatter-1.2.3.min.js"></script>
<link href="Flot/examples.css" rel="stylesheet" />
<%-- Library for TOOLTIP:--%>
<script src="Scripts/flot/jquery.flot.crosshair.js"></script>
<!-- CSS -->
<%--<style type="text/css">
#placeholder {
width: 1000px;
height: 500px;
text-align: center;
margin: 0 auto;
}
</style>--%>
<%-- <link href="Flot/examples.css" rel="stylesheet" />--%>
<%-- <script src="Scripts/jquery-1.4.1.js"></script>
<script src="Scripts/flot/jquery.flot.js"></script>--%>
<script type="text/javascript">
var sc = [], num = [];
var data = [];
var dataset;
var totalPoints = 100;
var updateInterval=30 ;
var now = new Date().getTime();
var t;
var multipleCalls, multCalls;
var input = document.getElementById('input');
var st;
/* window.onload = function f1() {
document.getElementById('updateInterval').value = 90;
}
function f2() {
// document.getElementById('up2').value = document.getElementById('up1').value
var updateInterval = document.getElementById('updateInterval').value;
// window.alert(updateInterval);
}*/
$(function () {
function test2() {
$.ajax({
type: 'GET',
url: ('ajax.aspx?meth=') + "rnd",
contentType: 'application/json2; charset=utf-8',
dataType: 'json',
//async: true,
//cache: false,
//global: false,
// timeout: 120000,
success: function (data, textStatus, jqXHR) {
var obj = jQuery.parseJSON(data);
$('#azi').html(obj.sec);
$('#nr').html(obj.val);
t = obj.val;
},
error: function (jqXHR, textStatus, errorThrown) {
window.alert(errorThrown);
}
});
}
function apel() {
test2();
$('#fn').html(t);
updateInterval = document.getElementById('updateInterval').value;
}
function GetData() {
data.shift();
data.slice(1);
while (data.length < totalPoints) {
// var y = Math.random() * 100;
var y = t;
var temp = [now += updateInterval, y];
data.push(temp);
}
}
$("#up").val(updateInterval).change(function () {
var vv = $(this).val();
if (vv && !isNaN(+vv)) {
updateInterval = +vv;
if (updateInterval < 1) {
updateInterval = 1;
} else if (updateInterval > 2000) {
updateInterval = 2000;
}
$(this).val("" + updateInterval);
}
});
var options = {
series: {
lines: {
show: true,
lineWidth: 1.2,
fill: false
}
},
xaxis: {
mode: "time",
tickSize: [2, "second"],
tickFormatter: function (v, axis) {
var date = new Date(v);
if (date.getSeconds() % 5 == 0) {
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
var w = hours + ":" + minutes + ":" + seconds;
return w;
} else {
return "";
}
},
axisLabel: "Time",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 10
},
grid: {
hoverable: true,
clickable: true
},
yaxis: {
min: 0,
max: 100,
tickSize: 5,
tickFormatter: function (v, axis) {
if (v % 10 == 0) {
return v + "%";
} else {
return "";
}
},
axisLabel: "CPU loading",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 6
},
legend: {
labelBoxBorderColor: "#fff"
}
};
//START TOOLTIP
/* $("#placeholder").bind("plothover", function (event, pos, item) {
if ($("#enablePosition:checked").length > 0) {
var str = "(" + pos.x.toFixed(2) + ", " + pos.y.toFixed(2) + ")";
$("#hoverdata").text(str);
}
if ($("#enableTooltip:checked").length > 0) {
if (item) {
var x = item.datapoint[0].toFixed(2),
y = item.datapoint[1].toFixed(2);
$("#tooltip").html(item.series.label + " of " + x + " = " + y)
.css({ top: item.pageY + 5, left: item.pageX + 5 })
.fadeIn(200);
} else {
$("#tooltip").hide();
}
}
});
$("#placeholder").bind("plotclick", function (event, pos, item) {
if (item) {
$("#clickdata").text(" - click point " + item.dataIndex + " in " + item.series.label);
plot.highlight(item.series, item.datapoint);
}
});
*/
//END TOOLTIP
st = $(document).ready(function f1() {
test2();
GetData();
dataset = [
{ label: "CPU", data: data }
];
$.plot($("#placeholder"), dataset, options);
function stop() {
//window.alert("Stop");
//multipleCalls.clearTimeout();
window.clearTimeout(updateInterval);
}
function update() {
test2();
GetData();
$.plot($("#placeholder"), dataset, options)
multipleCalls = setTimeout(update, updateInterval);
multCalls = multipleCalls;
}
update();
});
});
</script>
</head>
<body>
//Stops the graph
<button onclick="clearInterval(multipleCalls)">Stop</button>
<div id="header">
<div id="azi"></div>
<div id="nr"></div>
</div>
<div id="content">
<div class="demo-container">
<div id="placeholder" class="demo-placeholder"></div>
</div>
<p>Time between updates: <input id="up" type="text" value="" style="text-align: right; width:5em"/> milliseconds</p>
</div>
</body>
</html>
My Html code:
<div class="col-md-6">
<img ngf-src="!picFile.$error && picFile" style="height: 150px; width: 200px;">
<input type="file" ngf-select ng-model="picFile" name="file"
accept="image/*" ngf-max-size="2MB"><b>Picture</b><br />
</div>
<div class="col-md-6">
<img ngf-src="!sigFile.$error && sigFile" style="height: 150px; width: 200px;">
<input type="file" ngf-select ng-model="sigFile" name="file"
accept="image/*" ngf-max-size="2MB"><b>Signature</b><br />
</div>
And My angular code
$scope.SaveNewJoinHolder = function (picFile, sigFile) {
if (investor_validity == 1) {
if ($scope.newJoinHolderForm.$valid) {
if (typeof $scope.newJoinHolder.DOB == undefined) {
$scope.newJoinHolder.DOB = null;
}
else {
var datefilter = $filter('date');
$scope.newJoinHolder.DOB = datefilter($scope.newJoinHolder.DOB, 'dd/MM/yyyy');
$scope.newJoinHolder.birth_date = dateconfigservice.FullDateUKtoDateKey($scope.newJoinHolder.DOB);
}
Upload.upload(
{
url: '/InvestorManagement/JoinHolder/SaveNewJoinHolder',
method: 'POST',
fields: $scope.newJoinHolder,
file: { picFile: picFile, sigFile: sigFile },
async: true
})
.success(function () {
toastr.success('Submitted Successfully');
}).error(function () {
toastr.success('Failed');
});
}
}
};
I debugged the code and I got both of the file while debugging. But it is not calling my C# method
public JsonResult SaveNewJoinHolder(tblJoinHolder joinHolder, HttpPostedFileBase picFile, HttpPostedFileBase sigFile)
{
joinHolderFactory = new JoinHolderFactory();
try
{
joinHolder.membership_id = SessionManger.BrokerOfLoggedInUser(Session).membership_id;
joinHolder.changed_user_id = User.Identity.GetUserId();
joinHolder.changed_date = DateTime.Now;
joinHolder.is_dirty = 1;
byte[] image = new byte[picFile.ContentLength];
picFile.InputStream.Read(image, 0, picFile.ContentLength);
joinHolder.photo = image;
byte[] signature = new byte[sigFile.ContentLength];
sigFile.InputStream.Read(image, 0, sigFile.ContentLength);
joinHolder.signature = signature;
joinHolderFactory.Add(joinHolder);
joinHolderFactory.Save();
return Json(new { data = "Successfully Saved Data", success = true });
}
catch (Exception ex)
{
return Json(new { data = ex.Message, success = false });
}
}
What is the problem here?
If I try to upload single image it is working.
Before version 7.2.0 you couldn't specify a map as file option so you had to do
Upload.upload(
{
url: '/InvestorManagement/JoinHolder/SaveNewJoinHolder',
method: 'POST',
fields: $scope.newJoinHolder,
file: [picFile, sigFile],
fileFormDataName: ['picfile', 'sigFile'],
})
But since version 7.2.0 your original code should work.
You can verify the network tab of your browser to make sure that the file form data is being sent to the server.
<body>
<form id="form1" runat="server" enctype="multipart/form-data">
<table id="tblAttachment"> </table>
<input id="btnSubmit" type="button" value="button" />
</form>
</body>
Dynamically inserting a FileUpload Control
<script>
$(document).ready(function () {
var MaxAttachment = 1;
$("#tblAttachment").append('<tr><td><input id=\"Attachment_' + MaxAttachment.toString() + '\" name=\"file\" type=\"file\" /><br><a class=\"MoreAttachment\">Additional Attachment</a></td></tr>');
$("#btnSubmit").on("click", UploadFile);
});
</script>
Sending Data to .ashx using Jquery
function UploadFile() {
var kdata = new FormData();
var i = 0;
//run through each row
$('#tblAttachment tr').each(function (i, row) {
var row = $(row);
var File = row.find('input[name*="file"]');
alert(File.val());
kdata.append('file-' + i.toString(), File);
i = i + 1;
});
sendFile("fUpload.ashx", kdata, function (datad) {
}, function () { alert("Error in Uploading File"); }, true);
}
On .ashx Count always Zero ??
public class fUpload : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
int k = context.Request.Files.Count;
context.Response.Write(UploadMultipleFiles());
}
Ajax Request
function sendFile(requestUrl, dataPayload, successfunc, errorfunc, synchronousMode) {
$.ajax({
url: requestUrl,
type: "POST",
dataType: "json",
contentType: false,
processData: false,
cache: false,
async: synchronousMode,
data: dataPayload,
success: successfunc,
error: errorfunc
});
}
Please Check .. where i m doing wrong
form tag having enctype="multipart/form-data" and each fileUPload control have uniue id and name attribute too
Thanks
You're sending a jQuery object, not a file ?
Shortened down, you're basically doing this
var kdata = new FormData();
var File = row.find('input[name*="file"]'); // jQuery object
kdata.append('file-0', File);
You need the files, not the jQuery objects
var kdata = new FormData();
var File = row.find('input[name*="file"]'); // jQuery object
var files = File.get(0).files[0]; // it not multiple
kdata.append('file-0', Files);
I have a search form with several autocomplete fields.
When the page loads first time, everything works nicely, but if I reload/press F5 all the fields with minLength: 0 are triggered even though none gets or have focus.
No other action causes this.
function autocompleter(searchfield, autocompletee) {
$(searchfield)
.autocomplete({
minLength: autocompletee.minLength,
source: autocompletee.array,
change: function(event, ui) {
if (!ui.item) {
event.target.value = "";
}
},
select: function (event, ui) {
var chosenWord = ui.item.label;
var searchKeyWord = {
"webformField": autocompletee.selected,
"searchString": chosenWord
};
$.ajax({
contentType: "application/json; charset=utf-8",
type: 'POST',
url: "MyHandler.ashx",
data: JSON.stringify(searchKeyWord),
});
var title = ui.item.label; //get the object title here
$(searchfield).val(title);
$(autocompletee.chosen).append("<asp:HyperLink href='#' class='myClass' runat='server' ID='" + chosenWord + "'>" + chosenWord + "</asp:HyperLink>"); //
$(searchfield).val("");
$(searchfield).blur();
return false;
}
}).focus(function() {
$(this).autocomplete("search", "");
});
}
$(document).ready(function() {
var myObject = {
array: window.myarray,
selected: "object_chosen",
chosen: "#object_chosen",
minLength: 0,
};
autocompleter('#inputField, myObject);
});
<input type="text" id="inputField" placeholder="Text" runat="server" clientidmode="Static" />
<asp:Panel ID="object_chosen" CssClass="chosen-tag-container" ClientIDMode="Static" runat="server">
<%-- links appear here--%>
</asp:Panel>
Try This
$(document).ready(function() {
var myObject = {
array: window.myarray,
selected: "object_chosen",
chosen: "#object_chosen",
minLength: 0,
};
autocompleter("#inputField", myObject); //Remove this because it's calling that function on page load
});