VCL

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

New blog series coming about extending TMS WEB Core with popular JS libraries

We are pleased to announce that a new blog article series is coming with Andrew Simard with the working title: “Extend TMS WEB Core with JS Libraries with Andrew”. Every week, TMS WEB Core power user Andrew Simard, will offer insights into working with popular JavaScript libraries from TMS WEB Core and share tips, tricks, code and projects. Andrew shares for quite some time already tips, tricks & insights for TMS WEB Core users via our Support Center in a special topic you can find here. The first series of +/- 20 blog articles is already planned and will come to you from April 2022. Watch our blog to learn all about it!    Want to get to know Andrew Simard already? See Andrew in the replay of the TMS WEB Core power users webinar we held a couple of weeks ago where Andrew presents his project he is building with help of TMS WEB Core.

Read More

TMS WEB Core for Visual Studio Code 1.9.8 available now!

We’re pleased to inform that TMS WEB Core for Visual Studio Code 1.9.8 is available. With TMS WEB Core for Visual Studio Code, you can develop web client applications with Object Pascal and using a RAD component based approach. In the last year, we worked very hard to not only fine-tune TMS WEB Core project compatibility between Delphi and Visual Studio Code but also to ensure the features and framework are in sync. Last week we released TMS WEB Core for Delphi and all improvements this latest release brought are today available in TMS WEB Core for Visual Studio Code. This ensures that you or the colleagues in your team have the freedom of choice to develop web client applications from the Delphi IDE on Windows or from the Visual Studio Code IDE directly on Windows, macOS or a Linux desktop machine. Among the many framework improvements, we want to highlight in this blog two new core features. Direct forms support The “Direct form” type, is a form that isn’t using its own unique HTML template file but lives in the application main HTML file. This facilitates that such web client application can be started directly from the file system (no HTTP(s) server needed) and also that it loads faster. You can still bind WEB Core controls to HTML elements but here, the HTML elements will need to be added to the main application HTML file. Note that in a TMS WEB Core web client application, you can mix direct forms with regular forms using a HTML template. To add a direct form to your TMS WEB Core web client application in Visual Studio Code, use this new repository item: To understand better what direct forms can mean for you, check out this video too where it is demonstrated when used from the Delphi IDE. JavaScript Libraries Manager When developing web client applications, it’s a kind of no-brainer to take advantage of existing JavaScript and CSS libraries. Things that come to mind are the Bootstrap, jQuery, Google Material icons, Fontawesome libraries and many more. Most likely, you have your own favorite JavaScript libraries you want to use together with TMS WEB Core web client apps. The JavaScript Libraries Manager allows you to directly pick your preferred library from a list and the IDE will add the proper reference to the project HTML file. At the same time, you can add your own preferred libraries for later convenient reuse. Get started! If you are a TMS ALL-ACCESS user, you automatically have access to the full & latest version of TMS WEB Core for Visual Studio Code.  Get in touch with our team or check out our support center for technical assistance or for sharing your ideas & thoughts to steer further development.

Read More

Detect if a point is in a coordinate based polygon in Delphi

In this blog post, we explained how to measure the area of a polygon defined by coordinates. TMS FNC Maps v3.0.3.0 adds a way to detect a point (coordinate) inside a polygon. In this short blog post, we want to show you how to work with this new functionality. Load GeoJSON First of all, we are going to load our GeoJSON file with coordinates that define the surface area of Germany. TMSFNCMaps1.BeginUpdate; TMSFNCMaps1.LoadGeoJSONFromFile(‘germany.geojson’); TMSFNCMaps1.EndUpdate; Then, we style the polygons loaded by the LoadGeoJSONFromFile method. The complete code to load and style polygons is demonstrated below. procedure LoadGeoJSON; var p: TTMSFNCMapsPolygon; I: Integer; begin TMSFNCMaps1.BeginUpdate; TMSFNCMaps1.LoadGeoJSONFromFile(‘germany.geojson’); for I := 0 to TMSFNCMaps1.Polygons.Count – 1 do begin p := TMSFNCMaps1.Polygons[I]; p.FillOpacity := 0.4; p.FillColor := gcGreenyellow; p.StrokeOpacity := 0.4; p.StrokeColor := gcGreen; end; TMSFNCMaps1.EndUpdate; end; Detecting a coordinate inside a polygon To detect whether or not a coordinate lies inside a polygon, the polygon collection item class exposes a ContainsPoint function. For the purpose of this sample, we used the non visual TTMSFNCGeocoding component and retrieved the coordinates for cities that lie inside and outside of Germany. procedure DetectPoints; var c1, c2, c3, c4: TTMSFNCMapsCoordinateRec; const v = ‘Coordinate inside polygon’; n = ‘Coordinate outside polygon’; begin c1 := TMSFNCGeocoding1.GetGeocodingSync(‘Groningen’); c2 := TMSFNCGeocoding1.GetGeocodingSync(‘Dresden’); c3 := TMSFNCGeocoding1.GetGeocodingSync(‘Munich’); c4 := TMSFNCGeocoding1.GetGeocodingSync(‘Augustenborg’); if TMSFNCMaps1.Polygons[0].ContainsPoint(c1) then TMSFNCMaps1.ShowPopup(c1, v) else TMSFNCMaps1.ShowPopup(c1, n); if TMSFNCMaps1.Polygons[0].ContainsPoint(c2) then TMSFNCMaps1.ShowPopup(c2, v) else TMSFNCMaps1.ShowPopup(c2, n); if TMSFNCMaps1.Polygons[0].ContainsPoint(c3) then TMSFNCMaps1.ShowPopup(c3, v) else TMSFNCMaps1.ShowPopup(c3, n); if TMSFNCMaps1.Polygons[0].ContainsPoint(c4) then TMSFNCMaps1.ShowPopup(c4, v) else TMSFNCMaps1.ShowPopup(c4, n); end; The result output is shown below. Alternative detection The ContainsPoint function at polygon collection item level internally calls the IsPointInArea, which is defined in the *.TMSFNCMapsCommonTypes.pas unit. To use this function, you need to define an array of coordinates. This function can be used without the need to define a polygon inside the Polygons collection.  function IsPointInArea(ALatitude: Double; ALongitude: Double; ACoordinatesArray: TTMSFNCMapsCoordinateRecArray): Boolean; Explore! Go ahead and download TMS FNC Maps. Explore the features and demos and feel free to leave a comment on this blog.

