TMS Software. All-Access

Extend TMS WEB Core with JS Libraries with Andrew: FontAwesome

This time out, we are exploring FontAwesome, another wildly popular JS library. Like Bootstrap last week, FontAwesome requires no JavaScript coding knowledge and very little in the way of HTML or CSS knowledge either.  And while it does have a lot to do with fonts, and is indeed truly awesome, the main benefit we’re going to get from FontAwesome in terms of our TMS WEB Core projects is its enormous icon library. Great. More Icons. Last week, we touched briefly on the topic of Bootstrap Icons. 1,600 or so freely usable icons that you can directly use in your projects. There are also Google Material Icons. Several thousand more icons that also come in five different styles. The Google Material Icons library is even included in the JavaScript Library Manager in the Delphi IDE, so getting started is easy enough. If you’ve used one of these sets of icons previously in your projects, you might be reluctant to switch to something else.  The look of the Google icons will be familiar to many and might be somewhat of a safe choice.  Long-time developers might feel a bit of a chill when reflecting back on icons of ages past. There was a time when you could pretty accurately guess what tools were used to create an app based entirely on how audacious the icons were.  Like acid-wash jeans and tie-dye shirts, these are thankfully well behind us and we now have mostly sane choices to pick from.  Also long gone are less-than-fun topics like multi-res bitmaps, bmp-vs-ico, transparency issues, and anything to do with scaling.  I suspect our children will never care what a pixel is because they won’t actually be able to see any individual pixels anywhere without a microscope.  Back to the topic at hand.  Like Google Material Icons, FontAwesome has a handful of different styles to choose from.  And I personally much prefer FontAwesome styles to the Google equivalents, but there’s more to the story than just the look of the icons.  Much more. Making Your Project FontAwesome The FontAwesome library was recently added to the “Manage JavaScript Libraries” list, sometime around TMS WEB Core 1.9.8 or so.  It lists both FontAwesome 4 and FontAwesome 5. FontAwesome 6 also came out a couple of months ago.  We’ll run into some of the differences closer to the end of this article.  But I think everything we’re going to cover today will work the same in any version unless otherwise noted.  One thing that is different between versions is the icons themselves – new icons are added and occasionally icons are changed or removed or, more likely, renamed or redesigned.  This can even happen mid-version, so something to keep an eye out for, particularly if you want to use the very latest icons.  If your project doesn’t already use FontAwesome, just pick the highest version available from the “Manage JavaScript Libraries” list and you’re done! If you’d like to use a  particular version of the FontAwesome library, or a particular CDN, or even host the libraries yourself, then the usual approach of adding files to your Project.html file works just fine as well.  Or you can use the JavaScript Library Manager to update the list to suit your particular needs.  Both FontAwesome themselves as well as any reputable CDN will […]

Read More

Managing displays with the Multi-Screen Window Placement API

