François
François

Reputation: 65

Use local months on dc.js barchart

I'm simply trying to use local months on the x-axis of a bar chart. First I would like to only represent months on x-axis and second I would like to have the months defined in localeFrance.

I have forked a fiddle but I can't make it work :https://jsfiddle.net/xjp2o0wt/6/

so here is my code. Thanks for your valuable help

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dashboard</title>
<link rel="stylesheet" href="dc.css">
</head>

<body>
<div id=chart>
  here
</div>
<script src="crossfilter.js"></script>
<script src="d3.js"></script>
<script src="dc.js"></script>
<script>
var localeFrance = d3.locale ({
        "decimal": "",
        "thousands": "",
        "grouping": [3],
        "currency": ["€ ", ""],
        "dateTime": "%a %b %e %X %Y",
        "date": "%d/%m/%Y",
        "time": "%H:%M:%S",
        "periods": ["AM", "PM"],
        "days": ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"],
        "shortDays": ["lun", "mar", "mer", "jeu", "ven", "sa", "dim"],
        "months": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembrr", "Octobre", "Novembre", "Decembre"],
        "shortMonths": ["Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aou", "Sep", "Oct", "Nov", "Dec"]
      });
var dateFormat_in = d3.time.format.utc("%Y-%m-%d");
data=[{year:2017, month:1, value:12},{year:2017, month:2, value:15},{year:2017, month:3, value:12},
        {year:2017, month:4, value:16},{year:2017, month:5, value:14}]
data.forEach(function(d) {
    d["date"] = dateFormat_in.parse(d["year"]+"-"+d["month"]+"-01");
    d["value"] = +d["value"];
});     

ndx = crossfilter(data);   
timeChart = dc.barChart("#chart");
monthDim = ndx.dimension(d => d3.time.month.utc(d["date"]));
monthGroup = monthDim.group().reduceSum(d=>d.value); 
minDate = monthDim.bottom(1)[0]["date"];
maxDate = monthDim.top(1)[0]["date"];
timeChart
        .width(480)
        .height(320)
        .margins({top: 5, right: 30, bottom: 20, left: 50})
        .dimension(monthDim)
        .group(monthGroup)   
        .x(d3.time.scale().domain([minDate, maxDate]))
        .xUnits(d3.time.months)
      //.xUnits(localeFrance.timeFormat("%b"))
        .elasticY(true)
        .centerBar(true).xAxisPadding(15).xAxisPaddingUnit('month')
        .gap(16)
        .yAxis().ticks(1);
dc.renderAll();
 </script>

Upvotes: 1

Views: 472

Answers (1)

Gordon
Gordon

Reputation: 20120

I may be mistaken, but d3 doesn't seem to build international locales into the bundle. I'm new to this stuff myself, so I relied on a few other answers on SO which provide a lot more detail:

Localization of d3.js (d3.locale example of usage)

Where can in find the locale objects for d3.js for different countries

How to make localization on months / days for D3js?

We can define the fr_FR locale like so:

var fr_FR = {
  "dateTime": "%A, le %e %B %Y, %X",
  "date": "%d/%m/%Y",
  "time": "%H:%M:%S",
  "periods": ["AM", "PM"],
  "days": ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
  "shortDays": ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
  "months": ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
  "shortMonths": ["janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."]
};
var frLocale = d3.locale(fr_FR);

Source: https://github.com/d3/d3-time-format/blob/master/locale/fr-FR.json

Now we need to tell the x axis to use the custom locale:

timeChart.xAxis()
     .tickFormat(frLocale.timeFormat('%B'))
     .ticks(d3.time.months);

We're also telling it to put ticks on the months; otherwise the d3 axis will try to draw a lot more.

Similarly we have to set xUnits to draw one bar per month (I see you have this in your question, but it was different in your fiddle):

timeChart
        .xUnits(d3.time.months)

Unfortunately dc.js takes its x domain very literally, so if you're using .centerBar(true) you also need to offset your min and max date:

  minDate = new Date(monthDim.bottom(1)[0]["date"]);
  minDate.setDate(15)
  maxDate = new Date(monthDim.top(1)[0]["date"]);
  maxDate.setDate(15)

Et voilà, you might say. :)

bar chart with french dates

Fork of your fiddle.

Upvotes: 1

Related Questions