Read More

Q1 2022 : 3 months – 3 milestones – 3 new products in TMS ALL-ACCESS

Here, spring starts today March 21 and soon we are already closing the first quarter of 2022. So with the year well underway, it is time for a short look back at what the year brought so far for Delphi developers using TMS products.  While there has already been the usual flow of product update releases with new features & improvements, so far we also released 3 new products in 2022: TMS MemInsight This brings run-time memory allocation inspection, exception call stack logging, thread inspection and more. The unique angle of TMS MemInsight is that it gives you a run-time view on what is happening in your application as opposed to tools that only provide the information when the application closes, or worse, crashes. This gives the Delphi developer a powerful tool in the hands to inspect, analyze and improve where possible the memory allocation in applications.   GraphQL for Delphi When your applications work with GraphQL, whether it is at the client side or at the server side, our full GraphQL spec-compliant library for Delphi, empowers you to build applications that take advantage of GraphQL. GraphQL is rapidly getting traction as alternative or something to add in addition to classic REST API endpoints for data access. It empowers the client application to control the data communication. With GraphQL for Delphi, you can use the library for creating servers that respond correct to GraphQL requests. Watch the introduction webinar again here. GraphQL for Delphi is available stand-alone or as part of TMS ALL-ACCESS TMS FNC AppTools This is the latest addition to the FNC family of universal components. Universal components can be used in Delphi & C++Builder VCL, FireMonkey apps, Delphi TMS WEB Core apps and LCL Lazarus applications. TMS FNC AppTools focuses on typical desktop application use-cases. So far, it has a non-visual component for persisting the state of forms at the time the user quits the application to bring it back in exactly the same state when the user restarts. It has a component to temporarily password-lock an application to prevent non-authorized people to see sensitive data for example. And it has an automatic application updater component. With this component, it is possible to automatically update a Windows, macOS or Linux desktop application from updated files available on a HTTP(s) server. The component takes care of update version detection, update download and automatic replacement of existing files with updated files and restarting the new version of the application. Users already having our VIP ticket called TMS ALL-ACCESS received these 3 new products this quarter in addition to numerous product updates so far. This includes updates to TMS VCL UI Pack, TMS FNC Maps, TMS Business Subscription, TMS WEB Core and many more… In short, we deliver with TMS ALL-ACCESS literally what the name stands for: access to all our products, all our services, all our technical support and all our new upcoming new products or product update releases. If you did not yet obtain your TMS ALL-ACCESS VIP ticket or your overlooked to renew your TMS ALL-ACCES subscription for this year, contact our sales team to get the best possible deal to (re)enter the TMS ALL-ACCESS VIP area. Our sales team will offer you the best possible upgrade deal based on the existing products you might already have purchased in the past!

Read More

TMS WEB Core v1.9.8.0 Sentina for Delphi is here

