【问题标题】:dc.js - apply filter on click of a buttondc.js - 单击按钮应用过滤器
【发布时间】:2018-10-04 10:05:40
【问题描述】:

有人知道如何通过单击按钮将过滤器应用于图表吗?假设我已经有了由保存搜索的维度和过滤器组成的对象,现在我想通过单击按钮应用该过滤器。

我正在 Angular 中执行此操作,我正在尝试创建一个可用于将过滤器应用于我的所有图表的服务。

这是我迄今为止尝试过的:

我有一个包含所有图表的组件

            this.patients = v;
        this.ndx = crossfilter(this.patients);
        this.cs.samplesGroup = this.ndx.dimension((d) => {
            return d.sampleId;
        }, true).group();

        const all = this.ndx.groupAll();

        var genderDim = this.ndx.dimension(function(d){ return d.gender;})
        var genderGroup = genderDim.group();

        var conditionDim = this.ndx.dimension(function(d){ 
            return d.conditions;
        });
        var conditionGroup = conditionDim.groupAll().reduce(this.reduceAdd, this.reduceRemove, this.reduceInitial).value();
        conditionGroup.all = function() {
            var newObject = [];
            for (var key in this) {
              if (this.hasOwnProperty(key) && key != "all") {
                newObject.push({
                  key: key,
                  value: this[key],
                });
              }
            }
            return newObject;
          }

        var conditionDim = this.ndx.dimension(function(d){ 
            return d.conditions;
        });

        var alanineInCerebralSpinalFluidDim = this.ndx.dimension(function(d){ return d.alanineInCerebralSpinalFluid;});
        var alanineInCerebralSpinalFluidGroup = alanineInCerebralSpinalFluidDim.group();

        var lactateInCerebralSpinalFluidDim = this.ndx.dimension(function(d){ return d.lactateInCerebralSpinalFluid;});
        var lactateInCerebralSpinalFluidGroup = lactateInCerebralSpinalFluidDim.group();

        var alanineInSerumOrPlasmaDim = this.ndx.dimension(function(d){ return d.alanineInSerumOrPlasma;});
        var alanineInSerumOrPlasmaGroup = alanineInSerumOrPlasmaDim.group();

        var lactateInVenousBloodDim = this.ndx.dimension(function(d){ return d.lactateInVenousBlood;});
        var lactateInVenousBloodGroup = lactateInVenousBloodDim.group();

        var choiceDilatedDim = this.ndx.dimension(function(d){ return d.choiceDilated;});
        var choiceDilatedGroup = choiceDilatedDim.group();

        var choiceHyperthrophicDim = this.ndx.dimension(function(d){ return d.choiceHyperthrophic;});
        var choiceHyperthrophicGroup = choiceHyperthrophicDim.group();

        var choiceLeftVentricularNonCompactionDim = this.ndx.dimension(function(d){ return d.choiceLeftVentricularNonCompaction;});
        var choiceLeftVentricularNonCompactionGroup = choiceLeftVentricularNonCompactionDim.group();

        var choiceEndocardialFibroElastosisDim = this.ndx.dimension(function(d){ return d.choiceEndocardialFibroElastosis;});
        var choiceEndocardialFibroElastosisGroup = choiceEndocardialFibroElastosisDim.group();

        this.charts = [
            new MitochondriaChart(
                'gender',
                'pie',
                genderDim,
                340,
                200,
                true,
                genderGroup,
            ),
            new MitochondriaChart(
                'alanineInCerebralSpinalFluid',
                'bar',
                alanineInCerebralSpinalFluidDim,
                340,
                200,
                true,
                alanineInCerebralSpinalFluidGroup,
                null,
                'Alanine [Moles/volume] in Cerebral spinal fluid',
                '# Samples',
            ),      
            new MitochondriaChart(
                'lactateInCerebralSpinalFluid',
                'bar',
                lactateInCerebralSpinalFluidDim,
                340,
                200,
                true,
                lactateInCerebralSpinalFluidGroup,
                null,
                'Lactate [Moles/volume] in Cerebral spinal fluid',
                '# Samples',
            ),
            new MitochondriaChart(
                'alanineInSerumOrPlasma',
                'bar',
                alanineInSerumOrPlasmaDim,
                340,
                200,
                false,
                alanineInSerumOrPlasmaGroup,
                null,
                'Alanine [Moles/volume] in Serum or Plasma',
                '# Samples',
            ),
            new MitochondriaChart(
                'lactateInVenousBlood',
                'bar',
                lactateInVenousBloodDim,
                340,
                200,
                false,
                lactateInVenousBloodGroup,
                null,
                'Lactate [Moles/volume] in Venous blood',
                '# Samples',
            ),
            new MitochondriaChart(
                'choiceDilated',
                'pie',
                choiceDilatedDim,
                340,
                200,
                false,
                choiceDilatedGroup,
            ),
            new MitochondriaChart(
                'choiceHyperthrophic',
                'pie',
                choiceHyperthrophicDim,
                340,
                200,
                false,
                choiceHyperthrophicGroup,
            ),
            new MitochondriaChart(
                'choiceLeftVentricularNonCompaction',
                'pie',
                choiceLeftVentricularNonCompactionDim,
                340,
                200,
                false,
                choiceLeftVentricularNonCompactionGroup,
            ),
            new MitochondriaChart(
                'choiceEndocardialFibroElastosis',
                'pie',
                choiceEndocardialFibroElastosisDim,
                340,
                200,
                false,
                choiceEndocardialFibroElastosisGroup,
            ),
            new MitochondriaChart(
                'conditions',
                'row',
                conditionDim,
                1050,
                800,
                true,
                conditionGroup,
                (dimension, filters) => {
                    dimension.filter(null);   
                    if (filters.length === 0)
                        dimension.filter(null);
                    else
                        dimension.filterFunction(function (d) {
                            if (difference(filters, d).length === 0) return true;
                            return false; 
                        });
                    return filters;  
                },
            ),

        ];

        dc.dataCount('.dc-data-count')
        .dimension(this.ndx)
        .group(all);

        dc.renderAll();

