Add a footer to an exported OxyPlot plot - oxyplot

I am using OxyPlot to export plots.
When I export them, I want to add a footer to these plots with information like the path it is saved, a time-stamp, and so on...
Right now I am doing this by creating an extra X-axis on a different position-tier and then setting the sizes of all ticks and labels to zero except for the title font-size.
This works, but as you might imagine, this is quite hacky and does not look that good (as you cannot set for example the aligning).
So my question is, is there a possibility to add such a footer to the exported plot?
EDIT:
var xAxis = new OxyPlot.Axes.LinearAxis
{
Position = AxisPosition.Bottom,
PositionTier = 1,
Title = "Footer: i.e. path to my file",
MinorTickSize = 0.0,
MajorTickSize = 0.0,
FontSize = 0.0,
TitleFontSize = 12,
AxisDistance = 10
};
This is the workaround I mentioned.
I create an axis at position-tier 1, which is below the first one and then disable all visuals of it except the title.
And in the end I add it to my plotmodel pm.Axes.Add(xAxis).
To export my plotmodel I use PdfExporter like this:
using (var stream = File.Create(testFile.pdf))
{
PdfExporter.Export(pm, stream, 800, 500);
}
Greetings
Chriz

Just had to do the same thing with my project and thought I'd share how I managed it for anyone else in need of a footer.
I couldn't find any built in OxyPlot methods to add a header or footer but if you use OxyPlot.PDF it's built on top of PDFSharp and you have more options to customize your PDF export.
Remove any previous reference to OxyPlot.Pdf in your project.
Download OxyPlot.Pdf source code from: https://github.com/oxyplot/oxyplot
In your project in VS, right click your solution in 'Solution Explorer' and Add Existing Project.
Navigate to the downloaded source code and add OxyPlot.Pdf.csproj
Right click your project and Add Reference
Select 'Projects' on the left and check the box for OxyPlot.Pdf on the right. Hit OK.
Check that it's working by building and running project.
Go to PdfRenderContext.cs file and find the PdfRenderContext method near the top.
Add the code below then build and run your project.
This code creates a MigraDoc Document and then merges it with the OxyPlot PdfDocument.
public PdfRenderContext(double width, double height, OxyColor background)
{
//*** Original Code - Don't change **//
this.RendersToScreen = false;
this.doc = new PdfDocument();
var page = new PdfPage { Width = new XUnit(width), Height = new XUnit(height) };
this.doc.AddPage(page);
this.g = XGraphics.FromPdfPage(page);
if (background.IsVisible())
{
this.g.DrawRectangle(ToBrush(background), 0, 0, width, height);
}
//*** New Code to add footer **//
Document myDoc = new Document();
Section mySection = myDoc.AddSection();
Paragraph footerParagraph = mySection.Footers.Primary.AddParagraph();
footerParagraph.AddText(DateTime.Now.ToShortDateString());
footerParagraph.Format.Alignment = ParagraphAlignment.Right;
MigraDoc.Rendering.DocumentRenderer docRenderer = new MigraDoc.Rendering.DocumentRenderer(myDoc);
docRenderer.PrepareDocument();
docRenderer.RenderObject(g, XUnit.FromInch(9.5), XUnit.FromInch(8), "1in", footerParagraph);
}
When you export the PDF a date stamp is now added to the lower right corner of the PDF. Note that I was working with landscape 8.5x11 inch paper so you may need to change position if you don't see it on the plot. Upper left corner is 0,0. Once it's working, build the OxyPlot.Pdf project to create the dll and then you can add it as a reference to your project and remove the source code.
Result:

Related

Custom IntelliCode prediction with Visual Studio extension

