├── .gitignore ├── .vscode └── tasks.json ├── Docs ├── .gitignore ├── Examples.md ├── ReleaseNotes.md ├── api │ └── .gitignore ├── build.ps1 ├── docfx.json ├── images │ ├── 00.png │ └── 22_4.png ├── index.md └── toc.yml ├── Fetch-Native.ps1 ├── Generator ├── Gen.fs └── Generator.fsproj ├── LICENSE ├── Native └── linux │ ├── genstub.sh │ └── libplplot.so ├── PLplotNet ├── NativeGenerated.cs ├── NativeHelpers.cs ├── NativeTmpl.cs ├── PLStream.cs ├── PLStreamGenerated.cs ├── PLplotNet.csproj └── Types.cs ├── README.md ├── Revision.targets ├── Samples ├── CSharp │ └── SineWaves │ │ ├── Program.cs │ │ └── SineWaves.csproj └── FSharp │ ├── DevList │ ├── DevList.fsproj │ └── Program.fs │ ├── GetOpts │ ├── GetOpts.fsproj │ └── Program.fs │ ├── x00 │ ├── Program.fs │ └── x00.fsproj │ └── x22 │ ├── Program.fs │ └── x22.fsproj ├── TODO ├── Upload-Docs.ps1 ├── appveyor.yml └── global.json /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | /Packages 4 | /Publish.sh 5 | /Native/windows 6 | Samples/CSharp/SineWaves/SineWaves.svg 7 | .vscode/launch.json 8 | Samples/CSharp/SineWaves/SineWaves.png 9 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "taskName": "build", 8 | "command": "dotnet build PLplotNet", 9 | "type": "shell", 10 | "group": "build", 11 | "presentation": { 12 | "reveal": "silent" 13 | }, 14 | "problemMatcher": "$msCompile", 15 | }, 16 | { 17 | "taskName": "generate", 18 | "command": "cd PLplotNet; dotnet run -p ../Generator ../../PLplot/doc/docbook/src", 19 | "type": "shell", 20 | "group": "build", 21 | "problemMatcher": "$msCompile" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /Docs/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # folder # 3 | ############### 4 | /**/DROP/ 5 | /**/TEMP/ 6 | /**/packages/ 7 | /**/bin/ 8 | /**/obj/ 9 | _site 10 | docfx/ 11 | 12 | -------------------------------------------------------------------------------- /Docs/Examples.md: -------------------------------------------------------------------------------- 1 | # PLplot examples 2 | 3 | ## Simple line plot 4 | 5 | The following code demonstrates how to create a simple line plot from F#. 6 | For an example using C#, please visit [see here](https://github.com/surban/PLplotNet/blob/master/Samples/CSharp/SineWaves/Program.cs). 7 | All PLplot operations are invoked through an instance of a [PLStream object](xref:PLplot.PLStream). 8 | 9 | ```fsharp 10 | open System 11 | open PLplot 12 | 13 | [] 14 | let main argv = 15 | // create PLplot stream 16 | use pl = new PLStream() 17 | 18 | // generate data 19 | let nsize = 101 20 | let xmin, xmax, ymin, ymax = 0., 1., 0., 100. 21 | let x, y = 22 | Array.init nsize (fun i -> 23 | let x = float i / float (nsize - 1) 24 | let y = ymax * x * x 25 | x, y) 26 | |> Array.unzip 27 | 28 | // Parse and process command line arguments. 29 | // This grabs PLplot-specific arguments, such as output device, from the 30 | // command line. 31 | let mutable argv = argv 32 | pl.parseopts( &argv, ParseOpts.Full ||| ParseOpts.NoProgram ) |> ignore 33 | 34 | // Initialize plplot 35 | pl.init() 36 | 37 | // Create a labelled box to hold the plot. 38 | pl.env( xmin, xmax, ymin, ymax, AxesScale.Independent, AxisBox.BoxTicksLabelsAxes ) 39 | pl.lab( "x", "y=100 x#u2#d", "Simple PLplot demo of a 2D line plot" ) 40 | 41 | // Plot the data that was prepared above. 42 | pl.line( x, y ) 43 | 44 | // PLplot is automatically closed when pl is disposed. 45 | 0 46 | ``` 47 | 48 | The project must reference the PLplot package. 49 | This can be done by executing the following command inside the project directory. 50 | 51 | ```dotnet add package PLplot``` 52 | 53 | When run, the above program produces the following output. 54 | 55 | ![Example plot](images/00.png) 56 | 57 | Don't worry, the colors can be customized easily using the [spal0 function](xref:PLplot.PLStream.spal0*). 58 | Read the [official guide](http://plplot.sourceforge.net/docbook-manual/plplot-html-5.13.0/color.html) for more information. 59 | 60 | ## More examples 61 | 62 | Further examples are located in the project repository at . 63 | 64 | The [native PLplot example gallery](http://plplot.sourceforge.net/examples.php) demonstrates all possible plot types the library has to offer. 65 | 66 | -------------------------------------------------------------------------------- /Docs/ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ##### 5.13.8 4 | * .NET Standard 2.1 Support 5 | 6 | ##### 5.13.7 7 | * MacOS support. 8 | 9 | ##### 5.13.6 10 | * Improved NuGet package. 11 | 12 | -------------------------------------------------------------------------------- /Docs/api/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # temp file # 3 | ############### 4 | *.yml 5 | .manifest 6 | -------------------------------------------------------------------------------- /Docs/build.ps1: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | $VERSION="2.35.4" 4 | 5 | $ErrorActionPreference="Stop" 6 | 7 | Push-Location $PSScriptRoot 8 | 9 | if (-not (Test-Path docfx)) { 10 | New-Item -ItemType Directory docfx 11 | Push-Location docfx 12 | Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile nuget.exe 13 | ./nuget.exe install docfx.console -ExcludeVersion -Version $VERSION 14 | ./nuget.exe install memberpage -ExcludeVersion -Version $VERSION 15 | Pop-Location 16 | } 17 | 18 | ./docfx/docfx.console/tools/docfx.exe 19 | 20 | Pop-Location 21 | -------------------------------------------------------------------------------- /Docs/docfx.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": [ 3 | { 4 | "src": [ 5 | { 6 | "src": "../", 7 | "files": [ 8 | "PLplotNet/PLplotNet.csproj" 9 | ] 10 | } 11 | ], 12 | "dest": "api", 13 | "disableGitFeatures": false 14 | } 15 | ], 16 | "build": { 17 | "content": [ 18 | { 19 | "files": [ 20 | "api/**.yml", 21 | "api/index.md" 22 | ] 23 | }, 24 | { 25 | "files": [ 26 | "articles/**.md", 27 | "articles/**/toc.yml", 28 | "toc.yml", 29 | "*.md" 30 | ] 31 | } 32 | ], 33 | "resource": [ 34 | { 35 | "files": [ 36 | "images/**" 37 | ] 38 | } 39 | ], 40 | "overwrite": [ 41 | { 42 | "files": [ 43 | "apidoc/**.md" 44 | ], 45 | "exclude": [ 46 | "obj/**", 47 | "_site/**" 48 | ] 49 | } 50 | ], 51 | "dest": "_site", 52 | "globalMetadataFiles": [], 53 | "fileMetadataFiles": [], 54 | "template": [ 55 | "default", 56 | "docfx/memberpage/content" 57 | ], 58 | "postProcessors": [], 59 | "markdownEngineName": "markdig", 60 | "noLangKeyword": false, 61 | "keepFileLink": false, 62 | "cleanupCacheHistory": false, 63 | "disableGitFeatures": false, 64 | "globalMetadata": { 65 | "_appTitle": "PLplot for .NET", 66 | "_enableSearch": true 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /Docs/images/00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surban/PLplotNet/1534defb4cef70dfc531b330d34a3964abb8ebb0/Docs/images/00.png -------------------------------------------------------------------------------- /Docs/images/22_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surban/PLplotNet/1534defb4cef70dfc531b330d34a3964abb8ebb0/Docs/images/22_4.png -------------------------------------------------------------------------------- /Docs/index.md: -------------------------------------------------------------------------------- 1 | # PLplot for .NET 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/byma2lmdgl54m3h9?svg=true)](https://ci.appveyor.com/project/surban/plplotnet) 4 | 5 | [PLplot](http://plplot.sourceforge.net/) is a cross-platform software package for creating scientific plots whose (UTF-8) plot symbols and text are limited in practice only by what Unicode-aware system fonts are installed on a user's computer. 6 | The open-source PLplot software is primarily licensed under the [LGPL](http://www.gnu.org/licenses/lgpl.html). 7 | 8 | The PLplot core library can be used to create standard x-y plots, semi-log plots, log-log plots, contour plots, 3D surface plots, mesh plots, bar charts and pie charts. Multiple graphs (of the same or different sizes) may be placed on a single page, and multiple pages are allowed for those device formats that support them. 9 | 10 | The following output file formats are supported: PDF, PNG, JPEG, PostScript. 11 | Supported operating systems: Linux, MacOS, Windows. 12 | 13 | [Click here to see a full gallery of PLplot's abilities.](http://plplot.sourceforge.net/examples.php) 14 | 15 | ![Example plot](images/22_4.png) 16 | 17 | ## .NET Standard 2.0 bindings 18 | 19 | This project provides a complete, but unofficial, .NET binding for PLplot. 20 | It allows you to use PLplot from C#, F#, Visual Basic or any other .NET language. 21 | We are targeting .NET Standard 2.0 and have tested the bindings on Linux, MacOS and Windows. 22 | 23 | The simplest way of installing the package is to run the following command from inside your project directory. 24 | 25 | ```dotnet add package PLplot``` 26 | 27 | Alternatively you can download the NuGet package from . 28 | 29 | ### Linux 30 | 31 | For Linux, PLplot must be pre-installed on your system, i.e. we are expecting to find `libplplot.so.15` in your `LD_LIBRARY_PATH`. 32 | Usually a recent package from your favorite distribution will work fine. 33 | On Ubuntu you can run the following command to install the necessary dependencies. 34 | 35 | ```sudo apt install libplplot15 plplot-driver-cairo``` 36 | 37 | ### MacOS 38 | 39 | On MacOS, PLplot must also be pre-installed on your system. 40 | We are expecting to find `libplplot.dylib` in your `LD_LIBRARY_PATH`. 41 | Using [Homebrew](https://brew.sh/) the necessary dependencies can be installed by running the following command. 42 | 43 | ```brew install plplot``` 44 | 45 | ### Windows 46 | 47 | The native libraries for Windows (x64) are included, so you don't have to worry about them. 48 | The only requirement is that the [Microsoft Visual C++ Redistributable 2017](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) is installed on your system. 49 | 50 | 51 | ## Documentation 52 | 53 | Check out [the introductory examples](Examples.md) to get started. 54 | 55 | The [official PLplot manual](http://plplot.sourceforge.net/docbook-manual/plplot-html-5.13.0/) explains how to use the library in great detail. 56 | All principles described therein also apply to the .NET library. 57 | 58 | We also provide [mostly complete reference documentation](xref:PLplot.PLStream). 59 | 60 | ## Source code 61 | 62 | Source code is available at . 63 | Please use GitHub to report trouble with the library and send me your pull request. 64 | 65 | ## Authors 66 | 67 | [Sebastian Urban](http://www.surban.net) (.NET bindings) 68 | [PLplot developers](http://plplot.sourceforge.net/credits.php) 69 | 70 | *** 71 | -------------------------------------------------------------------------------- /Docs/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Home 2 | href: index.md 3 | - name: Release Notes 4 | href: ReleaseNotes.md 5 | - name: Examples 6 | href: Examples.md 7 | - name: API Reference 8 | href: api/ 9 | homepage: xref:PLplot.PLStream 10 | -------------------------------------------------------------------------------- /Fetch-Native.ps1: -------------------------------------------------------------------------------- 1 | $NATIVE_SRC = "https://github.com/surban/PLplot/releases/download/b1/plplot_windows.zip" 2 | 3 | 4 | $ErrorActionPreference = "Stop" 5 | Invoke-WebRequest $NATIVE_SRC -OutFile windows.zip 6 | Expand-Archive windows.zip -DestinationPath "$PSScriptRoot/Native" -Force 7 | Remove-Item -Force windows.zip 8 | -------------------------------------------------------------------------------- /Generator/Gen.fs: -------------------------------------------------------------------------------- 1 |  2 | open System 3 | open System.Text.RegularExpressions 4 | open System.IO 5 | open System.Xml 6 | open Microsoft.CodeAnalysis 7 | open Microsoft.CodeAnalysis.Formatting 8 | open Microsoft.CodeAnalysis.CSharp 9 | open Microsoft.CodeAnalysis.CSharp.Syntax 10 | open Microsoft.CodeAnalysis.CSharp.Formatting 11 | open Microsoft.CodeAnalysis.Editing 12 | 13 | 14 | let skipStreamMethods = 15 | ["end"; "end1"; "mkstrm"; "sstrm"; "cpstrm"] 16 | |> Set.ofList 17 | 18 | 19 | type FunctionDoc = { 20 | Name: string 21 | Summary: string 22 | Remarks: string 23 | Parameters: Map 24 | } 25 | 26 | let readDocs xmlPath = 27 | // remove entitites and whitespace 28 | let text = File.ReadAllText(xmlPath) 29 | let text = Regex.Replace(text, "PLplot-website", "w", RegexOptions.Compiled) 30 | let text = Regex.Replace(text, "\&(\w+);", "$1", RegexOptions.Compiled) 31 | let text = Regex.Replace(text, "\s+", " ", RegexOptions.Compiled) 32 | let xml = new XmlDocument() 33 | xml.LoadXml(text) 34 | 35 | let mutable docs = Map.empty 36 | for sect in xml.SelectNodes("//sect1") do 37 | let funcNodes = sect.SelectNodes("./title/function") 38 | if funcNodes.Count > 0 then 39 | let pars = 40 | sect.SelectNodes("./variablelist/varlistentry") 41 | |> Seq.cast 42 | |> Seq.map (fun parEntry -> 43 | let parName = parEntry.SelectSingleNode("./term/parameter").InnerText.Trim() 44 | let parDesc = parEntry.SelectSingleNode("./listitem").InnerText.Trim() 45 | parName, parDesc) 46 | |> Map.ofSeq 47 | let funcName = funcNodes.[0].InnerText 48 | docs <- docs |> Map.add funcName {Name=funcName; 49 | Summary=sect.SelectSingleNode("./title").InnerText.Trim(); 50 | Remarks=sect.SelectNodes("./para").[1].InnerText.Trim(); 51 | Parameters=pars} 52 | docs 53 | 54 | 55 | type StreamGen () = 56 | let mutable cu = SyntaxFactory.CompilationUnit() 57 | let mutable ns = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName("PLplot")); 58 | let cl = SyntaxFactory.ClassDeclaration("PLStream") 59 | let mutable cl = cl.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword), 60 | SyntaxFactory.Token(SyntaxKind.PartialKeyword)) 61 | 62 | member this.AddUsing(ud: UsingDirectiveSyntax) = 63 | if ud.Alias = null then 64 | cu <- cu.AddUsings(ud) 65 | else 66 | ns <- ns.AddUsings(ud) 67 | 68 | member this.AddMethod(md: MethodDeclarationSyntax) = 69 | let name = md.Identifier.Text 70 | if not (name.StartsWith "_" || skipStreamMethods |> Set.contains name) then 71 | let lt = md.GetLeadingTrivia() 72 | let md = md.WithAttributeLists(SyntaxList()) 73 | let md = md.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword))) 74 | let newPars = 75 | md.ParameterList.Parameters 76 | |> Seq.map (fun par -> par.WithAttributeLists(SyntaxList())) 77 | |> SyntaxFactory.SeparatedList 78 | let parList = md.ParameterList.WithParameters newPars 79 | let md = md.WithParameterList parList 80 | 81 | let actStr = SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("ActivateStream")); 82 | let actStr = SyntaxFactory.ExpressionStatement(actStr) 83 | 84 | let args = 85 | newPars 86 | |> Seq.map (fun par -> 87 | let modf = if par.Modifiers.Any() then par.Modifiers.First() else SyntaxFactory.Token(SyntaxKind.None) 88 | SyntaxFactory.Argument(null, modf, SyntaxFactory.IdentifierName(par.Identifier))) 89 | |> SyntaxFactory.SeparatedList 90 | |> SyntaxFactory.ArgumentList 91 | let nativeCall = SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("Native." + name)) 92 | let nativeCall = nativeCall.WithArgumentList args 93 | let nativeCall = 94 | if md.ReturnType.ToFullString().Trim() = "void" then 95 | SyntaxFactory.ExpressionStatement(nativeCall) :> StatementSyntax 96 | else 97 | SyntaxFactory.ReturnStatement(nativeCall) :> StatementSyntax 98 | 99 | let execBlock = SyntaxFactory.Block(actStr, nativeCall) 100 | let lockLib = SyntaxFactory.LockStatement(SyntaxFactory.IdentifierName("libLock"), execBlock); 101 | 102 | //SyntaxFactory.Token(SyntaxKind.None) 103 | let md = md.WithBody(SyntaxFactory.Block(lockLib)).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None)) 104 | let md = md.WithLeadingTrivia(lt) 105 | cl <- cl.AddMembers(md) 106 | 107 | member this.Finish() = 108 | let ns = ns.AddMembers(cl) 109 | let cu = cu.AddMembers(ns) 110 | cu :> SyntaxNode 111 | 112 | 113 | 114 | type DocRewriter (docs: Map, sg: StreamGen) = 115 | inherit CSharpSyntaxRewriter() 116 | override this.VisitUsingDirective (ud) = 117 | sg.AddUsing(ud) 118 | ud :> SyntaxNode 119 | 120 | override this.VisitMethodDeclaration (md) = 121 | let func = md.Identifier.Text 122 | let plFunc = 123 | match func with 124 | | _ when func.StartsWith("pl") -> func 125 | | _ when func.StartsWith("setcontlabel") -> "pl_" + func 126 | | _ -> "pl" + func 127 | match docs |> Map.tryFind plFunc with 128 | | Some doc -> 129 | let availPars = 130 | md.ParameterList.Parameters 131 | |> Seq.map (fun p -> p.Identifier.Text) 132 | |> Set.ofSeq 133 | let paramSyn = 134 | doc.Parameters 135 | |> Map.toList 136 | |> List.collect (fun (name, desc) -> 137 | if availPars |> Set.contains name then 138 | [SyntaxFactory.XmlParamElement(name, SyntaxFactory.XmlText desc) :> XmlNodeSyntax; 139 | SyntaxFactory.XmlNewLine("\n") :> XmlNodeSyntax] 140 | else []) 141 | let content = 142 | [SyntaxFactory.XmlSummaryElement(SyntaxFactory.XmlText doc.Summary) :> XmlNodeSyntax; 143 | SyntaxFactory.XmlNewLine("\n") :> XmlNodeSyntax] 144 | @ paramSyn 145 | @ [SyntaxFactory.XmlRemarksElement(SyntaxFactory.XmlText doc.Remarks) :> XmlNodeSyntax] 146 | |> Seq.toArray 147 | let docSyn = SyntaxFactory.DocumentationComment(content) 148 | 149 | let md = 150 | if md.GetLeadingTrivia().ToFullString().Contains("///") then md 151 | else md.WithLeadingTrivia( 152 | SyntaxFactory.TriviaList( 153 | SyntaxFactory.CarriageReturnLineFeed, 154 | SyntaxFactory.Trivia(docSyn), 155 | SyntaxFactory.CarriageReturnLineFeed)) 156 | sg.AddMethod md 157 | md :> SyntaxNode 158 | | None -> 159 | printfn "No documentation found for %s" plFunc 160 | let lt = md.GetLeadingTrivia() 161 | let docs = 162 | [for trv in lt do 163 | if trv.IsKind(SyntaxKind.SingleLineCommentTrivia) then 164 | yield trv.ToFullString().Replace("//", "").Trim()] 165 | |> String.concat " " 166 | if docs.Length > 0 then 167 | let st = SyntaxTrivia() 168 | let doc = 169 | SyntaxFactory.DocumentationComment( 170 | SyntaxFactory.XmlSummaryElement(SyntaxFactory.XmlText(docs)) 171 | ) 172 | let md = 173 | md.WithLeadingTrivia( 174 | SyntaxFactory.TriviaList( 175 | SyntaxFactory.CarriageReturnLineFeed, 176 | SyntaxFactory.Trivia(doc), 177 | SyntaxFactory.CarriageReturnLineFeed)) 178 | sg.AddMethod md 179 | md :> SyntaxNode 180 | else 181 | sg.AddMethod md 182 | md :> SyntaxNode 183 | 184 | 185 | [] 186 | let main argv = 187 | printfn "generating in %s" (Directory.GetCurrentDirectory()) 188 | let srcPath = "." 189 | 190 | if argv.Length = 0 then 191 | printfn "specify path to plplot doc directory, e.g. /home/user/plplot/doc/docbook/src" 192 | exit 1 193 | 194 | let docPath = argv.[0] 195 | let apiDocs = readDocs (Path.Combine (docPath, "api.xml")) 196 | let cDocs = readDocs (Path.Combine (docPath, "api-c.xml")) 197 | let docs = (Map.toList apiDocs) @ (Map.toList cDocs) |> Map.ofList 198 | 199 | use workspace = new AdhocWorkspace() 200 | let generator = SyntaxGenerator.GetGenerator(workspace, LanguageNames.CSharp); 201 | 202 | let nativeTmplSrc = Text.SourceText.From(File.ReadAllText(Path.Combine(srcPath, "NativeTmpl.cs"))) 203 | let nativeTmpl = CSharpSyntaxTree.ParseText(nativeTmplSrc) 204 | 205 | let streamGenerator = StreamGen () 206 | let rewriter = DocRewriter (docs, streamGenerator) 207 | let nativeGen = rewriter.Visit(nativeTmpl.GetRoot()) 208 | let streamGen = streamGenerator.Finish() 209 | 210 | let nativeGenSrc = Formatter.Format(nativeGen, workspace) 211 | File.WriteAllText(Path.Combine(srcPath, "NativeGenerated.cs"), nativeGenSrc.ToFullString()) 212 | 213 | let streamGenSrc = Formatter.Format(streamGen, workspace) 214 | File.WriteAllText(Path.Combine(srcPath, "PLStreamGenerated.cs"), streamGenSrc.ToFullString()) 215 | 216 | 0 217 | 218 | -------------------------------------------------------------------------------- /Generator/Generator.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Exe 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LIBRARY GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1991 Free Software Foundation, Inc. 5 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the library GPL. It is 10 | numbered 2 because it goes with version 2 of the ordinary GPL.] 11 | 12 | Preamble 13 | 14 | The licenses for most software are designed to take away your 15 | freedom to share and change it. By contrast, the GNU General Public 16 | Licenses are intended to guarantee your freedom to share and change 17 | free software--to make sure the software is free for all its users. 18 | 19 | This license, the Library General Public License, applies to some 20 | specially designated Free Software Foundation software, and to any 21 | other libraries whose authors decide to use it. You can use it for 22 | your libraries, too. 23 | 24 | When we speak of free software, we are referring to freedom, not 25 | price. Our General Public Licenses are designed to make sure that you 26 | have the freedom to distribute copies of free software (and charge for 27 | this service if you wish), that you receive source code or can get it 28 | if you want it, that you can change the software or use pieces of it 29 | in new free programs; and that you know you can do these things. 30 | 31 | To protect your rights, we need to make restrictions that forbid 32 | anyone to deny you these rights or to ask you to surrender the rights. 33 | These restrictions translate to certain responsibilities for you if 34 | you distribute copies of the library, or if you modify it. 35 | 36 | For example, if you distribute copies of the library, whether gratis 37 | or for a fee, you must give the recipients all the rights that we gave 38 | you. You must make sure that they, too, receive or can get the source 39 | code. If you link a program with the library, you must provide 40 | complete object files to the recipients so that they can relink them 41 | with the library, after making changes to the library and recompiling 42 | it. And you must show them these terms so they know their rights. 43 | 44 | Our method of protecting your rights has two steps: (1) copyright 45 | the library, and (2) offer you this license which gives you legal 46 | permission to copy, distribute and/or modify the library. 47 | 48 | Also, for each distributor's protection, we want to make certain 49 | that everyone understands that there is no warranty for this free 50 | library. If the library is modified by someone else and passed on, we 51 | want its recipients to know that what they have is not the original 52 | version, so that any problems introduced by others will not reflect on 53 | the original authors' reputations. 54 | 55 | Finally, any free program is threatened constantly by software 56 | patents. We wish to avoid the danger that companies distributing free 57 | software will individually obtain patent licenses, thus in effect 58 | transforming the program into proprietary software. To prevent this, 59 | we have made it clear that any patent must be licensed for everyone's 60 | free use or not licensed at all. 61 | 62 | Most GNU software, including some libraries, is covered by the ordinary 63 | GNU General Public License, which was designed for utility programs. This 64 | license, the GNU Library General Public License, applies to certain 65 | designated libraries. This license is quite different from the ordinary 66 | one; be sure to read it in full, and don't assume that anything in it is 67 | the same as in the ordinary license. 68 | 69 | The reason we have a separate public license for some libraries is that 70 | they blur the distinction we usually make between modifying or adding to a 71 | program and simply using it. Linking a program with a library, without 72 | changing the library, is in some sense simply using the library, and is 73 | analogous to running a utility program or application program. However, in 74 | a textual and legal sense, the linked executable is a combined work, a 75 | derivative of the original library, and the ordinary General Public License 76 | treats it as such. 77 | 78 | Because of this blurred distinction, using the ordinary General 79 | Public License for libraries did not effectively promote software 80 | sharing, because most developers did not use the libraries. We 81 | concluded that weaker conditions might promote sharing better. 82 | 83 | However, unrestricted linking of non-free programs would deprive the 84 | users of those programs of all benefit from the free status of the 85 | libraries themselves. This Library General Public License is intended to 86 | permit developers of non-free programs to use free libraries, while 87 | preserving your freedom as a user of such programs to change the free 88 | libraries that are incorporated in them. (We have not seen how to achieve 89 | this as regards changes in header files, but we have achieved it as regards 90 | changes in the actual functions of the Library.) The hope is that this 91 | will lead to faster development of free libraries. 92 | 93 | The precise terms and conditions for copying, distribution and 94 | modification follow. Pay close attention to the difference between a 95 | "work based on the library" and a "work that uses the library". The 96 | former contains code derived from the library, while the latter only 97 | works together with the library. 98 | 99 | Note that it is possible for a library to be covered by the ordinary 100 | General Public License rather than by this special one. 101 | 102 | GNU LIBRARY GENERAL PUBLIC LICENSE 103 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 104 | 105 | 0. This License Agreement applies to any software library which 106 | contains a notice placed by the copyright holder or other authorized 107 | party saying it may be distributed under the terms of this Library 108 | General Public License (also called "this License"). Each licensee is 109 | addressed as "you". 110 | 111 | A "library" means a collection of software functions and/or data 112 | prepared so as to be conveniently linked with application programs 113 | (which use some of those functions and data) to form executables. 114 | 115 | The "Library", below, refers to any such software library or work 116 | which has been distributed under these terms. A "work based on the 117 | Library" means either the Library or any derivative work under 118 | copyright law: that is to say, a work containing the Library or a 119 | portion of it, either verbatim or with modifications and/or translated 120 | straightforwardly into another language. (Hereinafter, translation is 121 | included without limitation in the term "modification".) 122 | 123 | "Source code" for a work means the preferred form of the work for 124 | making modifications to it. For a library, complete source code means 125 | all the source code for all modules it contains, plus any associated 126 | interface definition files, plus the scripts used to control compilation 127 | and installation of the library. 128 | 129 | Activities other than copying, distribution and modification are not 130 | covered by this License; they are outside its scope. The act of 131 | running a program using the Library is not restricted, and output from 132 | such a program is covered only if its contents constitute a work based 133 | on the Library (independent of the use of the Library in a tool for 134 | writing it). Whether that is true depends on what the Library does 135 | and what the program that uses the Library does. 136 | 137 | 1. You may copy and distribute verbatim copies of the Library's 138 | complete source code as you receive it, in any medium, provided that 139 | you conspicuously and appropriately publish on each copy an 140 | appropriate copyright notice and disclaimer of warranty; keep intact 141 | all the notices that refer to this License and to the absence of any 142 | warranty; and distribute a copy of this License along with the 143 | Library. 144 | 145 | You may charge a fee for the physical act of transferring a copy, 146 | and you may at your option offer warranty protection in exchange for a 147 | fee. 148 | 149 | 2. You may modify your copy or copies of the Library or any portion 150 | of it, thus forming a work based on the Library, and copy and 151 | distribute such modifications or work under the terms of Section 1 152 | above, provided that you also meet all of these conditions: 153 | 154 | a) The modified work must itself be a software library. 155 | 156 | b) You must cause the files modified to carry prominent notices 157 | stating that you changed the files and the date of any change. 158 | 159 | c) You must cause the whole of the work to be licensed at no 160 | charge to all third parties under the terms of this License. 161 | 162 | d) If a facility in the modified Library refers to a function or a 163 | table of data to be supplied by an application program that uses 164 | the facility, other than as an argument passed when the facility 165 | is invoked, then you must make a good faith effort to ensure that, 166 | in the event an application does not supply such function or 167 | table, the facility still operates, and performs whatever part of 168 | its purpose remains meaningful. 169 | 170 | (For example, a function in a library to compute square roots has 171 | a purpose that is entirely well-defined independent of the 172 | application. Therefore, Subsection 2d requires that any 173 | application-supplied function or table used by this function must 174 | be optional: if the application does not supply it, the square 175 | root function must still compute square roots.) 176 | 177 | These requirements apply to the modified work as a whole. If 178 | identifiable sections of that work are not derived from the Library, 179 | and can be reasonably considered independent and separate works in 180 | themselves, then this License, and its terms, do not apply to those 181 | sections when you distribute them as separate works. But when you 182 | distribute the same sections as part of a whole which is a work based 183 | on the Library, the distribution of the whole must be on the terms of 184 | this License, whose permissions for other licensees extend to the 185 | entire whole, and thus to each and every part regardless of who wrote 186 | it. 187 | 188 | Thus, it is not the intent of this section to claim rights or contest 189 | your rights to work written entirely by you; rather, the intent is to 190 | exercise the right to control the distribution of derivative or 191 | collective works based on the Library. 192 | 193 | In addition, mere aggregation of another work not based on the Library 194 | with the Library (or with a work based on the Library) on a volume of 195 | a storage or distribution medium does not bring the other work under 196 | the scope of this License. 197 | 198 | 3. You may opt to apply the terms of the ordinary GNU General Public 199 | License instead of this License to a given copy of the Library. To do 200 | this, you must alter all the notices that refer to this License, so 201 | that they refer to the ordinary GNU General Public License, version 2, 202 | instead of to this License. (If a newer version than version 2 of the 203 | ordinary GNU General Public License has appeared, then you can specify 204 | that version instead if you wish.) Do not make any other change in 205 | these notices. 206 | 207 | Once this change is made in a given copy, it is irreversible for 208 | that copy, so the ordinary GNU General Public License applies to all 209 | subsequent copies and derivative works made from that copy. 210 | 211 | This option is useful when you wish to copy part of the code of 212 | the Library into a program that is not a library. 213 | 214 | 4. You may copy and distribute the Library (or a portion or 215 | derivative of it, under Section 2) in object code or executable form 216 | under the terms of Sections 1 and 2 above provided that you accompany 217 | it with the complete corresponding machine-readable source code, which 218 | must be distributed under the terms of Sections 1 and 2 above on a 219 | medium customarily used for software interchange. 220 | 221 | If distribution of object code is made by offering access to copy 222 | from a designated place, then offering equivalent access to copy the 223 | source code from the same place satisfies the requirement to 224 | distribute the source code, even though third parties are not 225 | compelled to copy the source along with the object code. 226 | 227 | 5. A program that contains no derivative of any portion of the 228 | Library, but is designed to work with the Library by being compiled or 229 | linked with it, is called a "work that uses the Library". Such a 230 | work, in isolation, is not a derivative work of the Library, and 231 | therefore falls outside the scope of this License. 232 | 233 | However, linking a "work that uses the Library" with the Library 234 | creates an executable that is a derivative of the Library (because it 235 | contains portions of the Library), rather than a "work that uses the 236 | library". The executable is therefore covered by this License. 237 | Section 6 states terms for distribution of such executables. 238 | 239 | When a "work that uses the Library" uses material from a header file 240 | that is part of the Library, the object code for the work may be a 241 | derivative work of the Library even though the source code is not. 242 | Whether this is true is especially significant if the work can be 243 | linked without the Library, or if the work is itself a library. The 244 | threshold for this to be true is not precisely defined by law. 245 | 246 | If such an object file uses only numerical parameters, data 247 | structure layouts and accessors, and small macros and small inline 248 | functions (ten lines or less in length), then the use of the object 249 | file is unrestricted, regardless of whether it is legally a derivative 250 | work. (Executables containing this object code plus portions of the 251 | Library will still fall under Section 6.) 252 | 253 | Otherwise, if the work is a derivative of the Library, you may 254 | distribute the object code for the work under the terms of Section 6. 255 | Any executables containing that work also fall under Section 6, 256 | whether or not they are linked directly with the Library itself. 257 | 258 | 6. As an exception to the Sections above, you may also compile or 259 | link a "work that uses the Library" with the Library to produce a 260 | work containing portions of the Library, and distribute that work 261 | under terms of your choice, provided that the terms permit 262 | modification of the work for the customer's own use and reverse 263 | engineering for debugging such modifications. 264 | 265 | You must give prominent notice with each copy of the work that the 266 | Library is used in it and that the Library and its use are covered by 267 | this License. You must supply a copy of this License. If the work 268 | during execution displays copyright notices, you must include the 269 | copyright notice for the Library among them, as well as a reference 270 | directing the user to the copy of this License. Also, you must do one 271 | of these things: 272 | 273 | a) Accompany the work with the complete corresponding 274 | machine-readable source code for the Library including whatever 275 | changes were used in the work (which must be distributed under 276 | Sections 1 and 2 above); and, if the work is an executable linked 277 | with the Library, with the complete machine-readable "work that 278 | uses the Library", as object code and/or source code, so that the 279 | user can modify the Library and then relink to produce a modified 280 | executable containing the modified Library. (It is understood 281 | that the user who changes the contents of definitions files in the 282 | Library will not necessarily be able to recompile the application 283 | to use the modified definitions.) 284 | 285 | b) Accompany the work with a written offer, valid for at 286 | least three years, to give the same user the materials 287 | specified in Subsection 6a, above, for a charge no more 288 | than the cost of performing this distribution. 289 | 290 | c) If distribution of the work is made by offering access to copy 291 | from a designated place, offer equivalent access to copy the above 292 | specified materials from the same place. 293 | 294 | d) Verify that the user has already received a copy of these 295 | materials or that you have already sent this user a copy. 296 | 297 | For an executable, the required form of the "work that uses the 298 | Library" must include any data and utility programs needed for 299 | reproducing the executable from it. However, as a special exception, 300 | the source code distributed need not include anything that is normally 301 | distributed (in either source or binary form) with the major 302 | components (compiler, kernel, and so on) of the operating system on 303 | which the executable runs, unless that component itself accompanies 304 | the executable. 305 | 306 | It may happen that this requirement contradicts the license 307 | restrictions of other proprietary libraries that do not normally 308 | accompany the operating system. Such a contradiction means you cannot 309 | use both them and the Library together in an executable that you 310 | distribute. 311 | 312 | 7. You may place library facilities that are a work based on the 313 | Library side-by-side in a single library together with other library 314 | facilities not covered by this License, and distribute such a combined 315 | library, provided that the separate distribution of the work based on 316 | the Library and of the other library facilities is otherwise 317 | permitted, and provided that you do these two things: 318 | 319 | a) Accompany the combined library with a copy of the same work 320 | based on the Library, uncombined with any other library 321 | facilities. This must be distributed under the terms of the 322 | Sections above. 323 | 324 | b) Give prominent notice with the combined library of the fact 325 | that part of it is a work based on the Library, and explaining 326 | where to find the accompanying uncombined form of the same work. 327 | 328 | 8. You may not copy, modify, sublicense, link with, or distribute 329 | the Library except as expressly provided under this License. Any 330 | attempt otherwise to copy, modify, sublicense, link with, or 331 | distribute the Library is void, and will automatically terminate your 332 | rights under this License. However, parties who have received copies, 333 | or rights, from you under this License will not have their licenses 334 | terminated so long as such parties remain in full compliance. 335 | 336 | 9. You are not required to accept this License, since you have not 337 | signed it. However, nothing else grants you permission to modify or 338 | distribute the Library or its derivative works. These actions are 339 | prohibited by law if you do not accept this License. Therefore, by 340 | modifying or distributing the Library (or any work based on the 341 | Library), you indicate your acceptance of this License to do so, and 342 | all its terms and conditions for copying, distributing or modifying 343 | the Library or works based on it. 344 | 345 | 10. Each time you redistribute the Library (or any work based on the 346 | Library), the recipient automatically receives a license from the 347 | original licensor to copy, distribute, link with or modify the Library 348 | subject to these terms and conditions. You may not impose any further 349 | restrictions on the recipients' exercise of the rights granted herein. 350 | You are not responsible for enforcing compliance by third parties to 351 | this License. 352 | 353 | 11. If, as a consequence of a court judgment or allegation of patent 354 | infringement or for any other reason (not limited to patent issues), 355 | conditions are imposed on you (whether by court order, agreement or 356 | otherwise) that contradict the conditions of this License, they do not 357 | excuse you from the conditions of this License. If you cannot 358 | distribute so as to satisfy simultaneously your obligations under this 359 | License and any other pertinent obligations, then as a consequence you 360 | may not distribute the Library at all. For example, if a patent 361 | license would not permit royalty-free redistribution of the Library by 362 | all those who receive copies directly or indirectly through you, then 363 | the only way you could satisfy both it and this License would be to 364 | refrain entirely from distribution of the Library. 365 | 366 | If any portion of this section is held invalid or unenforceable under any 367 | particular circumstance, the balance of the section is intended to apply, 368 | and the section as a whole is intended to apply in other circumstances. 369 | 370 | It is not the purpose of this section to induce you to infringe any 371 | patents or other property right claims or to contest validity of any 372 | such claims; this section has the sole purpose of protecting the 373 | integrity of the free software distribution system which is 374 | implemented by public license practices. Many people have made 375 | generous contributions to the wide range of software distributed 376 | through that system in reliance on consistent application of that 377 | system; it is up to the author/donor to decide if he or she is willing 378 | to distribute software through any other system and a licensee cannot 379 | impose that choice. 380 | 381 | This section is intended to make thoroughly clear what is believed to 382 | be a consequence of the rest of this License. 383 | 384 | 12. If the distribution and/or use of the Library is restricted in 385 | certain countries either by patents or by copyrighted interfaces, the 386 | original copyright holder who places the Library under this License may add 387 | an explicit geographical distribution limitation excluding those countries, 388 | so that distribution is permitted only in or among countries not thus 389 | excluded. In such case, this License incorporates the limitation as if 390 | written in the body of this License. 391 | 392 | 13. The Free Software Foundation may publish revised and/or new 393 | versions of the Library General Public License from time to time. 394 | Such new versions will be similar in spirit to the present version, 395 | but may differ in detail to address new problems or concerns. 396 | 397 | Each version is given a distinguishing version number. If the Library 398 | specifies a version number of this License which applies to it and 399 | "any later version", you have the option of following the terms and 400 | conditions either of that version or of any later version published by 401 | the Free Software Foundation. If the Library does not specify a 402 | license version number, you may choose any version ever published by 403 | the Free Software Foundation. 404 | 405 | 14. If you wish to incorporate parts of the Library into other free 406 | programs whose distribution conditions are incompatible with these, 407 | write to the author to ask for permission. For software which is 408 | copyrighted by the Free Software Foundation, write to the Free 409 | Software Foundation; we sometimes make exceptions for this. Our 410 | decision will be guided by the two goals of preserving the free status 411 | of all derivatives of our free software and of promoting the sharing 412 | and reuse of software generally. 413 | 414 | NO WARRANTY 415 | 416 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 417 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 418 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 419 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 420 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 421 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 422 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 423 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 424 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 425 | 426 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 427 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 428 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 429 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 430 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 431 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 432 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 433 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 434 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 435 | DAMAGES. 436 | 437 | END OF TERMS AND CONDITIONS 438 | 439 | How to Apply These Terms to Your New Libraries 440 | 441 | If you develop a new library, and you want it to be of the greatest 442 | possible use to the public, we recommend making it free software that 443 | everyone can redistribute and change. You can do so by permitting 444 | redistribution under these terms (or, alternatively, under the terms of the 445 | ordinary General Public License). 446 | 447 | To apply these terms, attach the following notices to the library. It is 448 | safest to attach them to the start of each source file to most effectively 449 | convey the exclusion of warranty; and each file should have at least the 450 | "copyright" line and a pointer to where the full notice is found. 451 | 452 | 453 | Copyright (C) 454 | 455 | This library is free software; you can redistribute it and/or 456 | modify it under the terms of the GNU Library General Public 457 | License as published by the Free Software Foundation; either 458 | version 2 of the License, or (at your option) any later version. 459 | 460 | This library is distributed in the hope that it will be useful, 461 | but WITHOUT ANY WARRANTY; without even the implied warranty of 462 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 463 | Library General Public License for more details. 464 | 465 | You should have received a copy of the GNU Library General Public 466 | License along with this library; if not, write to the Free Software 467 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA 468 | 469 | Also add information on how to contact you by electronic and paper mail. 470 | 471 | You should also get your employer (if you work as a programmer) or your 472 | school, if any, to sign a "copyright disclaimer" for the library, if 473 | necessary. Here is a sample; alter the names: 474 | 475 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 476 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 477 | 478 | , 1 April 1990 479 | Ty Coon, President of Vice 480 | 481 | That's all there is to it! 482 | -------------------------------------------------------------------------------- /Native/linux/genstub.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TARGET="libplplot.so.15" 4 | 5 | touch empty.c 6 | gcc -shared -o $TARGET empty.c 7 | gcc -Wl,--no-as-needed -shared -o libplplot.so -fPIC -L. -l:$TARGET 8 | rm -f $TARGET 9 | rm -f empty.c 10 | 11 | -------------------------------------------------------------------------------- /Native/linux/libplplot.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surban/PLplotNet/1534defb4cef70dfc531b330d34a3964abb8ebb0/Native/linux/libplplot.so -------------------------------------------------------------------------------- /PLplotNet/NativeHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using System.Text; 5 | using System.Runtime.InteropServices; 6 | using System.Linq; 7 | 8 | namespace PLplot 9 | { 10 | 11 | // type aliases 12 | using PLBOOL = Boolean; 13 | using PLCHAR = Char; 14 | using PLUTF8 = Byte; 15 | using PLINT = Int32; 16 | using PLFLT = Double; 17 | using PLUNICODE = UInt32; 18 | using PLPointer = IntPtr; 19 | using FILE = IntPtr; 20 | using PLUTF8_STRING = String; // 8-bit string in UTF8 encoding 21 | using PLCHAR_STRING = String; // 8-bit string in ANSI encoding 22 | using PLFLT_MATRIX = IntPtr; // input matrix 23 | using PLFLT_NC_MATRIX = IntPtr; // output matrix 24 | 25 | 26 | // Marshals a PLFLT[,] as a PLFLT_MATRIX 27 | internal class MatrixMarshaller : IDisposable 28 | { 29 | private GCHandle gcHnd; 30 | private IntPtr RowArray; 31 | private int nRows; 32 | private int nCols; 33 | 34 | public MatrixMarshaller (PLFLT[,] matrix) 35 | { 36 | nRows = matrix.GetLength(0); 37 | nCols = matrix.GetLength(1); 38 | 39 | gcHnd = GCHandle.Alloc(matrix, GCHandleType.Pinned); 40 | IntPtr basePtr = gcHnd.AddrOfPinnedObject(); 41 | 42 | RowArray = Marshal.AllocHGlobal(nRows * Marshal.SizeOf()); 43 | for (var row=0; row < nRows; row++) 44 | { 45 | Marshal.WriteIntPtr(RowArray, row * Marshal.SizeOf(), 46 | basePtr + row * nCols * Marshal.SizeOf()); 47 | } 48 | } 49 | 50 | void IDisposable.Dispose() 51 | { 52 | Marshal.FreeHGlobal(RowArray); 53 | gcHnd.Free(); 54 | } 55 | 56 | public PLFLT_MATRIX Ptr { 57 | get { return RowArray; } 58 | } 59 | 60 | public int NX { 61 | get { return nRows; } 62 | } 63 | 64 | public int NY { 65 | get { return nCols; } 66 | } 67 | } 68 | 69 | internal class TR1Marshaller 70 | { 71 | GCHandle gcXg, gcYg, gcG; 72 | PLPointer pltr_data; 73 | 74 | public TR1Marshaller(PLFLT[] xg, PLFLT[] yg) 75 | { 76 | if (xg.Length != yg.Length) 77 | throw new ArgumentException("argument arrays must have same dimensions"); 78 | 79 | gcXg = GCHandle.Alloc(xg, GCHandleType.Pinned); 80 | gcYg = GCHandle.Alloc(yg, GCHandleType.Pinned); 81 | 82 | _CGrid g; 83 | g.Xg = gcXg.AddrOfPinnedObject(); 84 | g.Yg = gcYg.AddrOfPinnedObject(); 85 | g.Zg = IntPtr.Zero; 86 | g.NX = xg.Length; 87 | g.NY = yg.Length; 88 | g.NZ = 0; 89 | 90 | gcG = GCHandle.Alloc(g, GCHandleType.Pinned); 91 | pltr_data = gcG.AddrOfPinnedObject(); 92 | } 93 | 94 | ~TR1Marshaller() 95 | { 96 | gcXg.Free(); 97 | gcYg.Free(); 98 | gcG.Free(); 99 | } 100 | 101 | private void _Func(PLFLT x, PLFLT y, out PLFLT tx, out PLFLT ty, PLPointer unused) 102 | { 103 | Native._tr1(x, y, out tx, out ty, pltr_data); 104 | } 105 | 106 | public TransformFunc Func 107 | { 108 | get 109 | { 110 | return new TransformFunc(_Func); 111 | } 112 | } 113 | } 114 | 115 | internal class TR2Marshaller 116 | { 117 | MatrixMarshaller mXg, mYg; 118 | GCHandle gcG; 119 | PLPointer pltr_data; 120 | 121 | public TR2Marshaller(PLFLT[,] xg, PLFLT[,] yg) 122 | { 123 | if (xg.GetLength(0) != yg.GetLength(0) || xg.GetLength(1) != yg.GetLength(1)) 124 | throw new ArgumentException("argument matrices must have same dimensions"); 125 | 126 | mXg = new MatrixMarshaller(xg); 127 | mYg = new MatrixMarshaller(yg); 128 | 129 | _CGrid2 g; 130 | g.Xg = mXg.Ptr; 131 | g.Yg = mYg.Ptr; 132 | g.Zg = IntPtr.Zero; 133 | g.NX = mXg.NX; 134 | g.NY = mXg.NY; 135 | 136 | gcG = GCHandle.Alloc(g, GCHandleType.Pinned); 137 | pltr_data = gcG.AddrOfPinnedObject(); 138 | } 139 | 140 | ~TR2Marshaller() 141 | { 142 | (mXg as IDisposable).Dispose(); 143 | (mYg as IDisposable).Dispose(); 144 | gcG.Free(); 145 | } 146 | 147 | private void _Func(PLFLT x, PLFLT y, out PLFLT tx, out PLFLT ty, PLPointer unused) 148 | { 149 | Native._tr2(x, y, out tx, out ty, pltr_data); 150 | } 151 | 152 | public TransformFunc Func 153 | { 154 | get 155 | { 156 | return new TransformFunc(_Func); 157 | } 158 | } 159 | } 160 | 161 | 162 | /// Native PLplot functions 163 | public static partial class Native 164 | { 165 | // library name 166 | const string DllName = "plplot"; 167 | 168 | const int MaxLength = 1024; 169 | 170 | static Native() 171 | { 172 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 173 | { 174 | // directory of library binary 175 | string libDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 176 | 177 | // The NuGet package ships with the PLplot DLLs and supporting font and 178 | // color map files. These files get installed into the directory "plplot", 179 | // either relative to the application main executable (if published), 180 | // or are located in the "runtimes/win-x64/native" folder of the NuGet package. 181 | // For PLplot to find its support files, the environment variable 182 | // PLPLOT_LIB must be set accordingly. 183 | string[] supPaths = { 184 | Path.Combine(libDir, "plplot"), 185 | Path.Combine(libDir, "runtimes", "win-x64", "native", "plplot") 186 | }; 187 | string supPath = supPaths.FirstOrDefault(p => Directory.Exists(p)); 188 | if (supPath != null) { 189 | // We have to call the CRT function _putenv to update the global _environ 190 | // variable of the C runtime, since it is only populated at the start of 191 | // the program and not updated from the Windows environment block. 192 | _putenv_s("PLPLOT_LIB", supPath); 193 | } else { 194 | throw new InvalidOperationException($"Cannot find support PLplot support files in {supPaths}."); 195 | } 196 | 197 | //Console.WriteLine("Set PATH={0}", newPath); 198 | //Console.WriteLine("Set PLPLOT_LIB={0}", supPath); 199 | } 200 | } 201 | 202 | [DllImport("API-MS-WIN-CRT-ENVIRONMENT-L1-1-0.DLL", EntryPoint="_putenv_s", CallingConvention=CallingConvention.Cdecl)] 203 | private static extern int _putenv_s([MarshalAs(UnmanagedType.LPStr)] string name, 204 | [MarshalAs(UnmanagedType.LPStr)] string value); 205 | 206 | private static void CheckRange(string param, PLINT minVal, PLINT smallerThan, PLINT value) 207 | { 208 | if (!(minVal <= value && value < smallerThan)) 209 | { 210 | var msg = String.Format("Argument {0} must be between {1} and {2}, but it is {3}.", 211 | param, minVal, smallerThan, value); 212 | throw new ArgumentOutOfRangeException(msg); 213 | } 214 | } 215 | 216 | private static PLINT GetSize(PLFLT[] x, PLFLT[] y) 217 | { 218 | if (x.Length != y.Length) 219 | throw new ArgumentException("argument arrays must have same length"); 220 | return x.Length; 221 | } 222 | 223 | private static PLINT GetSize(PLINT[] x, PLINT[] y) 224 | { 225 | if (x.Length != y.Length) 226 | throw new ArgumentException("argument arrays must have same length"); 227 | return x.Length; 228 | } 229 | 230 | private static PLINT GetSize(PLFLT[] x, PLFLT[] y, PLFLT[] z) 231 | { 232 | if (x.Length != y.Length || y.Length != z.Length) 233 | throw new ArgumentException("argument arrays must have same length"); 234 | return x.Length; 235 | } 236 | 237 | private static void CheckSize(PLFLT[,] x, PLFLT[,] y) 238 | { 239 | if (x.GetLength(0) != y.GetLength(0) || x.GetLength(1) != y.GetLength(1)) 240 | throw new ArgumentException("argument matrices must have same dimensions"); 241 | } 242 | 243 | private static void CheckSize(PLFLT[] x, PLFLT[] y, PLFLT[,] z) 244 | { 245 | if (x.Length != y.Length || x.Length != z.GetLength(0) || y.Length != z.GetLength(1)) 246 | throw new ArgumentException("argument arrays must have matching dimensions"); 247 | } 248 | 249 | private static PLINT GetSize(PLFLT[] x, PLFLT[] y, PLFLT[] z, PLFLT[] a) 250 | { 251 | if (x.Length != y.Length || y.Length != z.Length || z.Length != a.Length) 252 | throw new ArgumentException("argument arrays must have same length"); 253 | return x.Length; 254 | } 255 | 256 | private static PLINT GetSize(PLFLT[] x, PLFLT[] y, PLFLT[] z, PLFLT[] a, PLFLT[] b) 257 | { 258 | if (x.Length != y.Length || y.Length != z.Length || z.Length != a.Length || a.Length != b.Length) 259 | throw new ArgumentException("argument arrays must have same length"); 260 | return x.Length; 261 | } 262 | 263 | private static PLINT GetSize(PLINT[] x, PLINT[] y, PLINT[] z) 264 | { 265 | if (x.Length != y.Length || y.Length != z.Length) 266 | throw new ArgumentException("argument arrays must have same length"); 267 | return x.Length; 268 | } 269 | 270 | private static PLINT GetSize(PLINT[] x, PLINT[] y, PLINT[] z, PLFLT[] a) 271 | { 272 | if (x.Length != y.Length || y.Length != z.Length || z.Length != a.Length) 273 | throw new ArgumentException("argument arrays must have same length"); 274 | return x.Length; 275 | } 276 | 277 | private delegate void GetDevsFunc(ref IntPtr p_menustr, ref IntPtr p_devname, ref int p_ndev); 278 | 279 | private static void GetDevHelper(GetDevsFunc gd, out string[] p_menustr, out string[] p_devname) 280 | { 281 | int ndevs = 100; 282 | IntPtr menustrs = Marshal.AllocHGlobal(ndevs * Marshal.SizeOf()); 283 | IntPtr devnames = Marshal.AllocHGlobal(ndevs * Marshal.SizeOf()); 284 | gd(ref menustrs, ref devnames, ref ndevs); 285 | 286 | p_menustr = new string[ndevs]; 287 | p_devname = new string[ndevs]; 288 | for (int dev=0; dev < ndevs; dev++) 289 | { 290 | p_menustr[dev] = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(menustrs + dev * Marshal.SizeOf())); 291 | p_devname[dev] = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(devnames + dev * Marshal.SizeOf())); 292 | } 293 | 294 | Marshal.FreeHGlobal(menustrs); 295 | Marshal.FreeHGlobal(devnames); 296 | } 297 | 298 | } 299 | } 300 | -------------------------------------------------------------------------------- /PLplotNet/PLStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace PLplot 5 | { 6 | 7 | /// A PLplot stream. 8 | /// 9 | /// A new PLplot stream is created when this class is instantiated. 10 | /// The PLplot stream is ended when the instance is disposed. 11 | /// An instance is thread-safe, however all calls from all 12 | /// instances are serialized. 13 | /// 14 | public partial class PLStream : IDisposable 15 | { 16 | static object libLock = new object(); 17 | int streamId = -1; 18 | bool disposed = false; 19 | 20 | /// Creates a new PLplot stream. 21 | public PLStream() 22 | { 23 | Native.mkstrm(out streamId); 24 | if (streamId < 0) 25 | throw new SystemException("cannot create PLplot stream"); 26 | } 27 | 28 | /// Ends the PLplot stream. 29 | ~PLStream() 30 | { 31 | if (!disposed) 32 | (this as IDisposable).Dispose(); 33 | } 34 | 35 | /// Ends the PLplot stream. 36 | void IDisposable.Dispose() 37 | { 38 | EndStream(); 39 | disposed = true; 40 | } 41 | 42 | /// The stream id of this stream as returned by plgstrm(). 43 | public int Id 44 | { 45 | get 46 | { 47 | if (disposed) 48 | throw new ObjectDisposedException("PLplot stream was disposed"); 49 | if (streamId < 0) 50 | throw new SystemException("PLplot stream has ended"); 51 | return streamId; 52 | } 53 | } 54 | 55 | public override string ToString() 56 | { 57 | return String.Format("PLplot stream {0}", streamId); 58 | } 59 | 60 | private void ActivateStream() 61 | { 62 | Native.sstrm(Id); 63 | } 64 | 65 | private void EndStream() 66 | { 67 | lock (libLock) 68 | { 69 | if (streamId >= 0) 70 | { 71 | ActivateStream(); 72 | Native.end1(); 73 | streamId = -1; 74 | } 75 | } 76 | } 77 | 78 | /// plcpstrm: Copy state parameters from the reference stream to the current stream 79 | /// Reference stream. 80 | /// If flags is set to true the device coordinates are not copied from the reference to current stream. 81 | /// Copies state parameters from the reference stream to the current stream. 82 | /// Tell driver interface to map device coordinates unless flags == 1. 83 | /// 84 | /// This function is used for making save files of selected plots (e.g. from the TK driver). 85 | /// After initializing, you can get a copy of the current plot to the specified device by switching to 86 | /// this stream and issuing a plcpstrm and a plreplot, with calls to plbop and pleop as appropriate. 87 | /// The plot buffer must have previously been enabled (done automatically by some display drivers, such as X). 88 | /// 89 | public void cpstrm(PLStream iplsr, bool flags) 90 | { 91 | lock (libLock) 92 | { 93 | ActivateStream(); 94 | Native.cpstrm(iplsr.Id, flags); 95 | } 96 | } 97 | 98 | } 99 | 100 | } -------------------------------------------------------------------------------- /PLplotNet/PLplotNet.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | netstandard2.1 6 | False 7 | x64 8 | 9 | PLplot 10 | PLplotNet 11 | true 12 | true 13 | true 14 | embedded 15 | true 16 | 1587;1573;1591 17 | 18 | PLplot 19 | PLplot cross-plattform scientific plotting library 20 | 21 | PLplot is a cross-platform software package for creating scientific plots 22 | whose (UTF-8) plot symbols and text are limited in practice only by what 23 | Unicode-aware system fonts are installed on a user's computer. 24 | 25 | The PLplot core library can be used to create standard x-y plots, 26 | semi-log plots, log-log plots, contour plots, 3D surface plots, mesh plots, 27 | bar charts and pie charts. Multiple graphs (of the same or different sizes) 28 | may be placed on a single page, and multiple pages are allowed for those 29 | device formats that support them. 30 | 31 | The native PLplot library for Windows (x64) is included in this package. 32 | For Linux and MacOS, PLplot must be already installed on your system and 33 | we expect to find libplplot.so.15 or libplplot.dylib in your LD_LIBRARY_PATH. 34 | 35 | Supported operating systems: Linux, MacOS, Windows 36 | Output file formats: PDF, PNG, SVG, Xfig and others 37 | 38 | Documentation: https://surban.github.io/PLplotNet 39 | Plot gallery: http://plplot.sourceforge.net/examples.php 40 | 41 | Sebastian Urban, PLplot developer community 42 | Sebastian Urban, PLplot developer community 43 | Sebastian Urban 44 | Copyright (C) 2017-2018 Sebastian Urban, PLplot developer community 45 | false 46 | https://www.gnu.org/licenses/old-licenses/lgpl-2.0.en.html 47 | https://surban.github.io/PLplotNet 48 | plplot plot plotting scientific pdf png svg xfig 49 | ../Packages/$(Configuration)/ 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | %(FileName)%(Extension) 61 | PreserveNewest 62 | 63 | 64 | plplot/%(FileName)%(Extension) 65 | PreserveNewest 66 | 67 | 68 | %(FileName)%(Extension) 69 | PreserveNewest 70 | 71 | 72 | -------------------------------------------------------------------------------- /PLplotNet/Types.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Runtime.InteropServices; 4 | 5 | 6 | 7 | namespace PLplot 8 | { 9 | // type aliases 10 | using PLBOOL = Boolean; 11 | using PLCHAR = Char; 12 | using PLUTF8 = Byte; 13 | using PLINT = Int32; 14 | using PLFLT = Double; 15 | using PLUNICODE = UInt32; 16 | using PLPointer = IntPtr; 17 | using FILE = IntPtr; 18 | using PLUTF8_STRING = String; // 8-bit string in UTF8 encoding 19 | using PLCHAR_STRING = String; // 8-bit string in ANSI encoding 20 | using PLFLT_MATRIX = IntPtr; // input matrix 21 | using PLFLT_NC_MATRIX = IntPtr; // output matrix 22 | 23 | 24 | /// Run level of PLplot. 25 | public enum RunLevel : PLINT 26 | { 27 | /// Uninitialized 28 | Uninitialized = 0, 29 | /// Initialized 30 | Initialized = 1, 31 | /// Viewport has been defined 32 | ViewportDefined = 2, 33 | /// Viewport and world coordinates have been defined defined 34 | WorldCoordinatesDefined = 3 35 | } 36 | 37 | /// Command line parsing mode. 38 | [Flags] 39 | public enum ParseOpts : PLINT 40 | { 41 | /// Full parsing of command line and all error messages enabled, including program exit when an error occurs. Anything on the command line that isn't recognized as a valid option or option argument is flagged as an error. 42 | Full = 0x0001, 43 | /// Turns off all output except in the case of errors. 44 | Quiet = 0x0002, 45 | /// Turns off deletion of processed arguments. 46 | NoDelete = 0x0004, 47 | /// Show invisible options 48 | ShowAll = 0x0008, 49 | /// Specified if argv[0] is NOT a pointer to the program name. 50 | NoProgram = 0x0020, 51 | /// Set if leading dash NOT required 52 | NoDash = 0x0040, 53 | /// Set to quietly skip over any unrecognized arguments. 54 | Skip = 0x0080 55 | } 56 | 57 | /// Predefined colors on default color map. 58 | public static class Color 59 | { 60 | /// Black 61 | public const PLINT Black = 0; 62 | /// Red 63 | public const PLINT Red = 1; 64 | /// Yellow 65 | public const PLINT Yellow = 2; 66 | /// Green 67 | public const PLINT Green = 3; 68 | /// Aquamarine 69 | public const PLINT Aquamarine = 4; 70 | /// Pink 71 | public const PLINT Pink = 5; 72 | /// Wheat 73 | public const PLINT Wheat = 6; 74 | /// Grey 75 | public const PLINT Grey = 7; 76 | /// Brown 77 | public const PLINT Brown = 8; 78 | /// Blue 79 | public const PLINT Blue = 9; 80 | /// BlueViolet 81 | public const PLINT BlueViolet = 10; 82 | /// Cyan 83 | public const PLINT Cyan = 11; 84 | /// Turquoise 85 | public const PLINT Turquoise = 12; 86 | /// Magenta 87 | public const PLINT Magenta = 13; 88 | /// Salmon 89 | public const PLINT Salmon = 14; 90 | /// White 91 | public const PLINT White = 15; 92 | } 93 | 94 | /// Symbols of plpoin, plsym and plstring. 95 | public static class Symbol 96 | { 97 | /// Box 98 | //public const char Box = (char)0; 99 | /// Dot 100 | public const char Dot = (char)1; 101 | /// Plus 102 | public const char Plus = (char)2; 103 | /// Multiply 104 | public const char Multiply = (char)3; 105 | /// Circle 106 | public const char Circle = (char)4; 107 | /// Times 108 | public const char Times = (char)5; 109 | /// Box 110 | public const char Box = (char)6; 111 | /// Triangle 112 | public const char Triangle = (char)7; 113 | /// Plus within circle 114 | public const char PlusCircle = (char)8; 115 | /// Dot within circle 116 | public const char DotCircle = (char)9; 117 | /// Filled box 118 | public const char FilledBox = (char)16; 119 | /// Bullet 120 | public const char Bullet = (char)17; 121 | /// Star 122 | public const char Star = (char)18; 123 | /// Left arrow 124 | public const char LeftArrow = (char)28; 125 | /// Right arrow 126 | public const char RightArrow = (char)29; 127 | /// Up arrow 128 | public const char UpArrow = (char)30; 129 | /// Down arrow 130 | public const char DownArrow = (char)31; 131 | } 132 | 133 | /// Options for an X-axis or Y-axis. 134 | public static class XYAxisOpt 135 | { 136 | /// No options. 137 | public const string None = ""; 138 | /// Draws axis, X-axis is horizontal line (y=0), and Y-axis is vertical line (x=0). 139 | public const string DrawAxis = "a"; 140 | /// Draws left (for Y-axis) edge of frame. 141 | public const string DrawLeft = "b"; 142 | /// Draws bottom (for X-axis) edge of frame. 143 | public const string DrawBottom = "b"; 144 | /// Draws top (for X-axis) edge of frame. 145 | public const string DrawTop = "c"; 146 | /// Draws right (for Y-axis) edge of frame. 147 | public const string DrawRight = "c"; 148 | /// Plot labels as date / time. Values are assumed to be seconds since the epoch (as used by gmtime). 149 | public const string DateTime = "d"; 150 | /// Always use fixed point numeric labels. 151 | public const string FixedPoint = "f"; 152 | /// Draws a grid at the major tick interval. 153 | public const string MajorGrid = "g"; 154 | /// Draws a grid at the minor tick interval. 155 | public const string MinorGrid = "h"; 156 | /// Inverts tick marks, so they are drawn outwards, rather than inwards. 157 | public const string InvertTickMarks = "i"; 158 | /// Labels axis logarithmically. This only affects the labels, not the data, and so it is necessary to compute the logarithms of data points before passing them to any of the drawing routines. 159 | public const string Log = "l"; 160 | /// Writes numeric labels at major tick intervals in the unconventional location (above box for X, right of box for Y). 161 | public const string UnconventionalLabels = "m"; 162 | /// Writes numeric labels at major tick intervals in the conventional location (below box for X, left of box for Y). 163 | public const string ConventionalLabels = "n"; 164 | /// Use custom labelling function to generate axis label text. The custom labelling function can be defined with the plslabelfunc command. 165 | public const string CustomLabels = "o"; 166 | /// Enables subticks between major ticks, only valid if t is also specified. 167 | public const string SubTicks = "s"; 168 | /// Draws major ticks. 169 | public const string MajorTicks = "t"; 170 | /// Draws left (for Y-axis) edge of frame without edge line. 171 | public const string DrawLeftWithoutEdgeLine = "u"; 172 | /// Draws bottom (for X-axis) edge of frame without edge line. 173 | public const string DrawBottomWithoutEdgeLine = "u"; 174 | /// Draws top (for X-axis) edge of frame without edge line. 175 | public const string DrawTopWithoutEdgeLine = "w"; 176 | /// Draws right (for Y-axis) edge of frame without edge line. 177 | public const string DrawRightWithoutEdgeLine = "w"; 178 | /// Draws major ticks (including the side effect of the numerical labels for the major ticks) except exclude drawing the major and minor tick marks. 179 | public const string MajorTicksWithoutMarks = "x"; 180 | /// Write numeric labels for the y axis parallel to the base of the graph, rather than parallel to the axis. 181 | public const string BaseParallelLabels = "v"; 182 | } 183 | 184 | /// Options for an Z-axis. 185 | public static class ZAxisOpt 186 | { 187 | /// No options. 188 | public const string None = ""; 189 | /// Draws z axis to the left of the surface plot. 190 | public const string DrawLeft = "b"; 191 | /// Draws z axis to the right of the surface plot. 192 | public const string DrawRight = "c"; 193 | /// Draws grid lines parallel to the x-y plane behind the figure. These lines are not drawn until after plot3d or plmesh are called because of the need for hidden line removal. 194 | public const string Grid = "d"; 195 | /// Plot labels as date / time. Values are assumed to be seconds since the epoch (as used by gmtime). 196 | public const string DateTime = "e"; 197 | /// Always use fixed point numeric labels. 198 | public const string FixedPoint = "f"; 199 | /// Inverts tick marks, so they are drawn outwards, rather than inwards. 200 | public const string InvertTickMarks = "i"; 201 | /// Labels axis logarithmically. This only affects the labels, not the data, and so it is necessary to compute the logarithms of data points before passing them to any of the drawing routines. 202 | public const string Log = "l"; 203 | /// Writes numeric labels at major tick intervals on the right-hand z axis. 204 | public const string RightHandLabels = "m"; 205 | /// Writes numeric labels at major tick intervals on the left-hand z axis. 206 | public const string LeftHandLabels = "n"; 207 | /// Use custom labelling function to generate axis label text. The custom labelling function can be defined with the plslabelfunc command. 208 | public const string CustomLabels = "o"; 209 | /// Enables subticks between major ticks, only valid if t is also specified. 210 | public const string SubTicks = "s"; 211 | /// Draws major ticks. 212 | public const string MajorTicks = "t"; 213 | /// If this is specified, the text label is written beside the left-hand axis. 214 | public const string LabelLeft = "u"; 215 | /// If this is specified, the text label is written beside the right-hand axis. 216 | public const string LabelRight = "v"; 217 | } 218 | 219 | /// The side of the viewport along which the text is to be written. 220 | public static class Side 221 | { 222 | /// Bottom of viewport, text written parallel to edge. 223 | public const string BottomParallel = "b"; 224 | /// Bottom of viewport, text written at right angles to edge. 225 | public const string BottomPerpendicular = "bv"; 226 | /// Left of viewport, text written parallel to edge. 227 | public const string LeftParallel = "l"; 228 | /// Left of viewport, text written at right angles to edge. 229 | public const string LeftPerpendicular = "lv"; 230 | /// Right of viewport, text written parallel to edge. 231 | public const string RightParallel = "r"; 232 | /// Right of viewport, text written at right angles to edge. 233 | public const string RightPerpendicular = "rv"; 234 | /// Top of viewport, text written parallel to edge. 235 | public const string TopParallel = "t"; 236 | /// Top of viewport, text written at right angles to edge. 237 | public const string TopPerpendicular = "tv"; 238 | } 239 | 240 | /// The side of the viewport along which the text is to be written. 241 | public static class Side3 242 | { 243 | /// Label the X axis. 244 | public const string XAxis = "x"; 245 | /// Label the Y axis. 246 | public const string YAxis = "y"; 247 | /// Label the Z axis. 248 | public const string ZAxis = "z"; 249 | /// Label the “primary” axis. For Z this is the leftmost Z axis. For X it is the axis that starts at y-min. For Y it is the axis that starts at x-min. 250 | public const string PrimaryAxis = "p"; 251 | /// Label the “secondary” axis. 252 | public const string SecondaryAxis = "s"; 253 | /// Draw the text perpendicular to the axis. 254 | public const string Perpendicular = "v"; 255 | } 256 | 257 | /// Font characterization integer flags and masks. 258 | [Flags] 259 | public enum FCI : PLUNICODE 260 | { 261 | /// Mark (must always be set for FCI) 262 | Mark = 0x80000000, 263 | /// Mask for font family 264 | FamilyMask = 0x00f, 265 | /// Flag for sans-serif font family 266 | FamilySans = 0x000, 267 | /// Flag for serif font family 268 | FamilySerif = 0x001, 269 | /// Flag for monospaced font family 270 | FamilyMono = 0x002, 271 | /// Flag for script font family 272 | FamilyScript = 0x003, 273 | /// Flag for symbol font family 274 | FamilySymbol = 0x004, 275 | /// Mask for font style 276 | StyleMask = 0x0f0, 277 | /// Flag for upright font style 278 | StyleUpright = 0x000, 279 | /// Flag for italic font style 280 | StyleItalic = 0x010, 281 | /// Flag for olique font style 282 | StyleOblique = 0x020, 283 | /// Mask for font weight 284 | WeightMask = 0xf00, 285 | /// Flag for medium font weight 286 | WeightMedium = 0x000, 287 | /// Flag for bold font weight 288 | WeightBold = 0x100, 289 | } 290 | 291 | /// Font flag 292 | public enum FontFlag : PLINT 293 | { 294 | /// Sans-serif font 295 | Sans = 1, 296 | /// Serif font 297 | Serif = 2, 298 | /// Italic font 299 | Italic = 3, 300 | /// Script font 301 | Script = 4 302 | } 303 | 304 | /// Font family 305 | public enum FontFamily : PLINT 306 | { 307 | /// Sans-serif 308 | Sans = 0, 309 | /// Serif 310 | Serif = 1, 311 | /// Monospaced 312 | Mono = 2, 313 | /// Script 314 | Script = 3, 315 | /// Symbol 316 | Symbol = 4 317 | } 318 | 319 | /// Font style 320 | public enum FontStyle : PLINT 321 | { 322 | /// Upright 323 | Upright = 0, 324 | /// Italic 325 | Italic = 1, 326 | /// Olique 327 | Oblique = 2 328 | } 329 | 330 | /// Font weight 331 | public enum FontWeight : PLINT 332 | { 333 | /// Medium 334 | Medium = 0, 335 | /// Bold 336 | Bold = 1 337 | } 338 | 339 | /// Option flags for plbin() 340 | [Flags] 341 | public enum Bin : PLINT 342 | { 343 | /// The x represent the lower bin boundaries, the outer bins are expanded to fill up the entire x-axis and bins of zero height are simply drawn. 344 | Default = 0x0, 345 | /// The bin boundaries are to be midway between the x values. If the values in x are equally spaced, the values are the center values of the bins. 346 | Centred = 0x1, 347 | /// The outer bins are drawn with equal size as the ones inside. 348 | NoExpand = 0x2, 349 | /// Bins with zero height are not drawn (there is a gap for such bins). 350 | NoEmpty = 0x4 351 | } 352 | 353 | /// Position flags for legend and colorbar. 354 | [Flags] 355 | public enum Position : PLINT 356 | { 357 | /// Left 358 | Left = 0x1, 359 | /// Right 360 | Right = 0x2, 361 | /// Top 362 | Top = 0x4, 363 | /// Bottom 364 | Bottom = 0x8, 365 | /// Inside plot 366 | Inside = 0x10, 367 | /// Outside plot 368 | Outside = 0x20, 369 | /// The adopted coordinates are normalized viewport coordinates. 370 | Viewport = 0x40, 371 | /// The adopted coordinates are normalized subpage coordinates. 372 | Subpage = 0x80 373 | } 374 | 375 | /// Option flags for a legend. 376 | [Flags] 377 | public enum Legend : PLINT 378 | { 379 | /// No flags 380 | None = 0x00, 381 | /// If set, put the text area on the left of the legend and the plotted area on the right. Otherwise, put the text area on the right of the legend and the plotted area on the left. 382 | TextLeft = 0x10, 383 | /// Plot a (semitransparent) background for the legend. 384 | Background = 0x20, 385 | /// Plot a bounding box for the legend 386 | BoundingBox = 0x40, 387 | /// If set, plot the resulting array of legend entries in row-major order. Otherwise, plot the legend entries in column-major order. 388 | RowMajor = 0x80, 389 | } 390 | 391 | /// Option flags for a legend entry. 392 | [Flags] 393 | public enum LegendEntry : PLINT 394 | { 395 | /// Entry is plotted with nothing in the plotted area. 396 | None = 0x1, 397 | /// Entry is plotted with colored box. 398 | ColorBox = 0x2, 399 | /// Entry is plotted with a line. 400 | Line = 0x4, 401 | /// Entry is plotted with a symbol. 402 | Symbol = 0x8 403 | } 404 | 405 | /// Option flags for colorbar. 406 | [Flags] 407 | public enum Colorbar : PLINT 408 | { 409 | /// Title is left 410 | TitleLeft = 0x1, 411 | /// Title is right 412 | TitleRight = 0x2, 413 | /// Title is at top 414 | TitleTop = 0x4, 415 | /// Title is at bottom 416 | TitleBottom = 0x8, 417 | /// Colorbar type is image 418 | Image = 0x10, 419 | /// Colorbar type is shade 420 | Shade = 0x20, 421 | /// Colorbar type is gradient 422 | Gradient = 0x40, 423 | /// No end-cap 424 | CapNone = 0x80, 425 | /// Low end-cap 426 | CapLow = 0x100, 427 | /// High end-cap 428 | CapHigh = 0x200, 429 | /// Any tick marks and tick labels will be placed at the breaks between shaded segments. 430 | ShadeLabel = 0x400, 431 | /// Direction of maximum value is right 432 | OrientRight = 0x800, 433 | /// Direction of maximum value is top 434 | OrientTop = 0x1000, 435 | /// Direction of maximum value is left 436 | OrientLeft = 0x2000, 437 | /// Direction of maximum value is bottom 438 | OrientBottom = 0x4000, 439 | /// Plot a (semitransparent) background for the color bar. 440 | Background = 0x8000, 441 | /// Plot a bounding box for the color bar. 442 | BoundingBox = 0x10000, 443 | } 444 | 445 | /// Option flags for colorbar label. 446 | public enum ColorbarLabel : PLINT 447 | { 448 | /// Label is ignored 449 | None = 0x0, 450 | /// Label is left 451 | Left = 0x1, 452 | /// Label is right 453 | Right = 0x2, 454 | /// Label is at top 455 | Top = 0x4, 456 | /// Label is at bottom 457 | Bottom = 0x8 458 | } 459 | 460 | /// Drawing mode 461 | public enum DrawMode : PLINT 462 | { 463 | /// Unknown 464 | Unknown = 0x0, 465 | /// Default 466 | Default = 0x1, 467 | /// Replace 468 | Replace = 0x2, 469 | /// Xor 470 | Xor = 0x4 471 | } 472 | 473 | /// Axis label tags 474 | public enum Axis : PLINT 475 | { 476 | /// X axis 477 | X = 1, 478 | /// Y axis 479 | Y = 2, 480 | /// Z axis 481 | Z = 3 482 | } 483 | 484 | /// Controls how the axes will be scaled 485 | public enum AxesScale : PLINT 486 | { 487 | /// The scales will not be set, the user must set up the scale before calling plenv using plsvpa, plvasp or other. 488 | NotSet = -1, 489 | /// The x and y axes are scaled independently to use as much of the screen as possible. 490 | Independent = 0, 491 | /// The scales of the x and y axes are made equal. 492 | Equal = 1, 493 | /// The axis of the x and y axes are made equal, and the plot box will be square. 494 | Square = 2 495 | } 496 | 497 | /// Controls drawing of the box around the plot: 498 | public enum AxisBox : PLINT 499 | { 500 | /// Draw no box, no tick marks, no numeric tick labels, no axes. 501 | Off = -2, 502 | /// Draw box only. 503 | Box = -1, 504 | /// Draw box, ticks, and numeric tick labels. 505 | BoxTicksLabels = 0, 506 | /// Draw box, ticks, and numeric tick labels, also draw coordinate axes at x=0 and y=0. 507 | BoxTicksLabelsAxes = 1, 508 | /// Draw box, ticks, and numeric tick labels, also draw a grid at major tick positions in both coordinates. 509 | BoxTicksLabelsAxesMajorGrid = 2, 510 | /// Draw box, ticks, and numeric tick labels, also draw a grid at minor tick positions in both coordinates. 511 | BoxTicksLabelsAxesMinorGrid = 3, 512 | /// Draw box, ticks, and numeric tick labels with logarithmic x tick marks. 513 | LogXBoxTicksLabels = 10, 514 | /// Draw box, ticks, and numeric tick labels, also draw coordinate axes at x=0 and y=0 with logarithmic x tick marks 515 | LogXBoxTicksLabelsAxes = 11, 516 | /// Draw box, ticks, and numeric tick labels, also draw a grid at major tick positions in both coordinates with logarithmic x tick marks. 517 | LogXBoxTicksLabelsAxesMajorGrid = 12, 518 | /// Draw box, ticks, and numeric tick labels, also draw a grid at minor tick positions in both coordinates with logarithmic x tick marks. 519 | LogXBoxTicksLabelsAxesMinorGrid = 13, 520 | /// Draw box, ticks, and numeric tick labels with logarithmic y tick marks. 521 | LogYBoxTicksLabels = 20, 522 | /// Draw box, ticks, and numeric tick labels, also draw coordinate axes at x=0 and y=0 with logarithmic y tick marks 523 | LogYBoxTicksLabelsAxes = 21, 524 | /// Draw box, ticks, and numeric tick labels, also draw a grid at major tick positions in both coordinates with logarithmic y tick marks. 525 | LogYBoxTicksLabelsAxesMajorGrid = 22, 526 | /// Draw box, ticks, and numeric tick labels, also draw a grid at minor tick positions in both coordinates with logarithmic y tick marks. 527 | LogYBoxTicksLabelsAxesMinorGrid = 23, 528 | /// Draw box, ticks, and numeric tick labels with logarithmic x and y tick marks. 529 | LogXYBoxTicksLabels = 30, 530 | /// Draw box, ticks, and numeric tick labels, also draw coordinate axes at x=0 and y=0 with logarithmic x and y tick marks 531 | LogXYBoxTicksLabelsAxes = 31, 532 | /// Draw box, ticks, and numeric tick labels, also draw a grid at major tick positions in both coordinates with logarithmic x and y tick marks. 533 | LogXYBoxTicksLabelsAxesMajorGrid = 32, 534 | /// Draw box, ticks, and numeric tick labels, also draw a grid at minor tick positions in both coordinates with logarithmic x and y tick marks. 535 | LogXYBoxTicksLabelsAxesMinorGrid = 33, 536 | /// Draw box, ticks, and numeric tick labels with date/time x labels. 537 | DateTimeXBoxTicksLabels = 40, 538 | /// Draw box, ticks, and numeric tick labels, also draw coordinate axes at x=0 and y=0 with date/time x labels 539 | DateTimeXBoxTicksLabelsAxes = 41, 540 | /// Draw box, ticks, and numeric tick labels, also draw a grid at major tick positions in both coordinates with date/time x labels. 541 | DateTimeXBoxTicksLabelsAxesMajorGrid = 42, 542 | /// Draw box, ticks, and numeric tick labels, also draw a grid at minor tick positions in both coordinates with date/time x labels. 543 | DateTimeXBoxTicksLabelsAxesMinorGrid = 43, 544 | /// Draw box, ticks, and numeric tick labels with date/time y labels. 545 | DateTimeYBoxTicksLabels = 50, 546 | /// Draw box, ticks, and numeric tick labels, also draw coordinate axes at x=0 and y=0 with date/time y labels 547 | DateTimeYBoxTicksLabelsAxes = 51, 548 | /// Draw box, ticks, and numeric tick labels, also draw a grid at major tick positions in both coordinates with date/time y labels. 549 | DateTimeYBoxTicksLabelsAxesMajorGrid = 52, 550 | /// Draw box, ticks, and numeric tick labels, also draw a grid at minor tick positions in both coordinates with date/time y labels. 551 | DateTimeYBoxTicksLabelsAxesMinorGrid = 53, 552 | /// Draw box, ticks, and numeric tick labels with date/time x and y labels. 553 | DateTimeXYBoxTicksLabels = 60, 554 | /// Draw box, ticks, and numeric tick labels, also draw coordinate axes at x=0 and y=0 with date/time x and y labels 555 | DateTimeXYBoxTicksLabelsAxes = 61, 556 | /// Draw box, ticks, and numeric tick labels, also draw a grid at major tick positions in both coordinates with date/time x and y labels. 557 | DateTimeXYBoxTicksLabelsAxesMajorGrid = 62, 558 | /// Draw box, ticks, and numeric tick labels, also draw a grid at minor tick positions in both coordinates with date/time x and y labels. 559 | DateTimeXYBoxTicksLabelsAxesMinorGrid = 63, 560 | /// Draw box, ticks, and numeric tick labels with custom x and y labels. 561 | CustomXYBoxTicksLabels = 70, 562 | /// Draw box, ticks, and numeric tick labels, also draw coordinate axes at x=0 and y=0 with custom x and y labels 563 | CustomXYBoxTicksLabelsAxes = 71, 564 | /// Draw box, ticks, and numeric tick labels, also draw a grid at major tick positions in both coordinates with custom x and y labels. 565 | CustomXYBoxTicksLabelsAxesMajorGrid = 72, 566 | /// Draw box, ticks, and numeric tick labels, also draw a grid at minor tick positions in both coordinates with custom x and y labels. 567 | CustomXYBoxTicksLabelsAxesMinorGrid = 73 568 | } 569 | 570 | /// Type of gridding algorithm for plgriddata() 571 | public enum Grid : PLINT 572 | { 573 | /// Bivariate Cubic Spline approximation 574 | CSA = 1, 575 | /// Delaunay Triangulation Linear Interpolation 576 | DTLI = 2, 577 | /// Natural Neighbors Interpolation 578 | NNI = 3, 579 | /// Nearest Neighbors Inverse Distance Weighted 580 | NNIDW = 4, 581 | /// Nearest Neighbors Linear Interpolation 582 | NNLI = 5, 583 | /// Nearest Neighbors Around Inverse Distance Weighted 584 | NNAIDW = 6 585 | } 586 | 587 | /// Line style 588 | public enum LineStyle : PLINT 589 | { 590 | /// Continous line 591 | Continuous = 1, 592 | /// short dashes followed by short gaps 593 | ShortDashesShortGaps = 2, 594 | /// long dashes followed by long gaps 595 | LongDashesLongGaps = 3, 596 | /// long dashes followed by short gaps 597 | LongDashesShortGaps = 4, 598 | /// short dashes followed by long gaps 599 | ShortDashesLongGaps = 5, 600 | /// line style 6 601 | Style6 = 6, 602 | /// line style 7 603 | Style7 = 7, 604 | /// line style 8 605 | Style8 = 8 606 | } 607 | 608 | /// Option flags for histogram 609 | [Flags] 610 | public enum Hist 611 | { 612 | /// The axes are automatically rescaled to fit the histogram data, the outer bins are expanded to fill up the entire x-axis, data outside the given extremes are assigned to the outer bins and bins of zero height are simply drawn. 613 | Default = 0x00, 614 | /// The existing axes are not rescaled to fit the histogram data, without this flag, plenv is called to set the world coordinates. 615 | NoScaling = 0x01, 616 | /// Data outside the given extremes are not taken into account. This option should probably be combined with opt=PL_HIST_NOEXPAND|..., so as to properly present the data. 617 | IgnoreOutliers = 0x02, 618 | /// The outer bins are drawn with equal size as the ones inside. 619 | NoExpand = 0x08, 620 | /// Bins with zero height are not drawn (there is a gap for such bins). 621 | NoEmpty = 0x10 622 | } 623 | 624 | /// Determines the way in which the surface is represented 625 | public enum Mesh : PLINT 626 | { 627 | /// Lines are drawn showing z as a function of x for each value of y[j]. 628 | LineX = 0x001, 629 | /// Lines are drawn showing z as a function of y for each value of x[i]. 630 | LineY = 0x002, 631 | /// Network of lines is drawn connecting points at which function is defined. 632 | LineXY = 0x003 633 | } 634 | 635 | /// Determines the way in which the surface is represented. 636 | [Flags] 637 | public enum MeshContour : PLINT 638 | { 639 | /// Lines are drawn showing z as a function of x for each value of y[j]. 640 | LineX = 0x001, 641 | /// Lines are drawn showing z as a function of y for each value of x[i]. 642 | LineY = 0x002, 643 | /// Network of lines is drawn connecting points at which function is defined. 644 | LineXY = 0x003, 645 | /// Each line in the mesh is colored according to the z value being plotted. The color is used from the current cmap1. 646 | MagColor = 0x004, 647 | /// A contour plot is drawn at the base XY plane using parameters nlevel and clevel. 648 | BaseCont = 0x008, 649 | /// Draws a curtain between the base XY plane and the borders of the plotted function. 650 | DrawSides = 0x040 651 | } 652 | 653 | /// Determines the way in which the surface is represented. 654 | [Flags] 655 | public enum Surf : PLINT 656 | { 657 | /// The surface is colored according to the value of Z; if MAG_COLOR is not used, then the surface is colored according to the intensity of the reflected light in the surface from a light source whose position is set using pllightsource. 658 | MagColor = 0x004, 659 | /// A contour plot is drawn at the base XY plane using parameters nlevel and clevel. 660 | BaseCont = 0x008, 661 | /// A contour plot is drawn at the surface plane using parameters nlevel and clevel. 662 | SurfCont = 0x020, 663 | /// draws a curtain between the base XY plane and the borders of the plotted function. 664 | DrawSides = 0x040, 665 | /// Network of lines is drawn connecting points at which function is defined. 666 | Faceted = 0x080 667 | } 668 | 669 | /// standard fill patterns 670 | public enum Pattern : PLINT 671 | { 672 | /// horizontal lines 673 | Horizontal = 1, 674 | /// vertical lines 675 | Vertical = 2, 676 | /// lines at 45 degrees 677 | Deg45 = 3, 678 | /// lines at -45 degrees 679 | DegMinus45 = 4, 680 | /// lines at 30 degrees 681 | Deg30 = 5, 682 | /// lines at -30 degrees 683 | DegMinus30 = 6, 684 | /// both vertical and horizontal lines 685 | HorizontalAndVertical = 7, 686 | /// lines at both 45 degrees and -45 degrees 687 | Deg45AndMinus45 = 8 688 | } 689 | 690 | /// Page orientation 691 | public enum Orientation : PLINT 692 | { 693 | /// landscape 694 | Landscape = 0, 695 | /// portrait 696 | Portrait = 1, 697 | /// upsidedown landscape 698 | FlippedLandscape = 2, 699 | /// upsidedown portrait 700 | FlippedPortrait = 3 701 | } 702 | 703 | /// Pen for strip chart 704 | public enum Pen : PLINT 705 | { 706 | /// Pen 0 707 | Pen0 = 0, 708 | /// Pen 1 709 | Pen1 = 1, 710 | /// Pen 2 711 | Pen2 = 2, 712 | /// Pen 3 713 | Pen3 = 3 714 | } 715 | 716 | /// Color space 717 | public enum ColorSpace : PLINT 718 | { 719 | /// HLS color space 720 | HLS = 0, 721 | /// RGB color space 722 | RGB = 1 723 | } 724 | 725 | /// Graphics input event state flags 726 | [Flags] 727 | public enum KeyButtonMask : uint 728 | { 729 | /// shift key 730 | Shift = 0x1, 731 | /// caps lock 732 | Caps = 0x2, 733 | /// control key 734 | Control = 0x4, 735 | /// alt key 736 | Alt = 0x8, 737 | /// num lock 738 | Num = 0x10, 739 | /// alt gr key 740 | AltGr = 0x20, 741 | /// windows key 742 | Win = 0x40, 743 | /// scroll lock 744 | Scroll = 0x80, 745 | /// mouse button 1 746 | Button1 = 0x100, 747 | /// mouse button 2 748 | Button2 = 0x200, 749 | /// mouse button 3 750 | Button3 = 0x400, 751 | /// mouse button 4 752 | Button4 = 0x800, 753 | /// mouse button 5 754 | Button5 = 0x1000 755 | } 756 | 757 | 758 | /// Data for the pltr1 function 759 | [StructLayout(LayoutKind.Sequential)] 760 | internal struct _CGrid 761 | { 762 | /// pointer to x array of floats 763 | public IntPtr Xg; 764 | /// pointer to y array of floats 765 | public IntPtr Yg; 766 | /// pointer to z array of floats 767 | public IntPtr Zg; 768 | /// number of x points 769 | public PLINT NX; 770 | /// number of y points 771 | public PLINT NY; 772 | /// number of z points 773 | public PLINT NZ; 774 | } 775 | 776 | /// Data for the pltr2 function (2d coordinate transformation arrays) 777 | [StructLayout(LayoutKind.Sequential, Pack=1)] 778 | internal struct _CGrid2 779 | { 780 | /// pointer to x matrix of floats 781 | public IntPtr Xg; 782 | /// pointer to y matrix of floats 783 | public IntPtr Yg; 784 | /// pointer to z matrix of floats 785 | public IntPtr Zg; 786 | /// number of x points 787 | public PLINT NX; 788 | /// number of y points 789 | public PLINT NY; 790 | } 791 | 792 | /// PLplot Graphics Input structure 793 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 794 | public struct GraphicsIn 795 | { 796 | /// event type (unused) 797 | int Type; 798 | /// key and button mask 799 | KeyButtonMask State; 800 | /// key selected 801 | uint KeySym; 802 | /// mouse button selected 803 | uint Button; 804 | /// Subwindow (or subpage / subplot) number. 805 | PLINT SubWindow; 806 | /// Translated ascii character string. 807 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 808 | string Str; 809 | /// Absolute X device coordinate of mouse pointer. 810 | int PX; 811 | /// Absolute Y device coordinate of mouse pointer. 812 | int PY; 813 | /// Relative X device coordinate of mouse pointer. 814 | PLFLT DX; 815 | /// Relative Y device coordinate of mouse pointer. 816 | PLFLT DY; 817 | /// World X coordinate of mouse pointer. 818 | PLFLT WX; 819 | /// World Y coordinate of mouse pointer. 820 | PLFLT WY; 821 | } 822 | 823 | /// A user supplied function to transform the original map data coordinates to a new coordinate system. 824 | /// Number of elements in the x and y vectors. 825 | /// original X coordinates that should be replaced by the corresponding plot X coordinates 826 | /// original Y coordinates that should be replaced by the corresponding plot Y coordinates 827 | public delegate void MapFunc(PLINT n, 828 | [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] PLFLT[] x, 829 | [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] PLFLT[] y); 830 | 831 | /// A callback function that defines the transformation between the zero-based indices of the matrix f and the world coordinates. 832 | /// x-position to be transformed. 833 | /// y-position to be transformed. 834 | /// transformed x-position 835 | /// transformed y-position 836 | /// Generic pointer to additional input data that may be required by the callback routine in order to implement the transformation. 837 | public delegate void TransformFunc(PLFLT x, PLFLT y, out PLFLT xp, out PLFLT yp, PLPointer data); 838 | 839 | /// Custom label generation function 840 | /// This indicates which axis a label is being requested for. 841 | /// This is the value along the axis which is being labelled. 842 | /// generated label 843 | /// maximum length of generated laben 844 | /// Generic pointer to additional input data that may be required by the callback routine in order to generate label. 845 | public delegate void LabelFunc(Axis axis, PLFLT value, 846 | [MarshalAs(UnmanagedType.LPStr, SizeParamIndex=3)] out string label, 847 | PLINT length, PLPointer data); 848 | 849 | /// A callback function that fills a region. 850 | /// Number of elements in the x and y vectors. 851 | /// Vector of x-coordinates of vertices. 852 | /// Vector of y-coordinates of vertices. 853 | public delegate void FillFunc(PLINT n, 854 | [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] PLFLT[] x, 855 | [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] PLFLT[] y); 856 | 857 | /// Callback function specifying the region that should be plotted in the shade plot 858 | /// x-coordinate to be tested for whether it is in the defined region. 859 | /// y-coordinate to be tested for whether it is in the defined region. 860 | /// true if within defined area, otherwise false. 861 | [return: MarshalAs(UnmanagedType.Bool)] 862 | public delegate PLBOOL DefinedFunc(PLFLT x, PLFLT y); 863 | 864 | // event handler delegates 865 | public delegate void KeyHandler([In] GraphicsIn evnt, PLPointer data, [MarshalAs(UnmanagedType.Bool)] out PLBOOL exit_eventloop); 866 | public delegate void ButtonHandler([In] GraphicsIn evnt, PLPointer data, [MarshalAs(UnmanagedType.Bool)] out PLBOOL exit_eventloop); 867 | public delegate void LocateHandler([In] GraphicsIn evnt, PLPointer data, [MarshalAs(UnmanagedType.Bool)] out PLBOOL locate_mode); 868 | public delegate void BopHandler(PLPointer bop_data, [MarshalAs(UnmanagedType.Bool)] out PLBOOL skip_driver_bop); 869 | public delegate void EopHandler(PLPointer eop_data, [MarshalAs(UnmanagedType.Bool)] out PLBOOL skip_driver_eop); 870 | public delegate int ExitHandler([In, MarshalAs(UnmanagedType.LPStr)] string msg); 871 | public delegate void AbortHandler([In, MarshalAs(UnmanagedType.LPStr)] string msg); 872 | 873 | } 874 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PLplot bindings for .NET Standard 2.0 2 | [![Build status](https://ci.appveyor.com/api/projects/status/byma2lmdgl54m3h9?svg=true)](https://ci.appveyor.com/project/surban/plplotnet) 3 | 4 | [PLplot](http://plplot.sourceforge.net/) is a cross-platform software package for creating scientific plots whose (UTF-8) plot symbols and text are limited in practice only by what Unicode-aware system fonts are installed on a user's computer. 5 | 6 | The PLplot core library can be used to create standard x-y plots, semi-log plots, log-log plots, contour plots, 3D surface plots, mesh plots, bar charts and pie charts. Multiple graphs (of the same or different sizes) may be placed on a single page, and multiple pages are allowed for those device formats that support them. 7 | 8 | Supported operating systems: Linux, MacOS, Windows 9 | 10 | Output File Formats: PDF, PNG, JPEG, PostScript 11 | 12 | ## .NET Standard 2.0 bindings 13 | 14 | This package provides a complete, but unofficial, .NET binding for PLplot. 15 | 16 | Documentation is available at . 17 | 18 | Obtain the NuGet package from . 19 | 20 | ## Usage 21 | 22 | Create a `PLPlot.PLStream` object and call its instance methods. 23 | 24 | See the examples in the `Samples` folder for more information. 25 | -------------------------------------------------------------------------------- /Revision.targets: -------------------------------------------------------------------------------- 1 | 5.13.8 2 | -------------------------------------------------------------------------------- /Samples/CSharp/SineWaves/Program.cs: -------------------------------------------------------------------------------- 1 | using PLplot; 2 | using System; 3 | using System.Reflection; 4 | 5 | namespace SineWaves 6 | { 7 | internal static class Program 8 | { 9 | private static void Main(string[] args) 10 | { 11 | // generate data for plotting 12 | const double sineFactor = 0.012585; 13 | const int exampleCount = 1000; 14 | var phaseOffset = 125; 15 | 16 | var x0 = new double[exampleCount]; 17 | var y0 = new double[exampleCount]; 18 | 19 | for (var j = 0; j < exampleCount; j++) 20 | { 21 | x0[j] = j; 22 | y0[j] = (double)(System.Math.Sin(sineFactor * (j + phaseOffset)) * 1); 23 | } 24 | 25 | var x1 = new double[exampleCount]; 26 | var y1 = new double[exampleCount]; 27 | phaseOffset = 250; 28 | 29 | for (var j = 0; j < exampleCount; j++) 30 | { 31 | x1[j] = j; 32 | y1[j] = (double)(System.Math.Sin(sineFactor * (j + phaseOffset)) * 1); 33 | } 34 | 35 | var x2 = new double[exampleCount]; 36 | var y2 = new double[exampleCount]; 37 | phaseOffset = 375; 38 | 39 | for (var j = 0; j < exampleCount; j++) 40 | { 41 | x2[j] = j; 42 | y2[j] = (double)(System.Math.Sin(sineFactor * (j + phaseOffset)) * 1); 43 | } 44 | 45 | var x3 = new double[exampleCount]; 46 | var y3 = new double[exampleCount]; 47 | phaseOffset = 500; 48 | 49 | for (var j = 0; j < exampleCount; j++) 50 | { 51 | x3[j] = j; 52 | y3[j] = (double)(System.Math.Sin(sineFactor * (j + phaseOffset)) * 1); 53 | } 54 | 55 | // create PLplot object 56 | var pl = new PLStream(); 57 | 58 | // use SVG backend and write to SineWaves.svg in current directory 59 | if (args.Length == 1 && args[0] == "svg") 60 | { 61 | pl.sdev("svg"); 62 | pl.sfnam("SineWaves.svg"); 63 | } 64 | else 65 | { 66 | pl.sdev("pngcairo"); 67 | pl.sfnam("SineWaves.png"); 68 | } 69 | 70 | // use white background with black foreground 71 | pl.spal0("cmap0_alternate.pal"); 72 | 73 | // Initialize plplot 74 | pl.init(); 75 | 76 | // set axis limits 77 | const int xMin = 0; 78 | const int xMax = 1000; 79 | const int yMin = -1; 80 | const int yMax = 1; 81 | pl.env(xMin, xMax, yMin, yMax, AxesScale.Independent, AxisBox.BoxTicksLabelsAxes); 82 | 83 | // Set scaling for mail title text 125% size of default 84 | pl.schr(0, 1.25); 85 | 86 | // The main title 87 | pl.lab("X", "Y", "PLplot demo of four sine waves"); 88 | 89 | // plot using different colors 90 | // see http://plplot.sourceforge.net/examples.php?demo=02 for palette indices 91 | pl.col0(9); 92 | pl.line(x0, y0); 93 | pl.col0(1); 94 | pl.line(x1, y1); 95 | pl.col0(2); 96 | pl.line(x2, y2); 97 | pl.col0(4); 98 | pl.line(x3, y3); 99 | 100 | // end page (writes output to disk) 101 | pl.eop(); 102 | 103 | // output version 104 | pl.gver(out var verText); 105 | Console.WriteLine("PLplot version " + verText); 106 | } 107 | 108 | } 109 | 110 | } -------------------------------------------------------------------------------- /Samples/CSharp/SineWaves/SineWaves.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Exe 9 | net5.0 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Samples/FSharp/DevList/DevList.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Samples/FSharp/DevList/Program.fs: -------------------------------------------------------------------------------- 1 | open System 2 | open PLplot 3 | 4 | 5 | [] 6 | let main argv = 7 | 8 | use pl = new PLStream() 9 | 10 | let mutable titles = Array.empty 11 | let mutable devs = Array.empty 12 | pl.gDevs(&titles, &devs) 13 | 14 | printfn "PLplot available devices" 15 | printfn "========================" 16 | for title, dev in Array.zip titles devs do 17 | printfn "%s: %s" dev title 18 | 19 | 0 20 | -------------------------------------------------------------------------------- /Samples/FSharp/GetOpts/GetOpts.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Samples/FSharp/GetOpts/Program.fs: -------------------------------------------------------------------------------- 1 | open System 2 | open PLplot 3 | 4 | 5 | [] 6 | let main argv = 7 | use pl = new PLStream() 8 | let mutable argv = argv 9 | 10 | printfn "before parseopts: %A" argv 11 | pl.parseopts(&argv, ParseOpts.Full ||| ParseOpts.NoProgram) |> ignore 12 | printfn "after parseopts: %A" argv 13 | 14 | 0 15 | -------------------------------------------------------------------------------- /Samples/FSharp/x00/Program.fs: -------------------------------------------------------------------------------- 1 | open System 2 | open PLplot 3 | 4 | 5 | [] 6 | let main argv = 7 | 8 | // create PLplot stream 9 | use pl = new PLStream() 10 | 11 | // generate data 12 | let nsize = 101 13 | let xmin, xmax, ymin, ymax = 0., 1., 0., 100. 14 | let x, y = 15 | Array.init nsize (fun i -> 16 | let x = float i / float (nsize - 1) 17 | let y = ymax * x * x 18 | x, y) 19 | |> Array.unzip 20 | 21 | // Parse and process command line arguments 22 | let mutable argv = argv 23 | pl.parseopts( &argv, ParseOpts.Full ||| ParseOpts.NoProgram ) |> ignore 24 | 25 | // Initialize plplot 26 | pl.init() 27 | 28 | // output version 29 | printfn "PLplot version %s" (pl.gver()) 30 | 31 | // Create a labelled box to hold the plot. 32 | pl.env( xmin, xmax, ymin, ymax, AxesScale.Independent, AxisBox.BoxTicksLabelsAxes ) 33 | pl.lab( "x", "y=100 x#u2#d", "Simple PLplot demo of a 2D line plot" ) 34 | 35 | // Plot the data that was prepared above. 36 | pl.line( x, y ) 37 | 38 | // PLplot is automatically closed when pl is disposed. 39 | 0 40 | -------------------------------------------------------------------------------- /Samples/FSharp/x00/x00.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Samples/FSharp/x22/Program.fs: -------------------------------------------------------------------------------- 1 | open System 2 | open PLplot 3 | 4 | let pl = new PLStream() 5 | 6 | let pi = atan 1.0 * 4.0 7 | 8 | (* Pairs of points making the line segments used to plot the user defined 9 | arrow. *) 10 | let arrow_x = [|-0.5; 0.5; 0.3; 0.5; 0.3; 0.5|] 11 | let arrow_y = [|0.0; 0.0; 0.2; 0.0; -0.2; 0.0|] 12 | let arrow2_x = [|-0.5; 0.3; 0.3; 0.5; 0.3; 0.3|] 13 | let arrow2_y = [|0.0; 0.0; 0.2; 0.0; -0.2; 0.0|] 14 | 15 | (*--------------------------------------------------------------------------*\ 16 | * Generates several simple vector plots. 17 | \*--------------------------------------------------------------------------*) 18 | 19 | (* 20 | * Vector plot of the circulation about the origin 21 | *) 22 | let circulation () = 23 | let nx = 20 24 | let ny = 20 25 | let dx = 1.0 26 | let dy = 1.0 27 | 28 | let xmin = - float nx / 2.0 * dx 29 | let xmax = float nx / 2.0 * dx 30 | let ymin = - float ny / 2.0 * dy 31 | let ymax = float ny / 2.0 * dy 32 | 33 | let xg = Array2D.zeroCreate nx ny 34 | let yg = Array2D.zeroCreate nx ny 35 | let u = Array2D.zeroCreate nx ny 36 | let v = Array2D.zeroCreate nx ny 37 | 38 | (* Create data - circulation around the origin. *) 39 | for i = 0 to nx - 1 do 40 | let x = (float i - float nx / 2.0 + 0.5) * dx 41 | for j = 0 to ny - 1 do 42 | let y = (float j - float ny / 2.0 + 0.5) * dy 43 | xg.[i,j] <- x; 44 | yg.[i,j] <- y; 45 | u.[i,j] <- y; 46 | v.[i,j] <- - x; 47 | 48 | (* Plot vectors with default arrows *) 49 | pl.env(xmin, xmax, ymin, ymax, AxesScale.Independent, AxisBox.BoxTicksLabels); 50 | pl.lab("(x)", "(y)", "#frPLplot Example 22 - circulation"); 51 | pl.col0 2; 52 | pl.vect (u, v, 0.0, pl.tr2(xg, yg)) 53 | pl.col0 1; 54 | () 55 | 56 | (* 57 | * Vector plot of flow through a constricted pipe 58 | *) 59 | let constriction astyle = 60 | let nx = 20 61 | let ny = 20 62 | let dx = 1.0 63 | let dy = 1.0 64 | 65 | let xmin = - float nx / 2.0 * dx 66 | let xmax = float nx / 2.0 * dx 67 | let ymin = - float ny / 2.0 * dy 68 | let ymax = float ny / 2.0 * dy 69 | 70 | let xg = Array2D.zeroCreate nx ny 71 | let yg = Array2D.zeroCreate nx ny 72 | let u = Array2D.zeroCreate nx ny 73 | let v = Array2D.zeroCreate nx ny 74 | 75 | let q = 2.0 76 | for i = 0 to nx - 1 do 77 | let x = (float i - float nx / 2.0 + 0.5) * dx 78 | for j = 0 to ny - 1 do 79 | let y = (float j - float ny / 2.0 + 0.5) * dy 80 | xg.[i,j] <- x; 81 | yg.[i,j] <- y; 82 | let b = ymax / 4.0 * (3.0 - cos (pi * x / xmax)) 83 | if abs y < b then 84 | let dbdx = ymax / 4.0 * sin (pi * x / xmax) * pi / xmax * y / b 85 | u.[i,j] <- q * ymax / b; 86 | v.[i,j] <- dbdx * u.[i,j]; 87 | else 88 | u.[i,j] <- 0.0; 89 | v.[i,j] <- 0.0; 90 | 91 | pl.env(xmin, xmax, ymin, ymax, AxesScale.Independent, AxisBox.BoxTicksLabels); 92 | let title = sprintf "%s%d%s" "#frPLplot Example 22 - constriction (arrow style " astyle ")" 93 | pl.lab("(x)", "(y)", title); 94 | pl.col0 2; 95 | pl.vect (u, v, (-1.0), pl.tr2(xg, yg)) ; 96 | pl.col0 1; 97 | () 98 | 99 | let f2mnmx (f: float[,]) = 100 | let fmax = ref f.[0,0] 101 | let fmin = ref f.[0,0] 102 | 103 | for i = 0 to Array2D.length1 f - 1 do 104 | for j = 0 to Array2D.length2 f - 1 do 105 | fmax := max !fmax f.[i,j]; 106 | fmin := min !fmin f.[i,j]; 107 | !fmin, !fmax 108 | 109 | (* 110 | * Vector plot of the gradient of a shielded potential (see example 9) 111 | *) 112 | let potential () = 113 | let nper = 100 114 | let nlevel = 10 115 | let nr = 20 116 | let ntheta = 20 117 | 118 | (* Potentialside a conducting cylinder (or sphere) by method of images. 119 | Charge 1 is placed at (d1, d1), with image charge at (d2, d2). 120 | Charge 2 is placed at (d1, -d1), with image charge at (d2, -d2). 121 | Also put smoothing term at small distances. *) 122 | 123 | let rmax = float nr 124 | 125 | let eps = 2.0 126 | 127 | let q1 = 1.0 128 | let d1 = rmax / 4.0 129 | 130 | let q1i = - q1 * rmax / d1 131 | let d1i = rmax**2.0 / d1 132 | 133 | let q2 = -1.0 134 | let d2 = rmax / 4.0 135 | 136 | let q2i = - q2 * rmax / d2 137 | let d2i = rmax**2.0 / d2 138 | 139 | let xg = Array2D.zeroCreate nr ntheta 140 | let yg = Array2D.zeroCreate nr ntheta 141 | let u = Array2D.zeroCreate nr ntheta 142 | let v = Array2D.zeroCreate nr ntheta 143 | let z = Array2D.zeroCreate nr ntheta 144 | 145 | for i = 0 to nr - 1 do 146 | let r = 0.5 + float i 147 | for j = 0 to ntheta - 1 do 148 | let theta = 2.0 * pi / float (ntheta - 1) * (0.5 + float j) 149 | let x = r * cos theta 150 | let y = r * sin theta 151 | xg.[i,j] <- x; 152 | yg.[i,j] <- y; 153 | let div1 = sqrt ((x - d1)**2.0 + (y - d1)**2.0 + eps**2.0) 154 | let div1i = sqrt ((x - d1i)**2.0 + (y - d1i)**2.0 + eps**2.0) 155 | let div2 = sqrt ((x - d2)**2.0 + (y + d2)**2.0 + eps**2.0) 156 | let div2i = sqrt ((x - d2i)**2.0 + (y + d2i)**2.0 + eps**2.0) 157 | z.[i,j] <- q1 / div1 + q1i / div1i + q2 / div2 + q2i / div2i; 158 | u.[i,j] <- 159 | - q1 * (x - d1) / div1**3.0 - q1i * (x - d1i) / div1i**3.0 160 | - q2 * (x - d2) / div2**3.0 - q2i * (x - d2i) / div2i**3.0; 161 | v.[i,j] <- 162 | - q1 * (y - d1) / div1**3.0 - q1i * (y - d1i) / div1i**3.0 163 | - q2 * (y + d2) / div2**3.0 - q2i * (y + d2i) / div2i**3.0; 164 | 165 | let xmin, xmax = f2mnmx xg 166 | let ymin, ymax = f2mnmx yg 167 | let zmin, zmax = f2mnmx z 168 | 169 | pl.env(xmin, xmax, ymin, ymax, AxesScale.Independent, AxisBox.BoxTicksLabels); 170 | pl.lab("(x)", "(y)", "#frPLplot Example 22 - potential gradient vector plot"); 171 | (* Plot contours of the potential *) 172 | let dz = (zmax - zmin) / float nlevel 173 | let clevel = 174 | Array.init nlevel (fun i -> zmin + (float i + 0.5) * dz) 175 | 176 | pl.col0 3; 177 | pl.lsty LineStyle.ShortDashesShortGaps; 178 | pl.cont (z, 0, nr-1, 0, ntheta-1, clevel, pl.tr2(xg,yg)); 179 | pl.lsty LineStyle.Continuous; 180 | pl.col0 1; 181 | 182 | (* Plot the vectors of the gradient of the potential *) 183 | pl.col0 2; 184 | pl.vect (u, v, 25.0, pl.tr2(xg, yg)); 185 | pl.col0 1; 186 | 187 | let px = Array.zeroCreate nper 188 | let py = Array.zeroCreate nper 189 | (* Plot the perimeter of the cylinder *) 190 | for i=0 to nper - 1 do 191 | let theta = (2.0 * pi / float (nper - 1)) * float i 192 | px.[i] <- rmax * cos theta; 193 | py.[i] <- rmax * sin theta; 194 | pl.line(px, py); 195 | () 196 | 197 | let transform2 xmax x y (xt: float byref) (yt: float byref) = 198 | xt <- x 199 | yt <- y / 4.0 * (3.0 - cos (pi * x / xmax)) 200 | 201 | (* Vector plot of flow through a constricted pipe 202 | with a coordinate transform *) 203 | let constriction2 () = 204 | let nx, ny = 20, 20 205 | let nc = 11 206 | let nseg = 20 207 | let dx, dy = 1.0, 1.0 208 | let xmin = float -nx / 2.0 * dx 209 | let xmax = float nx / 2.0 * dx 210 | let ymin = float -ny / 2.0 * dy 211 | let ymax = float ny / 2.0 * dy 212 | 213 | pl.stransform (TransformFunc(fun x y xt yt _ -> transform2 xmax x y &xt &yt)) 214 | 215 | let cgrid2_xg = Array2D.zeroCreate nx ny 216 | let cgrid2_yg = Array2D.zeroCreate nx ny 217 | let u = Array2D.zeroCreate nx ny 218 | let v = Array2D.zeroCreate nx ny 219 | let q = 2.0 220 | for i = 0 to nx - 1 do 221 | let x = (float i - float nx / 2.0 + 0.5) * dx 222 | for j = 0 to ny - 1 do 223 | let y = (float j - float ny / 2.0 + 0.5) * dy 224 | cgrid2_xg.[i,j] <- x; 225 | cgrid2_yg.[i,j] <- y; 226 | let b = ymax / 4.0 * (3.0 - cos (pi * x / xmax)) 227 | u.[i,j] <- q * ymax / b; 228 | v.[i,j] <- 0.0 229 | let clev = Array.init nc (fun i -> q + float i * q / float (nc - 1)) 230 | 231 | pl.env(xmin, xmax, ymin, ymax, AxesScale.Independent, AxisBox.BoxTicksLabels); 232 | pl.lab ("(x)", "(y)", "#frPLplot Example 22 - constriction with plstransform"); 233 | pl.col0 2; 234 | pl.shades (u, DefinedFunc(fun _ _ -> true), 235 | (xmin + dx / 2.0), (xmax - dx / 2.0), 236 | (ymin + dy / 2.0), (ymax - dy / 2.0), 237 | clev, 0.0, 1, 1.0, false, null); 238 | pl.vect (u, v, -1.0, pl.tr2(cgrid2_xg, cgrid2_yg)); 239 | pl.path (nseg, xmin, ymin, xmax, ymin); 240 | pl.path (nseg, xmin, ymax, xmax, ymax); 241 | pl.col0 1; 242 | 243 | pl.stransform null 244 | () 245 | 246 | 247 | [] 248 | let main argv = 249 | 250 | let mutable argv = argv 251 | (* Parse and process command line arguments *) 252 | pl.parseopts( &argv, ParseOpts.Full ||| ParseOpts.NoProgram ) |> ignore 253 | 254 | (*itialize plplot *) 255 | pl.init (); 256 | 257 | circulation (); 258 | 259 | let fill = false 260 | 261 | (* Set arrow style using arrow_x and arrow_y then 262 | plot using these arrows. *) 263 | pl.svect (arrow_x, arrow_y, fill); 264 | constriction ( 1 ); 265 | 266 | (* Set arrow style using arrow2_x and arrow2_y then 267 | plot using these filled arrows. *) 268 | let fill = true 269 | pl.svect (arrow2_x, arrow2_y, fill); 270 | constriction ( 2 ); 271 | 272 | constriction2 (); 273 | 274 | (* Reset arrow style to the default *) 275 | pl.svect (null, null, fill) 276 | 277 | potential (); 278 | 279 | (pl :> IDisposable).Dispose() 280 | 0 281 | 282 | -------------------------------------------------------------------------------- /Samples/FSharp/x22/x22.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | TODO: 2 | - Change marshalling of PLUTF8_STRING to UnmanagedType.LPUTF8String once this becomes available. 3 | - test if bools work as intended 4 | 5 | -------------------------------------------------------------------------------- /Upload-Docs.ps1: -------------------------------------------------------------------------------- 1 | #$ErrorActionPreference = "Stop" 2 | 3 | if ($env:APPVEYOR_REPO_BRANCH -ne "master") { 4 | Write-Host "Only uploading docs on master branch." 5 | exit 0 6 | } 7 | 8 | #Add-Content "$env:USERPROFILE.git-credentials" "https://$($env:GITHUB_TOKEN):x-oauth-basic@github.com`n" 9 | #git config --global credential.helper store 10 | git config --global user.name "Appveyor CI" 11 | git config --global user.email "appveyor@surban.net" 12 | 13 | git clone -b gh-pages https://$($env:GITHUB_TOKEN)@github.com/surban/PLplotNet.git web_old 14 | Move-Item $PSScriptRoot/Docs/_site web 15 | Move-Item web_old/.git web 16 | 17 | Push-Location web 18 | git add . 19 | git commit -m "Appveyor CI deployment" 20 | git push 21 | Pop-Location 22 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | - 2 | image: Visual Studio 2017 3 | 4 | environment: 5 | GITHUB_TOKEN: 6 | secure: eqPY/dxZGj9A0OPR5TsdTi9WZcsQQsaMR6kv5iqrtC1Thr8OgnVQbqVcq6nWnw9I 7 | 8 | before_build: 9 | - ps: .\Fetch-Native.ps1 10 | 11 | build_script: 12 | - dotnet pack -c Release PLplotNet 13 | - ps: .\Docs\build.ps1 14 | 15 | test_script: 16 | - dotnet run -c Release -p Samples/FSharp/DevList 17 | - dotnet run -c Release -p Samples/FSharp/x00 -- -dev pdfcairo -o out.pdf 18 | - dotnet run -c Release -p Samples/FSharp/x22 -- -dev pdfcairo -o out.pdf 19 | - dotnet run -c Release -p Samples/CSharp/SineWaves -- png 20 | 21 | artifacts: 22 | - path: 'Packages/Release/*.nupkg' 23 | 24 | deploy: 25 | provider: NuGet 26 | api_key: 27 | secure: JwbH3IZTbXNoH4tC9N3vqXHw1OeluIa7OHNaoEQR/LEy6c3DL/hU79sHFLVlz+mm 28 | on: 29 | appveyor_repo_tag: true 30 | 31 | on_success: 32 | - ps: .\Upload-Docs.ps1 33 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "2.2.200", 4 | "rollForward": "latestMajor" 5 | } 6 | } --------------------------------------------------------------------------------