With the release of Google Chrome 100 came the new Multi-Screen Window Placement API. This API allows you to enumerate the displays connected to your machine and to place windows on specific screens. We’ve wrapped this API with TMS WEB Core, so that you can use this inside your Web Applications with minimal effort.  Before we had this API, we could use the window.open() to control windows. This method however, is unaware of additional screens. We can specify the position by passing the coordinates as left and top and pass the size as width and height. To get the information about the current screen we could check the window.screen property.  How to use First of all we have to check if the API is supported. we can simply do this by calling the GetScreenAvailability function. this will return true if it is supported.  To get all necessary screen information you can call the following asynchronous function: GetScreensInfo. This will result in a TJSScreenInfo object containing a list of all the available displays as well as the current screen the window is rendered on.  screens := await(TJSScreeninfo, GetScreensInfo); screens.OnCurrentScreenChange := DoCurrentScreensChange; screens.OnScreensChange := DoScreensChanged; The Screens object also has 2 events: OnCurrentScreenChange: This event updates the screens object when the web application changes screen. OnScreenChange: This event updates the screens object when the browser detects that the displays have been changed.(i.e. adding/removing a display) The Screens object looks like this on my machine. As you can see I have to 2 Displays connected to my machine. And my CurrentScreen is “External Display 2” which is not my primary screen. Using the left and top properties of the TJSScreenDetails object, we can accurately position our window wherever we want on the display that you want. Before we can use the Multi-Screen Window Placement API we must ask the user for permission to use it. To do this, we can call the GetPermissions function. Be aware that this function is asynchronous. so you’ll have to await it. you can use it like this: allowed := await(boolean, GetPermissions); Weather around the world! Using this API we made a demo application that let’s you check the weather in several locations all around the world. If you have a multi display setup the weather popups will be shown on the screen the web application is not currently on.  The result will be something like this when clicking the button. Screen 1: Screen 2: And a screenshot from both screens together: To make this possible, we simply calculate how large the windows can be if we want to show a 5 x 2 table of windows. w := Math.floor((screens.screens[i].availableWidth – FColumns * 1) / FColumns); h := Math.floor((screens.screens[i].availableHeight – FRows * 51) / FRows); After that we loop over the columns and rows and calculate for each window the X and Y offset. we than add it to a WindowFeatures string and call the CreatePopup function.  for j := 0 to FColumns -1 do begin for k := 0 to FRows -1 do begin x := j * w + screens.screens[i].availableLeft + j * 1; y := k * h + screens.screens[i].availableTop + k * 51; Features := ” + ‘screenX=’ + IntToStr(x)+ ‘,’ + ‘screenY=’ + IntToStr(y)+ ‘,’ + ‘width=’ + IntToStr(w)+ ‘,’ + ‘height=’ + IntToStr(h)+ ‘,’ […]

Read More

Save and load Excel .XLSX files from grids in Delphi or C++Builder apps

The Microsoft Excel file as industry standard The Excel .XLSX file format is these days a de facto standard file format to exchange all kinds of tabular data. As the information in an Excel sheet is 2 dimensional, a grid control is the most logical choice for viewing such data or to be the source of such data. For a long time, the TMS VCL TAdvStringGrid component offered built-in support to open and save .XLS files natively without the need to have Microsoft Excel installed. Given how complex the .XLSX file format is, TAdvStringGrid offered only built-in support to save and load .XLSX files via OLE automation, i.e. with the requirement to have Microsoft Excel installed. On the other side, also for a long time, we have the TMS FlexCel product that specializes in native Excel file manipuluation, i.e. reading, writing, modifying Excel files (.XLS and .XLSX) as well as reporting based on Excel template files or exporting Excel files to PDF, HTML, …  TMS FlexCel has grown into an extremely feature rich and sophisticated product to work with Excel files. Hence, the idea to make it extremely easy to take advantage of the FlexCel technology to also allow to natively save and load .XLSX files in our grid components, in particular our VCL grid for Windows application development with Delphi or C++Builder as well as our FNC grid for cross-platform development for Windows, macOS, iOS, Android, Linux. [adinserter block=”2″] Bridge components To make this possible, we introduced two free bridge components, the TMS VCL Grid Excel bridge and the TMS FNC Grid Excel bridge. These are non-visual components TAdvGridExcelExport, TAdvGridExcelImport or TTMSFNCGridExcelExport, TTMSFNCGridExcelImport,  that simply connect to either TAdvStringGrid (and descending components) as well as the TTMSFNCGrid cross-platform grid component. After hooking the grid to this component via a property Grid, import or export is as low-code as a single line of code: To load .XLSX sheet data into a grid:   TMSFNCGridExcelImport1.Import(‘test.xlsx’, ‘my sheet’); In case you wish to work with multiple sheets at once, the bridge components can be connected to a TAdvGridWorkbook and multiple sheets will be imported or exported via the same functions. To save the data from the grid to an .XLSX file:   TMSFNCGridExcelExport1.Export(‘test.xlsx’); and in addition to export to Excel files, there are methods:   TMSFNCGridExcelExport1.ExportPDF(‘test.pdf’); or   TMSFNCGridExcelExport1.ExportHTML(‘test.html’); to export the grid to PDF or HTML files. By default, the TAdvGridExcelExport or TTMSFNCGridExcelExport take in account a lot of cell characteristics for the import or export. This includes: background color font color font name & size cell alignment cell pictures cell merging cell checkboxes cell sizes hyperlinks There is further fine control over what grid and/or Excel features will be imported & exported via properties under: TTMSFNCGridExcelImport.ImportOptions, TAdvGridExcelImport.ImportOptions and TTMSFNCGridExcelImport.ExportOptions, TAdvGridExcelExport.ExportOptions Also, the bridge components also allow you to specify what range of cells to import or export. By default this is the range of used cells in the grid or Excel file, but via TTMSFNCGridExcelImport.LocationOptions, TAdvGridExcelImport.LocationOptions and TTMSFNCGridExcelImport.LocationOptions, TAdvGridExcelExport.LocationOptions you have fine-grained control over what range of cells will be involved in the export/import. Finally, if you want to dynamically control in code additional formatting of cells, there is the TAdvGridExcelExport.OnCellExport() event that is triggered for every cell and allows to override in code the cell format to apply for […]