I would like to add the custom IntelliCode prediction/inline suggestion in Visual Studio with extension. In VSCode, I can use vscode.InlineCompletionProvider/InlineCompletionItem to do that. What's the class/method that would do the same things in Visual Studio extension?
I had the same requirement but I did not find any API for that.
However, what you can do is use adornments to draw a text that looks like code.
Define the adornment:
[Export(typeof(AdornmentLayerDefinition))]
[Name("TextAdornment1")]
[Order(After = PredefinedAdornmentLayers.Text)]
private AdornmentLayerDefinition editorAdornmentLayer;
Get the layer and add a TextBlock:
_layer = view.GetAdornmentLayer("TextAdornment1");
// triggeringLine is your current line
var geometry = _view.TextViewLines.GetMarkerGeometry(triggeringLine.Extent);
var textBlock = new TextBlock
{
Width = 600,
Foreground = _textBrush,
Height = geometry.Bounds.Height,
FontFamily = new FontFamily(_settings.FontFamily),
FontSize = _fontSize,
Text = $"Your completion text"
};
// put the box at the end of your current line
Canvas.SetLeft(textBlock, geometry.Bounds.Right);
Canvas.SetTop(textBlock, geometry.Bounds.Top);
_layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, triggeringLine.Extent, "your tag", textBlock, (tag, ui) => { });
You can get the current editor settings as follows:
// Get TextEditor properties
var propertiesList = dte.get_Properties("FontsAndColors", "TextEditor");
// Get the items that are shown in the dialog in VS
var itemsList = (FontsAndColorsItems)propertiesList.Item("FontsAndColorsItems").Object;
// Get color for comments
var commentItem = itemsList.Cast<ColorableItems>().Single(i => i.Name=="Comment");
var colorBytes = BitConverter.GetBytes(commentItem.Foreground);
var commentColor = Color.FromRgb(colorBytes[2], colorBytes[1], colorBytes[0]);
// Get editor BG
var textItem = itemsList.Cast<ColorableItems>().Single(i => i.Name == "Plain Text");
var bgColorBytes = BitConverter.GetBytes(textItem.Background);
var bbgColor = Color.FromRgb(bgColorBytes[2], bgColorBytes[1], bgColorBytes[0]);
// Get font size in points
var fontSize = (short)propertiesList.Item("FontSize").Value;
// Get current font family
var fontFamily = (string)propertiesList.Item("FontFamily").Value;
The issue with this approach is that the styling and font size slightly differs from the editor. Even if you use the editor setting.
However I think that IntelliCode and GitHub Copilot use another technique. As you can see here:
GitHub Coilot
It seems as the whole code is already inserted to the editor but has a special styling/behaviour. So it is possible somehow, but I don't how to achieve that.
For more information on adornments look here for example:
Visual Studio Text Adornment VSIX using Roslyn
You can implement your custom language-based statement completion. Please take a look at:
Walkthrough: Displaying Statement Completion
Implementing Custom XAML Intellisense VS2017 Extension
Visual-studio – Custom Intellisense Extension
Custom Intellisense Extension
Another different option is using GitHub Copilot extension for Visual Studio, it predicts code using AI

Adobe Photoshop Scripting - How to Select Bounding Box Around Current Selection?

Does anyone know whether it's possible, in Photoshop extend script, to convert an irregular selection (e.g. magic wand tool selection) into a rectangular selection encompassing the top, left, bottom and right bounds of the selection?
Here it is, I have documented the code so you can modify it later if you need. Also, check page 166 and following of Photoshop's JS reference manual, you may read more about selections - you can set feather, extend/intersect/etc. the selection if you need to.
Made for CS6, should work with latter.
#target photoshop
if (documents.length == 0) {
alert("nothing opened");
} else {
// start
//setup
var file = app.activeDocument;
var selec = file.selection;
//run
var bnds = selec.bounds; // get the bounds of current selection
var // save the particular pixel values
xLeft = bnds[0],
yTop = bnds[1],
xRight = bnds[2],
yBottom = bnds[3];
var newRect = [ [xLeft,yTop], [xLeft,yBottom], [xRight,yBottom], [xRight,yTop] ]; // set coords for selection, counter-clockwise
selec.deselect;
selec.select(newRect);
// end
}

