Skip to content

D3.js Localization โ€” Locale-Aware Formatting and Internationalization

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about D3.js Localization. We cover key concepts, practical examples, and best practices to help you master this topic.

D3.js localization formats numbers, currencies, dates, and times according to locale conventions using d3.formatLocale and d3.timeFormatLocale.

What You'll Learn

By the end of this guide, you will use locale-specific number formatting, format dates according to local conventions, create custom locale definitions, format currencies for different regions, and build internationalized charts.

Why Localization Matters

Global users expect data in their local format. In Durga Antivirus Pro, the dashboard shows dates in the user's locale and threat scores with local number formatting.

Default Number Formatting

d3.format(',.2f')(12345.6789);
// '12,345.68' (English locale)

d3.format('($.2f')(12345.6789);
// '$12,345.68'

Creating a Locale

var deLocale = d3.formatLocale({
    decimal: ',',
    thousands: '.',
    grouping: [3],
    currency: ['', '\u00a0\u20ac']
});

deLocale.format(',.2f')(12345.6789);
// '12.345,68'

deLocale.format('$,.2f')(12345.6789);
// '12.345,68 โ‚ฌ'

Date Localization

var deTime = d3.timeFormatLocale({
    dateTime: '%A, der %e. %B %Y, %X',
    date: '%d.%m.%Y',
    time: '%H:%M:%S',
    periods: ['AM', 'PM'],
    days: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
    shortDays: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
    months: ['Januar', 'Februar', 'Mรคrz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
    shortMonths: ['Jan', 'Feb', 'Mรคr', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
});

deTime.format('%B %Y')(new Date());
// 'Januar 2026'

Formatting Currencies

var formats = {
    'en-US': d3.formatLocale({ decimal: '.', thousands: ',', grouping: [3], currency: ['$', ''] }),
    'de-DE': d3.formatLocale({ decimal: ',', thousands: '.', grouping: [3], currency: ['', ' โ‚ฌ'] }),
    'ja-JP': d3.formatLocale({ decimal: '.', thousands: ',', grouping: [3], currency: ['ยฅ', ''] })
};

formats['de-DE'].format('$,.2f')(12345.67);
// '12.345,67 โ‚ฌ'

Common Mistakes

1. Forgetting That Locale Formatting Only Affects Display

Locale formatting changes how values appear, not their underlying numeric value. Charts still use raw numbers.

2. Not Matching Locale to User Preference

Hardcoding a locale ignores user settings. Detect locale from the browser or user profile.

3. Mixing Locale Formats in One Chart

Chart axis labels, tooltips, and legends should use the same locale for consistency.

4. Incorrect Grouping Arrays

The grouping array defines digit groups from right to left. [3] means groups of 3. [3, 2] means the first group from the right has 3, the next has 2.

5. Not Providing Fallback Formatting

If a locale definition is missing properties, D3 falls back to defaults. Provide complete definitions for consistent formatting.

Practice Questions

Q1: What does d3.formatLocale return? A: A locale object with format and formatPrefix methods that use the specified decimal, thousands, and grouping settings.

Q2: How do you format a number as German currency? A: Create a German locale with decimal comma and thousands dot, then use format('$,.2f').

Q3: What is the difference between d3.format and d3.formatDefaultLocale? A: d3.format uses the default locale. d3.formatDefaultLocale changes the default locale globally.

Q4: How do you format dates in French? A: Create a d3.timeFormatLocale with French day and month names, then use timeFormat.

Q5: What happens if a locale definition is incomplete? A: Missing properties fall back to the US English defaults.

Challenge: Build a multi-country dashboard. Users select a locale from a dropdown. All numbers, dates, and currencies update to match the selected locale.

FAQ

Can I use the browser's Intl API instead of D3 locale?

Yes. D3 locale predates modern Intl support. Use Intl.NumberFormat and Intl.DateTimeFormat for simpler cases.

Does D3 include built-in locale definitions?

No. D3 provides locale factory functions. You must provide the locale data or use a third-party library like d3-locale.

How do I detect the user's locale?

Use navigator.language in the browser. It returns a BCP 47 language tag like 'en-US' or 'de-DE'.

Can I change the locale after rendering?

Yes. Re-format your data and update the DOM with new formatted values using transition.

What is formatPrefix?

It formats numbers with SI prefixes (k, M, G, etc.) using locale-specific separator positions.

Try It Yourself

Build a locale switcher that changes number and date formatting.

<!DOCTYPE html>
<html>
<head>
    <title>Locale Switcher</title>
    <style>
        body { font-family: sans-serif; padding: 20px; }
        select, button { padding: 8px; margin: 8px 0; }
        .card { border: 1px solid #ddd; padding: 15px; margin: 10px 0; border-radius: 8px; max-width: 400px; }
        .label { color: #666; font-size: 12px; text-transform: uppercase; }
        .value { font-size: 18px; font-weight: bold; margin: 4px 0; }
    </style>
</head>
<body>
<h2>Locale Formatting Demo</h2>
<select id="locale">
    <option value="en-US">English (US)</option>
    <option value="de-DE">German (DE)</option>
    <option value="ja-JP">Japanese (JP)</option>
</select>
<button onclick="updateLocale()">Update</button>
<div class="card">
    <div class="label">Number</div>
    <div class="value" id="numDisplay">12,345,678.90</div>
</div>
<div class="card">
    <div class="label">Currency</div>
    <div class="value" id="curDisplay">$12,345.68</div>
</div>
<div class="card">
    <div class="label">Date</div>
    <div class="value" id="dateDisplay">January 1, 2026</div>
</div>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
var localeData = {
    'en-US': { decimal: '.', thousands: ',', grouping: [3], currency: ['$', ''] },
    'de-DE': { decimal: ',', thousands: '.', grouping: [3], currency: ['', ' โ‚ฌ'] },
    'ja-JP': { decimal: '.', thousands: ',', grouping: [3], currency: ['ยฅ', ''] }
};

var months = {
    'en-US': ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
    'de-DE': ['Januar', 'Februar', 'Mรคrz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
    'ja-JP': ['1ๆœˆ', '2ๆœˆ', '3ๆœˆ', '4ๆœˆ', '5ๆœˆ', '6ๆœˆ', '7ๆœˆ', '8ๆœˆ', '9ๆœˆ', '10ๆœˆ', '11ๆœˆ', '12ๆœˆ']
};

function updateLocale() {
    var loc = document.getElementById('locale').value;
    var locale = d3.formatLocale(localeData[loc]);
    var num = 12345678.9;
    var cur = 12345.6789;
    var date = new Date(2026, 0, 1);

    document.getElementById('numDisplay').textContent = locale.format(',.2f')(num);
    document.getElementById('curDisplay').textContent = locale.format('$,.2f')(cur);

    var m = months[loc][date.getMonth()];
    document.getElementById('dateDisplay').textContent = m + ' ' + date.getDate() + ', ' + date.getFullYear();
}
updateLocale();
</script>
</body>
</html>

What's Next

Make visualizations responsive to container size.

Responsive โ€” Responsive D3.js charts. Zoom Pan โ€” Zoom and pan behavior.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro