DC.js - Custom ordering of ordinal scale line chart

穿精又带淫゛_ 提交于 2020-01-25 04:14:06

问题


Please forgive my english.

I am trying to create a line chart with ordinal scale and brushon function. I successfully set brushing on ordinal thanks to this method : https://dc-js.github.io/dc.js/examples/brush-ordinal.html And now I need to set the x-axis values order.

My data is like this :

    [{"id_commune":4,"datation":"-30/-20","effectif":0.09,"commune":"Frejus","lieu_dit":"Les Aiguieres","departement":"83","pays":"FR","longitude":6.73703399,"latitude":43.433152,"quantite":1,"id_datation":1},
        {"id_commune":4,"datation":"-20/-10","effectif":0.09,"commune":"Frejus","lieu_dit":"Les Aiguieres","departement":"83","pays":"FR","longitude":6.73703399,"latitude":43.433152,"quantite":1,"id_datation":2},
        {"id_commune":4,"datation":"-10/1","effectif":0.09,"commune":"Frejus","lieu_dit":"Les Aiguieres","departement":"83","pays":"FR","longitude":6.73703399,"latitude":43.433152,"quantite":1,"id_datation":3},
    {"id_commune":7,"datation":"20/30","effectif":0.33,"commune":"Nimes","lieu_dit":"Solignac","departement":"30","pays":"FR","longitude":4.36005399,"latitude":43.836699,"quantite":1,"id_datation":6},{"id_commune":6,"datation":"20\/30","effectif":0.6,"commune":"Muralto","lieu_dit":"Liverpool b","departement":"TI","pays":"CH","longitude":8.80560809,"latitude":46.1729618,"quantite":1,"id_datation":6},
{"id_commune":4,"datation":"20/30","effectif":0.09,"commune":"Frejus","lieu_dit":"Les Aiguieres","departement":"83","pays":"FR","longitude":6.73703399,"latitude":43.433152,"quantite":1,"id_datation":6},{"id_commune":1,"datation":"20/30","effectif":0.14,"commune":"Aislingen","lieu_dit":"NP","departement":"Lkr. Dillingen an der Donau BY","pays":"DE","longitude":10.4559987,"latitude":48.5065603,"quantite":1,"id_datation":6},]

My crossfilter dimension and group look like this :

var ndx = crossfilter(records)
var graphDim = ndx.dimension(function(d) {return d.datation});
var graphGroup = graphDim.group().reduceSum(function(d) {return d.effectif;});

And the chart :

lineChart
            .width(950)
            .height(350)
            .margins({top: 10, right: 50, bottom: 35, left: 30})
            .dimension(graphDim)            
            .keyAccessor(function(kv) { return  graphGroup.ord2int(kv.key); })
            .group(graphGroup)
            .x(d3.scaleLinear().domain(linear_domain))
            .xAxisLabel("Chronologie")
            .yAxisLabel("Effectif")
            .brushOn(true)
            .renderArea(true)
            .renderHorizontalGridLines(true)
            .renderVerticalGridLines(true)
            .elasticY(true)
            .yAxis().ticks(4);

Right now, I get this :

The result I am trying to accomplish is the same chart but with x-axis ticks values ordered like this : "-30/-20 -20/-10 -10/1 ..."

Any help appreciated. Thank you!


回答1:


Welcome to Stack Overflow. For future reference, it helps if you can include a reproducible example, for example a jsFiddle.

I understood what you were doing because I wrote the ordinal brushing example, but you didn't include all the code, so it wouldn't be clear to others.

Here is a fiddle with complete code, and here is the relevant code:

var graphDim = ndx.dimension(function(d) {return d.datation});
var graphGroup = graphDim.group().reduceSum(function(d) {return d.effectif;});        
graphGroup = ordinal_to_linear_group(sort_group(graphGroup, function(a, b) {
        return d3.descending(a.value, b.value);
    }));
    line = dc.lineChart('#line');
    var linear_domain = [-0.5, data.length - 0.5];
    line
        .width(950)
        .height(350)
        .margins({top: 10, right: 50, bottom: 35, left: 30})
        .dimension(graphDim)            
        .keyAccessor(function(kv) { return  graphGroup.ord2int(kv.key); })
        .group(graphGroup)
        .x(d3.scaleLinear().domain(linear_domain))
        .xAxisLabel("Chronologie")
        .yAxisLabel("Effectif")
        .brushOn(true)
        .renderArea(true)
        .renderHorizontalGridLines(true)
        .renderVerticalGridLines(true)
        .elasticY(true)

    line.yAxis().ticks(4);

    line.xAxis()
        .tickValues(d3.range(data.length))
        .tickFormat(function(d) { return graphGroup.int2ord(d); });

Here is the (bad) result:

As its name implies, sort_group() creates a fake group sorted by the ordering function. Right now it's sorting by value, from highest to lowest:

sort_group(graphGroup, function(a, b) {
        return d3.descending(a.value, b.value);
    })

It looks like you want to sort by the numeric value of the first part of each key. You can change the sort accordingly:

sort_group(graphGroup, function(a, b) {
        return d3.ascending(+a.key.split('/')[0], +b.key.split('/')[0]);
    })

This splits each key by /, then takes the first item ([0]), then converts it to a number (+), before using d3.ascending to specify sorting from low to high.

The result:

And a working version of the fiddle.



来源:https://stackoverflow.com/questions/58934827/dc-js-custom-ordering-of-ordinal-scale-line-chart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!