From 89b03a8a9df8544b6e26980725d7f2d452d15a35 Mon Sep 17 00:00:00 2001 From: Adilson Schmitt Junior Date: Thu, 2 Feb 2017 15:27:15 -0200 Subject: [PATCH] Adding localization capabilities --- README.md | 31 +++++++++++++++++++++++++++- src/calendar-heatmap.js | 45 ++++++++++++++++++++++++++++++++--------- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index fdf0776..89567f4 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,23 @@ A [d3.js](https://d3js.org/) heatmap representing time series data. Inspired by | startDate | Date to start heatmap at | 1 year ago | no | | colorRange | Minimum and maximum chart gradient colors | ['#D8E6E7', '#218380'] | no | | tooltipEnabled | Option to render a tooltip | true | no | -| tooltipUnit | Unit to render on the tooltip | 'contributions' | no | +| tooltipUnit | Unit to render on the tooltip, can be object for pluralization control | 'contributions' | no | | legendEnabled | Option to render a legend | true | no | | onClick | callback function on day click events (see example below) | null | no | +| locale | Object to translate every word used, except for tooltipUnit | see below | no | + +### locale default object + +```javascript +{ + months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], + No: 'No', + on: 'on', + Less: 'Less', + More: 'More' +} +``` ## Dependencies @@ -60,6 +74,21 @@ var chart1 = calendarHeatmap() chart1(); // render the chart ``` +### control unit pluralization + +```javascript +var chart1 = calendarHeatmap() + .data(chartData) + .tooltipUnit( + [ + {min: 0, unit: 'contribution'}, + {min: 1, max: 1, unit: 'contribution'}, + {min: 2, max: 'Infinity', unit: 'contributions'} + ] + ); +chart1(); // render the chart +``` + ## Pull Requests and issues ...are very welcome! diff --git a/src/calendar-heatmap.js b/src/calendar-heatmap.js index 4982451..8eaa492 100644 --- a/src/calendar-heatmap.js +++ b/src/calendar-heatmap.js @@ -4,8 +4,6 @@ function calendarHeatmap() { var width = 750; var height = 110; var legendWidth = 150; - var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; - var days = ['S', 'M', 'T', 'W', 'T', 'F', 'S']; var selector = 'body'; var SQUARE_LENGTH = 11; var SQUARE_PADDING = 2; @@ -21,6 +19,14 @@ function calendarHeatmap() { var legendEnabled = true; var onClick = null; var weekStart = 0; //0 for Sunday, 1 for Monday + var locale = { + months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], + No: 'No', + on: 'on', + Less: 'Less', + More: 'More' + }; // setters and getters chart.data = function (value) { @@ -78,6 +84,12 @@ function calendarHeatmap() { return chart; }; + chart.locale = function (value) { + if (!arguments.length) { return locale; } + locale = value; + return chart; + }; + function chart() { d3.select(chart.selector()).selectAll('svg.calendar-heatmap').remove(); // remove the existing chart, if it exists @@ -165,16 +177,16 @@ function calendarHeatmap() { .attr('fill', function (d) { return d; }); legendGroup.append('text') - .attr('class', 'calendar-heatmap-legend-text') + .attr('class', 'calendar-heatmap-legend-text calendar-heatmap-legend-text-less') .attr('x', width - legendWidth - 13) .attr('y', height + SQUARE_LENGTH) - .text('Less'); + .text(locale.Less); legendGroup.append('text') - .attr('class', 'calendar-heatmap-legend-text') + .attr('class', 'calendar-heatmap-legend-text calendar-heatmap-legend-text-more') .attr('x', (width - legendWidth + SQUARE_PADDING) + (colorRange.length + 1) * 13) .attr('y', height + SQUARE_LENGTH) - .text('More'); + .text(locale.More); } dayRects.exit().remove(); @@ -184,7 +196,7 @@ function calendarHeatmap() { .attr('class', 'month-name') .style() .text(function (d) { - return months[d.getMonth()]; + return locale.months[d.getMonth()]; }) .attr('x', function (d, i) { var matchIndex = 0; @@ -197,7 +209,7 @@ function calendarHeatmap() { }) .attr('y', 0); // fix these to the top - days.forEach(function (day, index) { + locale.days.forEach(function (day, index) { index = formatWeekday(index); if (index % 2) { svg.append('text') @@ -210,10 +222,25 @@ function calendarHeatmap() { }); } + function pluralizedTooltipUnit (count) { + if ('string' === typeof tooltipUnit) { + return (tooltipUnit + (count === 1 ? '' : 's')); + } + for (var i in tooltipUnit) { + var _rule = tooltipUnit[i]; + var _min = _rule.min; + var _max = _rule.max || _rule.min; + _max = _max === 'Infinity' ? Infinity : _max; + if (count >= _min && count <= _max) { + return _rule.unit; + } + } + } + function tooltipHTMLForDate(d) { var dateStr = moment(d).format('ddd, MMM Do YYYY'); var count = countForDate(d); - return '' + (count ? count : 'No') + ' ' + tooltipUnit + (count === 1 ? '' : 's') + ' on ' + dateStr + ''; + return '' + (count ? count : locale.No) + ' ' + pluralizedTooltipUnit(count) + ' ' + locale.on + ' ' + dateStr + ''; } function countForDate(d) {