How can I display a logo and its description in the same line using iTextSharp?

I want to show a logo and its description in a pdf using itextSharp.
Example:
Logo LogoDescription
My below code shows logo and its description on two different lines
Document^ doc = gcnew Document(iTextSharp::text::PageSize::LETTER,10,10,42,32);
doc->Open();
// add image
iTextSharp::text::Image^ bmp = iTextSharp::text::Image::GetInstance("bts_logo.bmp");
bmp->ScaleToFit(50,100);
bmp->Border = iTextSharp::text::Rectangle::BOX;
bmp->BorderColor = iTextSharp::text::BaseColor::RED;
bmp->BorderWidth = 2;
doc->Add(bmp);
doc->Add(gcnew Phrase("Logo description", gcnew iTextSharp::text::Font(iTextSharp::text::Font::FontFamily::HELVETICA, 11, iTextSharp::text::Font::BOLD)));
I am using Visual Studio 2012.
If you want to add a Phrase (e.g. a description) next to an Image (e.g. a picture), you typically create a PdfPTable:
PdfPTable table^ = gcnew PdfpTable(2);
This will create a table that shows borders by default. You can change this by adding this line:
table->DefaultCell->Border = iTextSharp::text::Rectangle::NO_BORDER;
You then add the image and the text as cells:
table->AddCell(bmp);
table->AddCell(phrase);
Where bmp is an instance of the Image class, and phrase is an instance of the Phrase class.
You then add the table to the document:
doc->Add(table);
The table will have borders by default, but as I am not familiar with the programming language you are using, you probably know better how to change the border of the default cell to NO_BORDER than I do.

How can I reduce the top margin of a MigraDoc document?

How can I reduce the top margin of a MigraDoc document?
I added an image to the top right of my document however the space between the top of the document and the image is too big.
Here is how I'm setting the image:
Section section = document.AddSection();
Image image = section.AddImage(#"C:\img\mentSmallLogo.png");
image.Height = "1.5cm";
image.Width = "4cm";
image.LockAspectRatio = true;
image.RelativeVertical = RelativeVertical.Line;
image.RelativeHorizontal = RelativeHorizontal.Margin;
image.Top = ShapePosition.Top;
image.Left = ShapePosition.Right;
image.WrapFormat.Style = WrapStyle.Through;
And the document style:
Style style = document.Styles["Normal"];
style.Font.Name = "Verdana";
style = document.Styles[StyleNames.Header];
style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right);
style = document.Styles[StyleNames.Footer];
style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center);
// Create a new style called Table based on style Normal
style = document.Styles.AddStyle("Table", "Normal");
style.Font.Name = "Verdana";
style.Font.Name = "Times New Roman";
style.Font.Size = 8;
// Create a new style called Reference based on style Normal
style = document.Styles.AddStyle("Reference", "Normal");
style.ParagraphFormat.SpaceBefore = "5mm";
style.ParagraphFormat.SpaceAfter = "5mm";
style.ParagraphFormat.TabStops.AddTabStop("16cm", TabAlignment.Right);
style.ParagraphFormat.Font.Size = 8;
How can I reduce the space between the image and the top of the page?
Set image.WrapFormat.DistanceTop to set the top position of the image.
If you set the image position this way, there is no need to modify the PageSetup.
There are different values for RelativeVertical that can be used. And you can also use negative values.
See also:
http://forum.pdfsharp.net/viewtopic.php?p=5267#p5267
With respect to the other answer: it is good practice not to modify DefaultPageSetup. Instead make a Clone() of DefaultPageSetup and modify that.
The PageSetup of your documentis specific to your document. The DefaultPageSetup is shared by all documents; modifying it can lead to strange effects when you persist documents in MDDDL format or when your application has different documents with different page setups.
Code that creates a clone can look like this:
var doc = new Document();
var section = doc.AddSection();
section.PageSetup = doc.DefaultPageSetup.Clone();
Then you can make all necessary changes to section.PageSetup. If you need different settings for other sections, you can use either doc.DefaultPageSetup.Clone() or section.PageSetup.Clone() to get started.
something like this
document.DefaultPageSetup.LeftMargin = MigraDoc.DocumentObjectModel.Unit.FromCentimeter(.8);
document.DefaultPageSetup.TopMargin = MigraDoc.DocumentObjectModel.Unit.FromCentimeter(.5);
document.DefaultPageSetup.PageWidth = MigraDoc.DocumentObjectModel.Unit.FromCentimeter(11);
My solution to this involved having the image in my header section of the document, and controlling the position within the header by enclosing it in a borderless table.
Actual header and footer sections of the document are not effected by the margins applied to the document, they have their own Unit properties.
There is a HeaderDistance property in the PageSetup object of the document.
Same thing exists for Footers (FooterDistance).
https://forum.pdfsharp.net/viewtopic.php?f=2&t=3076
document.DefaultPageSetup.HeaderDistance = "0.20in";
document.DefaultPageSetup.FooterDistance = "0.20in";
Although other answers say to not modify DefaultPageSetup directly, it is a read-only variable in the document object, so you cannot set it equal to a clone. This is the best way.