We are pleased to announce the availability of TMS WEB Core v1.9.8.0 Sentina. The new release is a further step in making Object Pascal RAD component based web client application development from the Delphi IDE as productive and seamless as possible.  Among the new features are: New : TApplication.CreateFormDirect() method added + IDE integration for direct formsAllows to open forms not having a HTML template but use the project HTML template instead New : TWebListBox.ElementItemClassName property addedAllows to specify a CSS class for items in the TWebListBox New : Bootstrap hints for Bootstrap forms support addedWhen Form.CSSLibrary is set to cssBootstrap, controls will use Bootstrap hints Among the improvements are: Improved : Popup dialog close button positionThe dialog caption and the dialog close button in particular now look better Improved : Actualized materials icons design-time listThe design-time selectable material icons list is significantly extended Improved : High DPI support for design-time editors in Delphi 11 / 11.1When designing forms in Delphi 11 with high DPI form designer, control positioning is improved in resulting web app Other fixes & improvements Direct forms See for yourself what we mean with the new direct forms support in this new release. We created this video especially for you to show the difference between default forms that have a unique HTML template file per forms and direct forms that do not have a HTML template file and therefore are displayed within the context of the project HTML file. Get started Discover how you can create web client applications with zero deployment requirements and that work from a single application code-base on any machine or device that has a browser. Download the fully functional and not time-limited TMS WEB Core trial version to explore at your own pace how you can benefit from it!  For all users with an active TMS WEB Core license, TMS WEB Core v1.9.8.0 Sentina is a free update. If you have an expired license, login on our website to find the best upgrade option or contact our sales by email. 

Read More

Introducing TMS FNC AppTools

We are proud to announce a new member of the TMS FNC family: TMS FNC AppTools!  What is TMS FNC AppTools? Compared to the rest of the FNC family (that is the family of our universal components), TMS FNC AppTools is a little bit different. It revolves exclusively around desktop application development! The reason for this is simple: desktop and mobile applications are unalike and some functionalities/features make no sense or restricted in mobile environments. This way we can fully focus on desktop specific needs. What is included? Let’s take a look at what is included in this first release! TTMSFNCAppUpdate Manage automatic internet based application updates. You can use HTTPS based locations for secure downloads. Username and password protected downloads are also supported! The entry point to the automatic update is an .INF control file. By calling TTMSFNCAppUpdate.NewVersionAvailable the component will download and look at the contents of the control file. A single control file can be used to handle the updates for 3 supported platforms at the same time. This is achieved by a platform suffix (= win, macos or linux): [update_platform] keywords [files_platform] count=N [file1_platform] keywords … [fileN_platform] keywords The TTMSFNCAppUpdate component will automatically scan the control file for the platform it is running on, which means the platform specific suffix is always needed. TTMSFNCAppUpdate gives huge flexibility after the control file has been read. When NewVersionAvailable is called, the FileList collection property will be filled with the contents of the control file. This allows you to freely remove or modify the file descriptors before continuing with the update. procedure TForm1.Button1Click(Sender: TObject); begin   if TMSFNCAppUpdate1.NewVersionAvailable then   begin     if TMSFNCAppUpdate1.FileList.Count > 0 then       TMSFNCAppUpdate1.FileList[0].URL := ‘newdownloadurl’;     TMSFNCAppUpdate1.StartUpdate;   end; end; This becomes a lot simpler if you don’t need to change the file descriptors afterwards. Just call DoUpdate which will internally use NewVersionAvailable and StartUpdate and run the whole process at once. TTMSFNCAppUpdate also supports predefined and custom prefixes that will be replaced in the path related keywords. For example: {APP} stands for the application folder. For custom prefixes you can implement the OnCustomPrefix event! Curious to see it in action? Check our first video we prepared: TTMSFNCAppFormPersist With this component you can automatically persist and restore your application windows’ position, this way the application will open all its windows where you left them. It’s also possible to save and load the position programmatically: procedure TForm1.restoreBtnClick(Sender: TObject); var   afp: TTMSFNCAppFormPersist; begin   afp := TTMSFNCAppFormPersist.Create(Self);   afp.FileName := ‘./temp_settings.ini’;   afp.LoadFormSettings;   afp.Free; end; procedure TForm1.saveBtnClick(Sender: TObject); var   afp: TTMSFNCAppFormPersist; begin   afp := TTMSFNCAppFormPersist.Create(Self);   afp.FileName := ‘./temp_settings.ini’;   afp.SaveFormSettings;   afp.Free; end; TTMSFNCAppLock Keep your current workflow and sensitive data hidden by password locking your running application when needed or if it has been idling for a while. After locking all application windows become minimized and hidden. To unlock, click the minimized application icon and use the default unlock dialog. Alternatively a custom unlocking mechanism can be used by implementing the OnQueryUnlock event. It’s also possible to unlock the application automatically by calling the Unlock method.  procedure TForm1.Button1Click(Sender: TObject); begin   //Unlock automatically after 30 seconds   Timer1.Interval := 30000;   Timer1.Enabled := True;   TMSFNCAppLock1.Lock; end; procedure TForm1.Timer1Timer(Sender: TObject); begin   Timer1.Enabled := False; […]

