How do I create a copy of an asp.net chart? - c#

I'm currently designing a web-based (asp.net/C#) volume tracking tool for a company which is used for reporting and rendering volume data. One way for the user to render data is through using a chart tool which uses the asp.net built-in chart. The user can set plenty of different filtering options to customize his chart appropriately and then have it rendered on the same page. Regarding the contents of the chart everything is working quite alright, however I have created a few controls for giving the user the possibility to generate higher quality images of their graph and show them in a separate window. Using an extension method for Response.Redirect I am redirecting the user to a new window that contains the high resolution version of the chart image, as can be seen below:
private void DownloadImage(int width, int height)
{
double scale = width / ViewGraphChart.Width.Value;
// Resize chart:
ViewGraphChart.Width = width;
ViewGraphChart.Height = height;
// Resize titles:
foreach (Title t in ViewGraphChart.Titles)
{
t.Font = new Font(t.Font.FontFamily, (float)(t.Font.Size * scale), FontStyle.Regular);
}
// Resize legends:
foreach (Legend l in ViewGraphChart.Legends)
{
l.Font = new Font(l.Font.FontFamily, (float)(l.Font.Size * scale), FontStyle.Regular);
}
UpdateChart();
// Open image in new window:
Response.Redirect(ViewGraphChart.CurrentImageLocation, "_blank", "");
}
So far so good, a new window opens up and the user is handed a high resolution version of his chart image. The problem is however that the chart in the tool also, naturally, is modified and obviously becomes way too big to properly fit inside the layout. I tried to remedy this by resetting the chart properties right after the redirect, this however made the "HD" chart image show up as the same tiny chart image inside the tool. So, I figured the best way would be to make a copy of the chart, modify the copy and hand it to the user, while the original image remains its small size within the tool. Is there any simple way to do this, considering that I have tons of databindings and other things connected to my chart, or is there some other way to go about?
I'm in somewhat of a hurry so if this came out rather unclear, please tell me and I'll explain more thoroughly.
Regards,
Ante
Edit:
The code behind the Response.Redirect extension method. Borrowed from this very page if I remember correctly.
public static void Redirect(this HttpResponse response, string url, string target, string windowFeatures)
{
if
((String.IsNullOrEmpty(target) || target.Equals("_self", StringComparison.OrdinalIgnoreCase))
&& String.IsNullOrEmpty(windowFeatures))
{
response.Redirect(url);
}
else
{
Page page = (Page)HttpContext.Current.Handler;
url = page.ResolveClientUrl(url); string script;
if (!String.IsNullOrEmpty(windowFeatures))
{
script = #"window.open(""{0}"", ""{1}"", ""{2}"");";
}
else
{
script = #"window.open(""{0}"", ""{1}"");";
}
script = String.Format(script, url, target, windowFeatures);
ScriptManager.RegisterStartupScript(page, typeof(Page), "Redirect", script, true);
}
}

Related

How to place a photo in a specific location in Indesign document using C#?