Changing text color in PdfSharp

I'm currently creating a PDF with PdfSharp which mostly consists of text and some images.
The text elements have different colors. My problem is that as soon as I use a different color than the color I started with, the text is not visible in the resulting PDF (e.g. I start with black text, switch to a red text, the red text is not visible). All text elements are in the resulting PDF (I can select them), but the red elements are invisible.
So here is the code:
// Create a new PDF document with one page
var document = new PdfDocument();
var page = document.AddPage();
page.Width = 800;
page.Height = 600;
var defaultFont = new XFont("Arial", 12, XFontStyle.Regular, new XPdfFontOptions(PdfFontEmbedding.Always));
var gfx = XGraphics.FromPdfPage(page);
// black text
gfx.DrawString("black", defaultFont, XBrushes.Black, new XRect(x, y, width, height), XStringFormats.Center);
// red text
gfx.DrawString("red", defaultFont, XBrushes.Red, new XRect(x2, y2, width2, height2), XStringFormats.Center);
I've already found a solution (re-creating the XGraphics object) but it's quiete messy because it needs to be called after each color change:
// ...
// black text
gfx.DrawString("black", defaultFont, XBrushes.Black, new XRect(x, y, width, height), XStringFormats.Center);
// disposing the old graphics context and creating a new one seems to help
gfx.Dispose();
gfx = XGraphics.FromPdfPage(page);
// red text
gfx.DrawString("red", defaultFont, XBrushes.Red, new XRect(x2, y2, width2, height2), XStringFormats.Center);
I guess there is a better solution, but I couldn't find one yet.
Edit
As suggested in this answer, I wanted to create a SSCCE. During the creation I found the actual bug. Instead of XBrushes.Red I used an own defined XBrush, but didn't mention it in the above code snippet, because I thought it was unnecessary.
As already mentioned in the last section of the question, I used an own defined brush instead of XBrushes.Red.
I defined it the following way:
XBrush redBrush = new XSolidBrush(new XColor {R = 207, G = 0, B = 44});
This way the brush only worked after I disposed the graphics object and created a new one. But after some googling I found the correct way to define a brush:
XBrush redBrush = new XSolidBrush(XColor.FromArgb(207, 0, 44));
I tried to replicate your problem using your code snippet and PDFsharp version 1.32. I used VS Express 2013 which automatically converted all projects to .NET 4.5.
I tried both builds (GDI+ and WPF) and all colours worked fine for me.
So instead of just a code snippet you should provide an SSCCE.
See also:
http://forum.pdfsharp.net/viewtopic.php?p=2094#p2094