然后我有图表组件本身:

ngAfterViewInit(): void {
    if (this.data.type === "row") {
        this.initRowChart();
    } else if (this.data.type === "pie"){
        this.initPie();
    }else if (this.data.type === "bar"){
        this.initBarChart();
    }

    this.chart.on("filtered", (c) => {
        this.cd.detectChanges();
        this.cs.changes.next();
        this.ClinicalFilterService.setFilters(this.data.name, this.chart.filters());
    });

    this.chart.render();
    this.cd.detectChanges();
}

initPie() {
    this.chart = dc.pieChart(`.chart .${this.data.name}`)
        .width(this.data.width)
        .height(this.data.height)
        .innerRadius(30)
        .slicesCap(10)
        .dimension(this.data.dim)
        .group(this.data.group)
        .title(() => this.data.name);
    if(this.ClinicalFilterService.filters[this.data.name] !== undefined){
        this.ClinicalFilterService.filters[this.data.name].forEach(filter => {
            this.chart.filter(filter);
        })
    }      
    if (this.data.filterHandler !== null) {
        this.chart.filterHandler(this.data.filterHandler);
    }
}

initRowChart() {
    this.chart = dc.rowChart(`.chart .${this.data.name}`)                                                                           
                .width(this.data.width)
                .height(this.data.height)
                .group(this.data.group)
                .elasticX(true)
                .ordering(function(d){
                    let i = 0;
                    if(CONDITION_GROUPING[0].includes(d.key))
                        return i++;                       
                    else if(CONDITION_GROUPING[1].includes(d.key))
                        return 25 + i++;
                    else if(CONDITION_GROUPING[2].includes(d.key))
                        return 50 + i++;
                    else if(CONDITION_GROUPING[3].includes(d.key))
                        return 100 + i++;
                })
                .dimension(this.data.dim)
                .colors(d3.scale.ordinal().domain(["a","b","c","d"])
                                .range(["#d6e8f5","#85bae0", "#348ccb", "#25628e"]))
                .colorAccessor(function(d) { 
                    if(CONDITION_GROUPING[0].includes(d.key)) 
                        return "a";
                    else if(CONDITION_GROUPING[1]. includes(d.key))
                        return "b";
                    else if(CONDITION_GROUPING[2]. includes(d.key))
                        return "c";
                    else if(CONDITION_GROUPING[3]. includes(d.key))
                        return "d";
                    });
    if(this.ClinicalFilterService.filters[this.data.name]){
        this.ClinicalFilterService.filters[this.data.name].forEach(filter => {
            this.chart.filter(filter);
        })
    }        
    if (this.data.filterHandler !== null) {
        this.chart.filterHandler(this.data.filterHandler);
    }
}