Read More

Extensions for TMS WEB Core for Delphi

1. Introduction TMS WEB Core is a framework that allows the user to write JavaScript web client applications with the Object Pascal language. Therefore the Object Pascal code is transpiled to JavaScript with the pas2js compiler . TMS WEB Core supports the three IDEs Embarcadero RAD Studio with Delphi, Microsoft Visual Studio Code and Lazarus. This article is primarily concerned with Delphi and shows four options to extend the TMS WEB Core product: Creating design-time packages Writing custom WEB Core components Using & registering base web form classes Registering custom Frames 2. Demo The above mentioned options are practically shown in the demo DemoPackage (download here) which contains a run-time package, a design-time package, a TMS WEB Core application and a VCL application. 3. Packages Delphi projects can contain packages, either for regular programs and for the IDE. A package is a Delphi specific library, similar to a DLL (Dynamic Link Library) on Windows. Packages end with the extension .BPL (Borland Package Library) and are created by the compiler after compilation. When starting an application, the packages are loaded statically. We have to differentiate between two sorts of packages. These are run-time packages and design-time packages. 3.1. Run-time Packages A run-time package is a library that includes parts of the source code and provides parts of the functionality of the application. Instead of having one single executable, it is split into a small executable and multiple packages. 3.2. Design-time Packages Design-time packages are used by the Delphi IDE to make components load dynamically. Therefore components must be registered. Doing this, the IDE tool palette will list the components and this allows the designer to display the components. It is good practice to split the code into run-time code for the run-time package and register code (and any other code that might be only needed and used at design-time) for the design-time package. This design-time package for this demo is DemoPackageIDE.dproj. 3.3. How to set design-time and run-time packages The options of a project can be set in the so called “Project Options”. There is a radio button in the section “Description”, in which the options “Run-time only” and “Design-time only” can be selected. The option “Design-time and Runtime” can be selected, but is as mentioned above not recommended. 3.4. Build control It is also recommended to select “Explicit rebuild” since the option “Rebuild as needed” often leads to problems with packages that are distributed over several project groups. 4. Writing custom TMS WEB Core components The demo contains the unit MyFloatEdit with the component TMyFloatEdit which is a small improvement of a TWebEdit. 4.1. Registering a Component The Delphi IDE calls all public procedures named “Register” from design-time packages. These procedures are called when the design-time package is loaded. Inside a Register procedure components can be registered. The Demo shows how this looks like: interface procedure Register; implementation procedure Register;begin  RegisterComponents(‘My TMS WEB components!!’, [TMyFloatEdit]);end; 4.2. DesignIDE package In order to call RegisterComponents it is necessary to require the DesignIDE package in a Designtime package. The Demo shows this: requires…  DesignIDE,… 4.3. Platforms In order to register a component the Delphi designer needs to be informed which platforms the component shall be used for (e.g. Win32, Win64 and WEB). In the Delphi IDE all TMS WEB Core projects are treated […]

Read More

A simple computer algebra system with TMS Analytics & Physics 3.4

