Skip to main content
Technology

Visualising South African Procurement Data by Sector: An Embeddable Bar Chart Widget

The Tenders-SA Sector Trends widget renders an interactive SVG bar chart showing tender volume and value across procurement sectors. No external chart libraries, lazy-loaded, and open source.

Why Visualise Tender Data by Sector?

South African government procurement is distributed across dozens of sectors — construction, information technology, healthcare, transportation, security services, facilities management, and many more. For suppliers deciding where to focus their bidding efforts, understanding which sectors have the highest tender volumes and values is a strategic input. For industry analysts, it reveals where public spending is flowing.

The Sector Trends widget (github.com/Tenders-SA/widget-sector-trends

) renders this data as an interactive bar chart that you can embed on any website. It is an open-source, zero-dependency JavaScript widget that draws inline SVG bar charts — no external charting library required. This makes it exceptionally lightweight and fast to render.

This sector-level view complements the province-level heatmap widget: one axis of analysis is geographic, the other is by industry. Together they let a visitor answer two different but related questions — where is procurement activity concentrated, and what kind of work is it? A supplier operating in facilities management, for instance, might use the sector chart to confirm that their sector remains active nationally before drilling into which provinces to focus on using the heatmap.

What Data Does the Widget Display?

The widget fetches data from the /api/widgets/sector-trends endpoint, which aggregates active tenders by procurement sector. Each sector is represented as a horizontal bar:

FieldTypeDescription
sectorstringProcurement sector name (e.g. 'Construction', 'IT & Technology')
tenderCountnumberNumber of active tenders in the sector
totalValuenumberTotal combined value of tenders in the sector (ZAR)

The widget shows both a value bar (total contract value) and a count label for each sector. Bars are colour-coded using the Tenders-SA brand palette and scale proportionally to the maximum value in the dataset.

Because the bars scale relative to the largest sector in the current view, the chart automatically adapts whether you are looking at national data or a single filtered province. A province with a small overall tender volume still produces a readable, proportionate chart rather than a set of nearly invisible bars, because the scale is always relative to that view's own maximum rather than a fixed national benchmark.

Technical Architecture

The Sector Trends widget is the most technically sophisticated of the four public widgets. It uses several browser APIs that the simpler widgets do not:

Inline SVG Rendering

The chart is rendered entirely with SVG elements — rect for bars, text for labels, line for grid lines. This means there are no dependencies on charting libraries like Chart.js, D3.js, or Recharts. The rendering code in renderer.ts calculates bar dimensions, positions labels, and draws tooltip elements directly using the SVG DOM API.

This approach keeps the bundle size around 7 KB and eliminates the need for canvas or WebGL, which makes the widget suitable for use in environments where heavy DOM manipulation is undesirable.

Lazy Loading with IntersectionObserver

The widget uses the IntersectionObserver API to defer all network requests and rendering until the widget container is visible in the viewport. When a page loads with the widget below the fold, the widget shows a CSS-animated loading skeleton and only makes the API call once the container scrolls into view.

This has two benefits: it avoids unnecessary network requests for off-screen content, and it prevents layout shift by reserving space for the widget skeleton from the moment the script loads.

Responsive Resizing with ResizeObserver

The widget uses ResizeObserver to detect when its container changes size — for example, when a user rotates their phone from portrait to landscape, or when a responsive layout reflows. When a resize is detected, the widget clears the current SVG, recalculates dimensions, and re-renders the chart. This ensures the chart always fills its available space without distortion.

Taken together, these three techniques — inline SVG, IntersectionObserver, and ResizeObserver — reflect a design philosophy that runs through all of the Tenders-SA embeddable widgets: favour native browser APIs over external dependencies wherever possible. This keeps bundle sizes small, avoids version conflicts with whatever other JavaScript is already running on a host page, and reduces the surface area for bugs introduced by a third-party charting library's own release cycle.

Configuration Options

OptionTypeDefaultDescription
provincestring'all'Filter by province to show sector breakdown for a specific region
categorystring'all'Filter by parent category to narrow the sector view
limitnumber8Number of sectors to show (max 20)
theme'light''dark''light'
apiBasestring'https://tenders-sa.org
'
Base URL for the API endpoint

Embed Methods

Method 1: HTML Data Attribute

1<div
2  data-tendersa-sector-trends
3  data-theme="light"
4  data-limit="8"
5  data-province="all"
6></div>
7
8<script
9  src="https://cdn.jsdelivr.net/npm/@tenders-sa-org/widget-sector-trends/dist/widget-sector-trends.iife.js"
10  async
11></script>
HTML

Method 2: Programmatic (NPM)

1npm install @tenders-sa-org/widget-sector-trends
BASH
1import { SectorTrendsWidget } from '@tenders-sa-org/widget-sector-trends'
2
3const container = document.getElementById('chart-container')
4const widget = new SectorTrendsWidget(container, {
5  theme: 'dark',
6  limit: 12,
7  province: 'gauteng',
8})
9
10widget.render()
JAVASCRIPT

The render method is asynchronous and returns a promise that resolves once the data is fetched and the chart is drawn. The widget also supports an init() function for bulk initialisation if you have multiple widget containers on the same page:

1import { init } from '@tenders-sa-org/widget-sector-trends'
2
3// Initialise all [data-tendersa-sector-trends] elements on the page
4const widgets = init({ theme: 'dark' })
5
6// Each widget can be individually destroyed later
7widgets.forEach(w => w.destroy())
JAVASCRIPT

A Practical Walkthrough

