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.

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.

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.

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/@tendersa/widget-sector-trends/dist/widget-sector-trends.iife.js"
10  async
11></script>
HTML

Method 2: Programmatic (NPM)

1npm install @tendersa/widget-sector-trends
BASH
1import { SectorTrendsWidget } from '@tendersa/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 '@tendersa/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

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 @tendersa/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.

Tags

WidgetData VisualisationSVG ChartsOpen SourceGovernment TendersSector Analysis
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