Here is the code of a Delphi console application, that simulates a simple computer algebra system using the ‘Run’ method: program Simulator; {$APPTYPE CONSOLE} {$R *.res} uses   System.SysUtils,   Analytix.Utilities,   Analytix.Assembly,   Analytix.Float.Assembly,            Analytix.LinearAlgebra.Assembly,    Analytix.Derivatives.Assembly,      Analytix.Integrals.Assembly,        Analytix.Translator; var   translator: TTranslator;   command, msg: string;   lines: TArray;   i: integer; begin   translator:= TTranslator.Create;                while true do   begin     Write(‘Input command: ‘);     ReadLn(command);     if command=” then exit;     translator.Run(command, msg);                    lines:= msg.Split([#13]);     for i:=Low(lines) to High(lines) do       WriteLn(lines[i]);     WriteLn;   end; end. In the simplest case, we can use commands for creating new variables, assigning new values to the existing variables, or evaluating symbolic expressions, as shown in the picture below. Assignment statement in the ‘Run’ method supports arrays, indexed expressions, and array slicing. Let us consider the following commands and the console output: Input command: A=[1 -1 2 3/4]Variable created. A=Array[4]=(1 -1 2 0.75 )Input command: B=[e 1/2 3 -3/4]Variable created. B=Array[4]=(2.71828182845905 0.5 3 -0.75 )Input command: M=Matrix{3 4}(0)Variable created. M=Array[3][4]=( 0 0 0 0)( 0 0 0 0)( 0 0 0 0)Input command: M[0]=A+BVariable M[0] assigned: Array[4]=(3.71828182845905 -0.5 5 0 )Input command: M[2]=A-BVariable M[2] assigned: Array[4]=(-1.71828182845905 -1.5 -1 1.5 )Input command: MM=Array[3][4]=(  3.71828182845905 -0.5  5   0)(                 0    0  0   0)( -1.71828182845905 -1.5 -1 1.5) First, two arrays ‘A’ and ‘B’ are created, using so called array expression syntax (array elements in the brackets ‘[]’), and the ‘M’ matrix 3×4, using the ‘Matrix’ function. Then we assigned the sum of the arrays to the zero row of the matrix, and the difference of the arrays to the 2nd row. The assignment statement used so called array slicing feature. That is, we can use not entire matrix or its individual element, but also the part of the matrix – a row or a column. The library supports array expressions and slicing for Real, Complex, and Boolean arrays up to the 3 dimensions. Another application of the assignment statement is creating user-defined functions. In the following example, we created two functions: the first calculates the volume of a sphere of radius ‘r’; the second calculates the length of a 3D vector, defined by the ‘x’, ‘y’, and ‘z’ coordinates. Input command: V(r)=4/3*Pi*r^3Function created. V(r)->4/3*Pi*r^3Input command: L(x y z)=(x^2+y^2+z^2)^(1/2)Function created. L(x y z)->(x^2+y^2+z^2)^(1/2) Once a function is defined, it can be then used in expressions to calculate their values for the specified arguments: Input command: V(1/2)V(1/2)=0.523598775598299Input command: L(-1 e 3/4)L(-1 e 3/4)=2.99191512228048 The ‘Run’ method also supports more complicated commands, such as conditional statement and loop statement. The following console output shows how the user solves a square equation with specified coefficients ‘a’, ‘b’, ‘c’, using the conditional ‘IF’ statement:  Input command: a=1Variable created. a=1Input command: b=-2Variable created. b=-2Input command: c=-3Variable created. c=-3Input command: d=b^2-4*a*cVariable created. d=16Input command: IF{d

Read More

Extend TMS WEB Core with JS Libraries with Andrew: Bootstrap

With so many incredible JS libraries available to developers, it might be hard to pick a place to start. But one in particular touts itself as The most popular JS, CSS and HTML library in the world and indeed it is, with good reason. I’m talking of course about Bootstrap.  One would be hard-pressed to find a modern website today that doesn’t take advantage of this library.  In fact, there is even a TMS WEB Core Bootstrap template to help you get started using Bootstrap right out of the gate.  And, unlike many of the JS libraries we’ll be covering, you can make use of Bootstrap without knowing any JS at all, or really any CSS or HTML for that matter.  In this article, we’ll cover a bit about what Bootstrap is and how to get started using it in your TMS WEB Core projects. So What is Bootstrap? Bootstrap is essentially an enormous collection of JS code and CSS styles that allow you to quickly design modern, mobile-first and responsive websites. Beyond just marketing hype though, it does this by providing a robust framework of CSS classes that help organize a typical website into a structure that works well in many different browser environments.  Indeed, if you were starting from nothing and didn’t have an IDE or other development tools, it is possible to do quite a bit of layout and design work just with Bootstrap by itself.  Fortunately we don’t have to work at that level.  Instead, we can simply use these Bootstrap classes in all kinds of ways with standard TMS WEB Core components. Adding Bootstrap to Your Project If you’ve got an existing TMS WEB Core project that you want to add Bootstrap to, it is just a few minutes  to get it installed.  As we covered in the introduction for this blog series, there are a few considerations here.  But the easiest way is to just use the “Manage JavaScript Libraries” feature of the IDE: Using this option, or creating a new TMS WEB Bootstrap Application will setup the necessary links in the Project.html file and will include a copy of the necessary Bootstrap library code in your project directly.  No need for a CDN or external links.  If you’d prefer to use a CDN instead, you can add the following links to your Project.html, as per the Bootstrap website: I’ve also included the Bootstrap Icons in the above links.  More on that a bit later.  Popper is another JS library that is used to display popup dialogs and other things. The Bootstrap folks have conveniently included it in their “bundle” distribution but you could choose a smaller package if you really didn’t need any of that functionality.  These links also reference Bootstrap 5 (or later) which no longer has a dependency on jQuery. So it doesn’t much matter where Bootstrap appears in the order, if you have multiple JS libraries in your project. If you’re using an older version of Bootstrap (v4 or earlier) then be sure to check that jQuery is loaded first. So. Many. Classes. The Bootstrap website is an excellent source of documentation for all the many features they offer, complete with many examples.  One of the better sites for documentation of all the JS libraries we’re likely to cover.  However […]

Read More

Adding HTML, CSS & JavaScript to your native applications with TTMSFNCWXContainer

Always wanted to use interesting JavaScript libraries with functionality not readily available in Delphi or C++Builder in you VCL and FireMonkey applications? Or integrate HTML Components? The TTMSFNCWXContainer component let’s you do just that! Simply adding a container to the component and setting the HTML, CSS & JavaScript is enough to get you started. This example is a simple HTML Button styled with Bootstrap. We’ve tweaked the CSS a bit to make sure the button is the size of the whole component to get this result.  From here you can write your own JavaScript to be executed when the user clicks the button. But you can also add assign an action to it. To do this, simply add an action to the Actions collection and assign the HTMLElementID. Subscribe to the OnExecute event and put your code there. the AEventData contains all information from the JavaScript. Or you can go the other way around and call JavaScript functionality from the pascal side with the ExecuteJavaScript function. procedure TForm5.TMSFNCWXContainer1ElementContainers0Actions0Execute( Sender: TObject; AEventData: TTMSFNCCustomWEBControlEventData); begin TMSFNCWXContainer1.ExecuteJavaScript(‘$(“#clickbutton”).removeClass().addClass(“btn btn-danger”)’); end; As you can see this OnExecute event calls the ExecuteJavaScript and uses jQuery functionality to remove all CSS classes and add the “btn btn-danger” class. This means that when you click the button it will change from blue to red.  Last but not least you can use the JavaScript Bridge to send data from the JavaScript to the pascal code. To do this call the ‘CallBack(‘eventname’, eventData) function in your JavaScript and subscribe to the OnCustomEvent of the component. 

Read More

Extend TMS WEB Core with JS Libraries with Andrew: introduction

  Welcome to the first post in a new series for the TMS Blog, “Extend TMS WEB Core with JS Libraries with Andrew “.  In this ongoing series we’ll look at how to quickly and easily incorporate third-party JavaScript libraries into TMS WEB Core projects.  Each week will typically focus on a particular JS library and the problem it is trying to solve.  A sample project will be included to showcase some of its key features and how they can be integrated into TMS WEB Core. And some additional commentary will offer insight as to what it is like to work with the particular JS library as most of those to be featured in this series are used regularly in my own projects. For those new to TMS WEB Core or new to JavaScript, we’ll spend the rest of this first post covering a lot of the basics of what this is all about.   So. Many. JS Libraries. It is quite possible to develop fantastic 100% pure JavaScript/HTML/CSS web applications using just TMS WEB Core and the included components, just as you would expect with any other popular web frameworks. When it comes to extending a project with additional functionality beyond the included components, you’ve got options. You can of course write code yourself. You can use components from vendors like TMS Software and others that are specifically designed for TMS WEB Core.  Or you can tap into the huge reservoir of both open source and commercial JavaScript libraries.  On GitHub for example there at least several thousand such JS libraries covering everything from the simplest little CSS tweaks to hugely complex and involved APIs for machine learning.  If you’ve run into a problem developing your web application and need a bit of functionality that just isn’t there, there’s a pretty good chance someone has come along and made a JS library to address it.  Here’s a bit of an idea about the categories of JS Libraries that are available. Helpers.  Provide developers with shortcuts for common tasks.  JQuery and Bootstrap fall in this category. Assets.  Icons, fonts, themes and so on that are likely to make a big impact on the look and feel of your web application.  FontAwesome is an example.   Bootstrap comes with icons as well. Controls.  Interactive UI elements that provide functionality roughly equivalent to what a Delphi component might offer.  There are countless date/time pickers, for example FlatPickr. Tools.  Similar to Helpers, these are used to extend or otherwise enhance the components core controls that you are already using.  Interact.js adds drag+resize functionality to any control, for example. Services.  These include libraries for connecting to external services or communications, and libraries that help with sending e-mail and SMS messages, that sort of thing. Devices.  Typically these are APIs that allow for interacting with local devices or other hardware. Anything to do with Raspberry Pi, for example, would fall into this category. In this series we’re going to start out by focusing on those JS libraries that can help us craft better looking and easier to use web applications, so typically the first four categories. While the last two categories, Services and Devices, are hugely popular and important, they’re also very specific in nature.  Coverage of these would likely be far less about JS and TMS […]

Read More

Data analytics & chart visualization in Delphi

Google Analytics helps to identify user browsing behavior. It is a powerful tool to analyze & monitor data and eventually adapt the content on your website to make sure users have a better experience. The purpose of this blog post is to capture realtime page visits on your website, analyze which browser is used and visualize it in a pie chart. The component capable of doing this is the TTMSFNCChart. At the end of this blog post, a sample is provided which allows you to see the code to retrieve the data from Google Analytics and how to configure the chart to display the results. Note that this sample also makes use of the component TTMSFNCCloudGoogleAnalytics which is part of the TMS FNC Cloud Pack. Retrieving the data After setting up Google Analytics, and setting up a connection via the TTMSFNCCloudGoogleAnalytics component, we call RetrieveData which asynchronously retrieves the data we are looking for. The code to properly setup the required data fields depends on a series of request parameters which are shown in the code snippet below. procedure TGoogleAnalyticsForm.GetReportData; begin … TMSFNCCloudGoogleAnalytics1.RequestData.UserMetrics := UM; TMSFNCCloudGoogleAnalytics1.RequestData.PageMetrics:= PM; TMSFNCCloudGoogleAnalytics1.RequestData.PlatformOrDeviceDimension := DM; TMSFNCCloudGoogleAnalytics1.RequestData.SystemDimension := SM; TMSFNCCloudGoogleAnalytics1.RequestData.PageDimension := PGM; TMSFNCCloudGoogleAnalytics1.RequestData.TimeDimension := TM; TMSFNCCloudGoogleAnalytics1.RetrieveData(StartDate, EndDate, MaxResults); end; Executing this request will display results in a VCL TStringGrid. Note that we can see the amount of time the user spends on each page and which browser and resolution is used. This is realtime data! Visualizing browser usage Whilst the grid shows the data after retrieval, it doesn’t give an easy visual interpretation. You need to look carefully which browser is used, which page is visited, etc .. whilst scrolling through the grid. This is where TMS FNC Chart comes into play. Dropping an instance of TTMSFNCChart on the form immediately gives an idea of its capabilities. For this particular sample, we will configure a pie chart, which is ideal for displaying percentage numbers. We start by analyzing the browser column inside the grid, and count the duplicate entries. d := TDictionary.Create; … for I := 1 to sgReport.RowCount – 1 do begin b := sgReport.Cells[6, I]; if d.ContainsKey(b) then d[b] := d[b] + 1 else d.Add(b, 1); end; … Then, once we collected the data inside the dictionary, we can start configuring the TTMSFNCChart instance. Step 1 is to clear the default series, add a new series and set the correct type. var p: TTMSFNCChartSerie; … TMSFNCChart1.BeginUpdate; TMSFNCChart1.Clear; p := TMSFNCChart1.Series.Add; p.ChartType := ctPie; TMSFNCChart1.EndUpdate; … Step 2 is to add points to the pie series. This is done by looping through the dictionary keys, which actually represent the browser, and retrieve the total value. Adding points in the chart is done with one of the multiple overloads, depending on the chosen type. For a pie chart, we use one of the AddPoint overloads, specifically to pass a value, color and a legend text. for k in d.Keys do begin if d.TryGetValue(k, v) then begin c := gcRed; if ci < Length(ca) then c := ca[ci]; p.AddPoint(v, c, Format(k + ' %.1f %%', [v / t * 100])); Inc(ci); end; end; The default look and feel of the pie chart is sufficient for displaying the results, but we also want to visualize the actual values in a separate legend. In TMS FNC Chart each visual element is fully customizable, via […]

Read More

Upcoming free webinar: Getting started with TMS FNC Maps

Did you know that on April 22, we celebrate the 2nd birthday of TMS FNC Maps? In full first COVID19 lockdown, we successfully launched TMS FNC Maps v1.0 after many man-months of development work. It is since its launch, a product that is unmatched in flexibility and features. TMS FNC Maps works fine for your VCL Windows applications, your FireMonkey Windows, macOS, iOS, Android and Linux applications, your TMS WEB Core web client applications, your Lazarus applications… You can use TMS FNC Maps from 4 IDEs: Delphi, C++Builder, Lazarus and Visual Studio Code. And with a single property switch, you select between Google Maps, Bing Maps, Here Maps, OpenLayers, Azure Maps, MapBox, Apple MapKit, TomTom maps.   In the past 2 years, we released non-stop a wave of new versions offering new features, improved performance and more flexibility.  Free webinar If you haven’t discovered our powerful TMS FNC Maps product yet, here is your chance to participate in our upcoming free webinar “Getting started with TMS FNC Maps“. On the agenda of this upcoming webinar on Apr 13 at 3PM UTC (17h00 CEST) we have: Why TMS FNC Maps: why did we create this product Introduction to included components, services, supported frameworks and IDEs and architecture Basic mapping techniques: location, bounds, pan, zoom, controls, views Working with markers: add markers, marker properties and custom markers Graphics on maps: circles, rectangles, polylines, polygons, HTML elements on maps + helper functions Geolocation & reverse geolocation: services, sync and async handling Directions: get directions with optional waypoints Overview of other advanced features Register for our free live interactive webinar on TMS Web Academy now! Read more Meanwhile, you can already prepare for the webinar and read all about TMS FNC Maps: TMS FNC Maps Hands-on video v1.0 TMS FNC Maps book availability Release v1.1 : Directions, Google Maps marker clusters Release v1.2 : Elevation, GPX import/expert, custom tile servers in OpenLayers Tile Layers support, Plus Codes, GPX export Release v1.3 : Google streetview support, toll roads settings  Release v1.4 : Apple MapKit support, integrated directions, map rotation Release v1.5 : static map image, toll cost calculation, timezone information Helper functions: distance calculation and working with Plus Codes Google heat maps Release v2.0 : route calculator & route editing, geodesic polylines Release v2.1 : Using overlay views Free geocoding & reverse geocoding with OpenStreetMap Nomatim Free route directions with OpenRouteService Release v2.4 : Google Places, address autocompletion & polyline symbols Directions and geocoding with GeoApify Add custom controls to your map with TMS FNC Maps for Delphi Calculate square meters of an area Detect if a point is in a coordinate based polygon in Delphi  Register now & participate We look forward to meet you online in our live webinar “Getting started with TMS FNC Maps” on April 13 at 3PM UTC (17h00 CEST). Learn about TMS FNC Maps and have all your questions answered during the webinar! Register here

Read More