Suppose an industry association for electrical contractors wants to show its members which procurement sectors have the strongest tender activity this quarter. Embedding the widget with data-category left at its default lets visitors see the full sector breakdown, while a province-specific version could be embedded on a regional chapter's page using the province configuration option. Because the widget lazy-loads via IntersectionObserver, it can be placed anywhere on a long content page — a newsletter archive, a resources page, a members' dashboard — without adding to the initial page load time for visitors who never scroll down to see it.

A developer embedding the chart inside a React or Vue application would typically use the programmatic API rather than the data-attribute method, since it gives explicit control over the widget's lifecycle alongside the framework's own component lifecycle. Calling widget.render() inside a mount hook and widget.destroy() inside an unmount hook ensures the ResizeObserver and IntersectionObserver instances are cleaned up properly when the component is removed from the page, avoiding memory leaks in long-lived single-page applications.

Performance and Browser Support

  • Bundle size: approximately 7 KB (minified and gzipped)
  • All modern browsers with IntersectionObserver and ResizeObserver support (Chrome 61+, Firefox 68+, Safari 12.1+, Edge 79+)
  • The chart SVG scales cleanly to 2x and 3x display resolutions because it uses vector graphics, not raster images
  • The API endpoint (/api/widgets/sector-trends) is ISR-cached with 3600-second revalidation, so repeated views of the same sector data are served from the Edge

The Open Source Package

The Sector Trends widget is published as @tenders-sa-org/widget-sector-trends on npm and is open source under the MIT license. The source code is available at github.com/Tenders-SA/widget-sector-trends

.

The repository includes TypeScript source code with exported type definitions, the full SVG renderer implementation, a tsup build pipeline (ESM, CJS, and IIFE bundles), and utility functions for currency formatting and sector colour mapping.

Use Cases

  • Industry publications — Show readers which procurement sectors are most active in a given quarter.
  • Business strategy pages — Help readers decide which sectors to target by displaying comparative tender volume and value.
  • District and provincial development sites — Display sector breakdowns for a specific province, showing where local procurement spending is concentrated.
  • Research and academic projects — Embed live sector data in research portals studying public procurement patterns.

Getting Started

Add the widget to any page with the data-attribute HTML snippet above. The full source code, documentation, and issue tracker are at github.com/Tenders-SA/widget-sector-trends

. For direct API access, the endpoint at /api/widgets/sector-trends returns the sector aggregation data in JSON format.

If your site already embeds one of the other Tenders-SA widgets, adding the Sector Trends chart alongside it is straightforward since all four widgets share the same configuration conventions — theme, apiBase, and a consistent data-attribute naming pattern. This consistency means a developer who has integrated one widget can typically add a second without re-reading the full documentation from scratch.

Tags

WidgetData VisualisationSVG ChartsOpen SourceGovernment TendersSector Analysis
Relevant Tender Opportunities

Based on this article's topics, here are some current tenders that might interest you

Professional, Scientific and Technical Activities

Feasibility Study on Hydrogen-Powered Mining Equipment Conversion using Hydrogen Combustion Technology for Surface and Underground Mining.

South African National Energy Development Institute
Gauteng
02 Sept 2026
26d left
Administrative and Support Activities

VIRTUALIZATION TECHNOLOGY REQUIREMENTS AND CAPABILITIES FOR SABC

South African Broadcasting Corporation Limited
National
28 Aug 2026
21d left
Computer Programming, Consultancy and Related Activities

REQUEST FOR INFORMATION: CLOUD-HOSTED OBSERVABILITY SOLUTION FOR THE ROAD ACCIDENT FUND (RAF) TO SUPPORT ENTERPRISE-WIDE MONITORING, ANALYTICS AND OPERATIONAL INTELLIGENCE ACROSS ITS HYBRID TECHNOLOGY ENVIRONMENT

Road Accident Fund (RAF)
Gauteng
26 Aug 2026
19d left
Services: Professional

APPOINTMENT OF A SERVICE PROVIDER TO ROLL OUT AND IMPLEMENT A FOUNDRY TRAINING AND FURNACE REPAIRS PROJECT AT THE DOWNSTREAM ALUMINIUM CENTRE FOR TECHNOLOGY (DACT) TO IMPROVE METAL BENEFICIATION SKILLS FOR A PERIOD OF SIX MONTHS.

Kwazulu Natal - Economic Development, Tourism and Environ Affairs
KwaZulu-Natal
25 Aug 2026
18d left
Services: Professional

Job grading, remuneration benchmark, and employee engagement services Tender for Technology Innovation Agency

Technology Innovation Agency
National
24 Aug 2026
17d left
Civil Engineering

APPOINTMENT OF A SUITABLE CIDB GRADE 1SL (OR HIGHER) SERVICE PROVIDER TO REMOVE, SUPPLY, DELIVER AND INSTALL STEEL TRELLIS AND STEEL BURGLAR GATES REINFORCEMENTS TO IMPROVE SECURITY AT ST JOHNS COLLEGE TECHNOLOGY AND INNOVATION HUB

National Research Foundation
Eastern Cape
20 Aug 2026
13d left

Want to see all available tenders?

Browse All Tenders →
AI-Powered Matching
Never Miss a Perfect Tender Again
Our AI analyzes thousands of tenders and finds the ones YOUR company can actually win
AI Match Scoring for every tender
Instant alerts for 85%+ matches
B-BBEE level optimization
Document readiness checks

Share this article

Visualising South African Procurement Data by Sector: An Embeddable Bar Chart Widget

The Tenders-SA Sector Trends widget renders an interactive SVG bar chart showing tender volume and value across procurement sectors. No external chart libraries, lazy-loaded, and open source.

https://www.tenders-sa.org/blog/embed-sector-trends-widget