【发布时间】: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({})
}
我不知道如何让我在服务上拥有的过滤器应用于我拥有的图表组件
【问题讨论】:
-
请发布您目前尝试过的代码,并阅读how to write a good question on StackOverflow 上的建议。
标签: dc.js crossfilter