Read More

Custom extensibility for your Miletus application

One of the new features of TMS WEB Core v1.9.7.0 was custom extensibility for Miletus applications. But what is that exactly? To put it simply, if you are after a native API we did not cover or you have custom routines you’d like to move separately you can take advantage of dynamic libraries and write your own extensions! How it works? As the intro suggests a custom dynamic library will be needed. We’ve built in support for 4 different method types that can be used in dynamic libraries to execute them directly from a Miletus application. These are the following: procedure MyProcedureWithParameter(AData: PChar); cdecl; procedure MyProcedureWithoutParameter; cdecl; function MyFunctionWithParameter(AData: PChar): PChar; cdecl; function MyFunctionWithoutParameter: PChar; cdecl; And the corresponding promises to execute these methods are: //Resolves with nil in case of await() function ExecProc(ALibraryPath: string; AProc: string; AData: string): TJSPromise;  function ExecProc(ALibraryPath: string; AProc: string): TJSPromise; //Resolves with a string in case of await() function ExecFunc(ALibraryPath: string; AFunc: string; AData: string): TJSPromise; function ExecFunc(ALibraryPath: string; AFunc: string): TJSPromise; It’s also possible to assign a callback that can be used to send custom messages to the Miletus application at any time. The only requirement for this is to implement RegisterCallback: type   TCallback = procedure(AMessageID: Integer; AData: PChar); cdecl; var   MyCallback: TCallBack; const    MYID = 123; procedure RegisterCallback(AFunction: Pointer); cdecl; begin   @MyCallback := AFunction; end; procedure MyProcedure; cdecl; begin   //Do something and call MyCallback   MyCallback(MYID, ‘{“Name”: “My data”, “Value”: “This is my JSON formatted data”}’); end; To capture the messages sent via the callback, use the MiletusCommunication.OnCustomMessage event. And of course let’s not forget that you can load a library by calling LoadLibrary(ALibraryPath: string) and unload it by UnloadLibrary(ALibraryPath). With all the puzzle pieces layed out, let’s see how to arrange them into a nice picture. Let’s see an example In our small example we’ll take a look at how to expose the GetUserNameW Windows API to a Miletus application. Keep in mind this is for Windows only! If you want to extend your dynamic library to get the current username for macOS or Linux too, you’ll need to use/implement the OS specific calls for those platforms as well. After creating a new dynamic library project in the Delphi IDE we’ll see an empty template. From here we only need to add one function that returns the result of GetUserName from the Winapi.Windows unit. library DemoLib; uses   System.SysUtils,   System.Classes,   Winapi.Windows; {$R *.res} function GetCurrentUsername: PChar; cdecl; var   buf: array[0..255] of Char;   bufsize: DWORD; begin   bufsize := SizeOf(buf);   GetUserName(buf, bufsize);   Result := buf; end; exports   GetCurrentUsername; begin end. The next step is to use this newly created library from our Miletus application. To keep the application simple, we’ll add a TWebLabel and use that to greet the user when the application starts. As mentioned above we can call the methods directly from the dynamic library via promises. This means we’ll need to mark the TMiletusForm.OnCreate event implementation as [async], which allows us to await the results of our async calls. [async] procedure MiletusFormCreate(Sender: TObject); Now we can use the TMiletusForm.OnCreate implementation to await the LoadLibrary and ExecFunc promises. LoadLibrary resolves with a Boolean value which indicates success of the library loading. ExecFunc resolves with a string that is the result from the DLL. […]

Read More

Automatically work with data backup in the cloud from your Delphi app

Automatically accessing files in cloud storage, making backups, sharing files with other users, distributing application resources via a cloud storage service … all these use-cases became a common practice in recent years. And with TMS FNC Cloud Pack, this becomes easy and seamless to add it to your Delphi VCL Windows applications, cross-platform FireMonkey applications for Windows, macOS, iOS, Android and Linux or TMS WEB Core web client applications. Our colleague Holger Flick explains how you can easily automate access to files stored in the cloud, on the biggest and most well-known cloud storage service providers. What’s more, when you write code once for a given cloud storage service, you can, with just switching properties, change to another cloud storage service provider and use 100% the same code. This includes Dropbox, Google Drive, Microsoft OneDrive, Hubic, Box, … This way, you can even let your end-users decide with what cloud storage service they want to work.  See how it works step by step in this new “How it works with Holger” video: Get started today Discover how TMS FNC Cloud Pack can save you tons of work and start taking advantage of cloud services seamlessly. TMS FNC Cloud Pack can be used simultaneously on these frameworks TMS FNC Cloud Pack can be used simultaneously on these operating systems/browsers TMS FNC Cloud Pack can be used simultaneously on these IDEs

Read More