I need to place photos on Indesign pages, few on each of 100 pgs. I use Place function and it causes to the photo to be loaded on the cursor, and then I need to click on the location I want it. But I need it to be automatic! I mean, to finish placing the photos on the page, but it waits to the user to click.
This is the code:
Indesign.Page pg = doc.Pages[1];
Indesign.TextFrame frm = pg.TextFrames[1];
string txt = frm.Contents;
if (txt.Contains("ploni"))
{
app.Place("C:\\User\\Directory\\PhotoFile.png");
}
I have noticed that Indesign.Page has another parameter in its Place function that called "InsertionPoint". But I didn't understand what is it.
Yes, finally I created a rect, then position it, and then place the image inside. Like this:
InDesign.Rectangle rct = pg.Rectangles.Add(doc.Layers.FirstItem(), InDesign.idLocationOptions.idUnknown, pg);
rct.GeometricBounds = new[] { yDown, xDown, yUp, xUp };
rct.Place(#"C:\User\image.png");
I know nothing about C#, but in Extendscript InDesign DOM Page object has place() method. http://jongware.mit.edu/idcs6js/pc_Page.html And it doesn't wait any click from a user.
You can place image at top-left corner of a page this way:
app.activeDocument.pages[0].place("c:/temp/image.jpg")
I believe C# uses the the more or less same object model as Extendscript.

How to display a PDF in Winforms with no obstructions?

I want to display a PDF in my WinForms C# application. I have tried using a WebBrowser component, but it displays control bars from Adobe Reader. I have also tried a component Adobe PDF Reader control axAcroPDF, but using it crashed the responsiveness of my form, other components didn't move when resizing the form (I don't know why). What can I do to either change the WebBrowser component to not display the controls, or display the PDF in some other way?
With Magick.NET, you can convert your pdf to an image, and display it on the form. Also you need the GhostScript to be installed on your PC. Something like this:
using (var image = new MagickImage())
{
private MagickReadSettings _settings;
_settings = new MagickReadSettings()
{
FrameCount = 1, // return only one page
};
_settings.FrameIndex = 1; // return only the first page
_settings.Density = new Density(resolution); // set the resolution
image.Read(DocPath, _settings);
image.ColorAlpha(MagickColors.White);
bmp = image.ToBitmap();
}
Or, you can try this, but I have no experience with that. It is free and has some limitations, but may be it will fit your needs.

How to wait for each page before taking screenshot?

I'm trying to have Selenium take a screenshot of the current page in the webdriver. I'd also like to set the browser's dimensions before this occurs so that the screenshot can capture an image of a specific size.
I use this to change the window size:
webDrv.Manage().Window.Size = new Size(w, h);
And this to take the screenshot:
Screenshot ss = ((ITakesScreenshot)webDrv).GetScreenshot();
ss.SaveAsFile(Path.Combine(m_path, m_filename), ScreenshotImageFormat.Png);
The problem is that on some pages, the screenshot will be taken before the browser has finished redrawing the page.
I cannot use the usual methods of checking (such as using JS to get the document.readyState) because the page is already loaded at this point, so any checks like this return true.
This is only a problem on pages that use Javascript to resize elements based on window size. Pages that use CSS don't have this problem.
I can get around this by taking the entire HTML Body element before and comparing it to after the resize is completed:
webDrv.Manage().Window.Size = new Size(w, h);
int oldBodyHash = webDrv.FindElement(By.TagName("body")).Text.GetHashCode(); //get a hash of the current html body
DateTime nextthink = DateTime.Now.AddSeconds(10); //hard time out incase there is no javascript resizing
while (webDrv.FindElement(By.TagName("body")).Text.GetHashCode() == oldBodyHash && DateTime.Now < nextthink) //wait until hash changes or timeout occurs
{
Thread.Sleep(500);
}
Screenshot ss = ((ITakesScreenshot)webDrv).GetScreenshot();
ss.SaveAsFile(Path.Combine(m_path, m_filename), ScreenshotImageFormat.Png);
But then on pages using CSS to control changing elements, there is no change in the HTML Body.
It seems like it is one or the other, but it's not possible to cover for both possibilities?
I have the same question question JeffC, but to directly fix you problem try adding a
browser.refresh()
in between the window resize and the screenshot-taking.
Looks like there is no actual solution to this other than changing the order in which we perform the operations; essentially the solution is to change the browser dimensions far enough ahead of time to ensure that JS resize activities complete before the screenshot is taken.

How to combine multiple PrintVisual() in 1 print-job?

I have a C# WPF application (.NET 4.6) that needs to print a number of Page objects.
Each Page is setup in the XAML editor to be exactly 1 page of A4 in size and the content is build from a number of label, border and image components placed on the Page.
I added a method to my Page class that adds some dynamic data at run-time to the Page and then prints it using PrintVisual().
In fact: Its a loop that fills a Page object with the dynamic content and then calls PrintVisual() to print it. For each iteration, some new content is placed in the Page. (See sample code.)
// Print method of the Page object.
public void PrintIt(int totalpages)
{
PrintDialog pDialog = new PrintDialog();
// If not cancelled then print
if (pDialog.ShowDialog() == false) return; // User cancelled. Don't bother
for(int pagenum=1; i<=totalpages; i++)
{
// Omitted several dozen statements that fill/update the content of various
// label components based on the pagenumber.
this.UpdateLayout(); // Required to re-render new page properly before printing.
pDialog.PrintVisual(this, "My PrintJob");
}
}
This works well, expect for the fact that each PrintVisual() creates a separate print-job, which makes it impossible to print double-sided (and when printing to PDF each page ends up in a new file).
I need to tie all pages (PrintVisual() calls) in a single print-job. I'm fairly sure that I need to use a PrintDocument(), but I can't seem to figure out how to construct the required FlowDocument and populate it with my actual prints.
I'm quite new to WPF programming so I'm probably missing something obvious, but as far as I can't tell there isn't any simple way to do this.
Can anyone give me a push in the right direction ?

How to render a string containing HTML into an image in C#?

I am developing a web application that has an interactive feedback tool for users. In this application users can click a send feedback button. The button puts up an overlay over their current web page and allows them to drag highlight area DIVs to emphasize certain areas. Once they submit their feedback the HTML of the entire page is passed via AJAX back to the server.
Once on the server I now have a string containing the HTML of the page. From here I would like to run this string through some sort of engine that renders the HTML and builds an image. A sort of round about way of taking a screenshot if you will.
How might one accomplish something like this? Are there engines available that are written in C# and can build up the HTML and render an image?
Check out this framework - http://awesomium.com/
This is exactly what you need.
Set the base URL, this will be needed to resolve any relative URLs
WebCore.SetBaseDirectory("C:\\MyApplication\\MyBaseDirectory");
Then load the HTML -
myWebView.LoadHTML("<p>Hello World!</p>");
Then use the .Render() method, and you'll be able to save the rendered content to an image.
You can consider usin LLMozLib if you want to go by Gecko.
See more details here
EDIT
There's an ActiveX control to embed Gecko on Windows.
Sample here
EDIT
I got it working on a Windows Forms application.
Using these resources.
It is a csharp wrapper to Gecko ...
That's my sample code ...
public partial class Form1 : Form
{
public Form1()
{
Xpcom.Initialize(#"C:\Users\esouza\Downloads\xulrunner"); //Tell where are XUL bin
InitializeComponent();
//geckoWebBrowser1 is an instance of GeckoWebBrowser control that I've dragged on the Form1
geckoWebBrowser1.DocumentCompleted += new EventHandler(geckoWebBrowser1_DocumentCompleted);
}
private void button1_Click(object sender, EventArgs e)
{
geckoWebBrowser1.Navigate("http://www.google.com");
}
void geckoWebBrowser1_DocumentCompleted(object sender, EventArgs e)
{
Bitmap b = new Bitmap(geckoWebBrowser1.Width, geckoWebBrowser1.Height);
geckoWebBrowser1.DrawToBitmap(b, new Rectangle { X = 0, Y = 0, Width = 800, Height = 600 });
b.Save("file.bmp");
}
}
Very interesting question and I've not got a silver bullet for you.
You're surely going to need a browser engine of some description and then capture the rendered output as a bitmap.
I see from this question that there was a COM wrapper developed for WebKit. Maybe that's a good starting point.

Categories