initBarChart() {
    this.chart = dc.barChart(`.chart .${this.data.name}`)
        .width(this.data.width)
        .height(this.data.height)
        .x(d3.scale.linear().domain([0, 100]))
        .elasticY(true)
        .yAxisLabel(this.data.yAxisLabel)
        .xAxisLabel(this.data.xAxisLabel)
        .dimension(this.data.dim)
        .group(this.data.group);


    this.chart.yAxis().ticks(3);
    if(this.ClinicalFilterService.filters[this.data.name]){
        this.ClinicalFilterService.filters[this.data.name].forEach(filter => {
            this.chart.filter(filter);
        })
    }
    if (this.data.filterHandler !== null) {
        this.chart.filterHandler(this.data.filterHandler);
    }
}

现在我尝试创建一个保存过滤器对象的服务,当我更改它时,我想将其应用于我拥有的图表。

private filtersSource = new BehaviorSubject<any>({});
filters = this.filtersSource.asObservable();
chart: crossfilter.baseMixin;

private savedSearchesSource = new BehaviorSubject<any>({});
savedSearches = this.savedSearchesSource.asObservable();

setFilters(name, filter){
    let currentFilter = this.filtersSource.getValue();
    let newFilter = Object.assign({}, currentFilter, {[name]: filter});
    if(newFilter[name].length === 0){
        delete newFilter[name];
    }
    this.filtersSource.next(newFilter);
}

deleteFilter(name){
    let currentFilter = this.filtersSource.getValue();
    let newFilter = Object.assign({}, currentFilter);
    delete newFilter[name];
    this.filtersSource.next(newFilter);
}

clearFilters(){
    this.filtersSource.next({});
}

saveSearches(name){
    let currentSavedSearches = Object.assign({}, this.savedSearchesSource.getValue());
    let currentFilter = Object.assign({}, this.filtersSource.getValue());
    currentSavedSearches[name] = currentFilter;
    this.savedSearchesSource.next(currentSavedSearches);
}

applySavedSearches(savedFilterName) {
    let savedSearches = Object.assign({}, this.savedSearchesSource.getValue()[savedFilterName]);
    this.filtersSource.next(savedSearches);
}


ngOnDestroy() {
    this.filtersSource.next({})
}

我不知道如何让我在服务上拥有的过滤器应用于我拥有的图表组件

【问题讨论】:

标签: dc.js crossfilter


【解决方案1】:

你没有说你在应用过滤器时遇到了什么问题,但是这段代码看起来有问题:

if(this.ClinicalFilterService.filters[this.data.name]){
    this.ClinicalFilterService.filters[this.data.name].forEach(filter => {
        this.chart.filter(filter);
    })
}

这可能会起作用,因为chart.filter(value) 将在过滤器集内外切换该值。但是多次更换过滤器可能效率低下。

syntax for applying multiple filters 有点奇怪:

chart.filter([[value,value,value]]);

是的,一个包含单个数组的数组,其中包含值。不要问为什么。

实际上,这将切换每个值,就像您单击了每个值一样。所以replaceFilter 可能就是你想要的:

chart.replaceFilter([[value,value,value]]);

那你只需要打电话

chart.redrawGroup();

将过滤器更改应用于组中的所有图表。

【讨论】:

    猜你喜欢
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    相关资源
    最近更新 更多