每次我的 behaviorSubject 更改其值时如何删除图表并创建一个新图表
How to remove a chart and create a new one each time that my behaviorSubject change its values
我遇到了一个问题,因为我正在尝试将有关国家/地区的一些结果显示到饼图 (HightCharts) 中。在 API 调用 Api 服务后,我将此信息分配给 BehaviorSubject。
第一次,我在我的 chartComponent 中收到信息,它创建了一个图表,但第二次我需要删除这个图表并创建一个新图表,因为用户可以通过按大陆和种类过滤的表单修改结果人口或 AreaInSqkm 等指标。
这是服务中的 Api 调用:
public dataObservable = this.data.asObservable();
private data = new BehaviorSubject<any>(null);
direction: String = "dsc";
public filters: any = {
continent : "All",
metric: "None",
quantity: 5,
};
url = "some URL";
constructor(private http : Http) { }
getCountries(){
return this.http.get(this.url)
.map(res=>res.json())
.map((data)=>data.geonames.filter((country)=>{
if(this.filters.continent !== "All"){
return country.continent == this.filters.continent
}else{
return country.continent
}
})
)
.map((data)=>{
if(this.filters.metric == "population"){
return this.sortByPopulation(data, this.direction).slice(0, this.filters.quantity)
}else if(this.filters.metric == "areaInSqKm"){
return this.sortByArea(data, this.direction).slice(0, this.filters.quantity)
}
return data.slice(0, this.filters.quantity);
})
.subscribe((data)=>{
this.setData(data);
})
}
sortByPopulation(data, direction){
if(direction =="asc"){
data.sort((a, b)=>{
return a["population"] - b["population"]
})
} else{
data.sort((a, b)=>{
return b["population"] - a["population"]
})
}
return data
}
sortByArea(data, direction){
if(direction =="asc"){
data.sort((a, b)=>{
return a["areaInSqKm"] - b["areaInSqKm"]
})
} else{
data.sort((a, b)=>{
return b["areaInSqKm"] - a["areaInSqKm"]
})
}
return data
}
updateFilters(filters){
this.filters = filters
}
setData(data){
this.data.next(data)
}
如您所见,我将数据作为 BehaviorSubject 的值传递,并且每次有人修改表单时我都会收到此值更改的信息。
稍后我在 chartComponent 中创建图表如下:
@Component({
selector: 'chart',
templateUrl: './chart.component.html',
styleUrls: ['./chart.component.scss']
})
export class ChartComponent implements OnInit, AfterViewInit {
element : any;
opts: Object = {};
container : any;
@Input()
values: Array<Object>;
getCountriesSubscription: Subscription = null;
chartValues: any = []
@ViewChild('chart') chart: ElementRef
constructor(
private renderer : Renderer2,
private api : ApiService,
private cdRef : ChangeDetectorRef
) { }
ngOnInit() {
}
ngAfterViewInit(){
this.getCountriesSubscription = this.api.dataObservable
.subscribe((data)=>{
if(data){
data.map((element)=>{
this.generateChartValues(element, this.api.filters.metric)
})
this.generateChartOptions(this.chartValues);
this.createChart()
this.cdRef.markForCheck();
console.log(this.chartValues[0])
}
})
}
createChart(){
this.container = this.renderer.createElement("div");
this.renderer.addClass(this.container, "mychart");
let chart = new Highcharts.Chart(this.container,this.opts)
this.renderer.appendChild(this.chart.nativeElement, this.container)
console.log(this.container)
this.cdRef.markForCheck();
}
generateChartOptions(chartValues){
this.opts = {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: `Countries in by ${this.api.filters.metric}`
},
series: [{
name: 'Total',
colorByPoint: true,
data: chartValues
}]
};
}
generateChartValues(data, metric){
if(metric == "population"){
this.chartValues.push({ name: data.countryName, y: parseInt(data.population) });
}
if(metric == "areaInSqKm"){
this.chartValues.push({ name: data.countryName, y: parseInt(data.areaInSqKm) });
}
if(metric == "None"){
this.chartValues.push({ name: data.countryName, y: 1});
}
}
}
<div #chart class="chartplace">
</div>
主要问题是我无法检查之前是否存在图表,如果存在则删除它并创建一个新图表,结果通过订阅捕获。我想我应该使用 Rederer2 服务在 createChart 函数的开头添加一些内容,但我不知道该怎么做。
谢谢!
我会完全避免使用渲染器并使用 angular2-highcharts 库。
您可以将选项传递给库提供的 chart
元素。您还可以附加一个事件,该事件将在图表呈现后为您提供图表对象。这将允许您根据需要 remove/add 系列。
// component.html
<chart [options]="options" (load)="saveInstance($event.context)"></chart>
// component.ts
saveInstance(chartInstance) {
this.chart = chartInstance;
}
在你订阅你的行为主题observable中,你可以检查图表是否存在。如果是,请更新现有图表。如果没有,创建初始图表
// component.ts
.subscribe(data => {
// if chart exists, update chart
if(this.chart){
// remove existing series, and add new series
this.chart.series[0].remove(false);
this.chart.addSeries({
data: data
}, true);
}else{
// else generate chart initially
this.options = this.generateOptions(data);
}
});
这里是 plnkr 演示此功能
旁注:您通常不应在您的服务中订阅。相反,服务应该公开组件可以订阅的可观察对象。在这种情况下,解决方案可能看起来像这样 plnkr
我遇到了一个问题,因为我正在尝试将有关国家/地区的一些结果显示到饼图 (HightCharts) 中。在 API 调用 Api 服务后,我将此信息分配给 BehaviorSubject。
第一次,我在我的 chartComponent 中收到信息,它创建了一个图表,但第二次我需要删除这个图表并创建一个新图表,因为用户可以通过按大陆和种类过滤的表单修改结果人口或 AreaInSqkm 等指标。
这是服务中的 Api 调用:
public dataObservable = this.data.asObservable();
private data = new BehaviorSubject<any>(null);
direction: String = "dsc";
public filters: any = {
continent : "All",
metric: "None",
quantity: 5,
};
url = "some URL";
constructor(private http : Http) { }
getCountries(){
return this.http.get(this.url)
.map(res=>res.json())
.map((data)=>data.geonames.filter((country)=>{
if(this.filters.continent !== "All"){
return country.continent == this.filters.continent
}else{
return country.continent
}
})
)
.map((data)=>{
if(this.filters.metric == "population"){
return this.sortByPopulation(data, this.direction).slice(0, this.filters.quantity)
}else if(this.filters.metric == "areaInSqKm"){
return this.sortByArea(data, this.direction).slice(0, this.filters.quantity)
}
return data.slice(0, this.filters.quantity);
})
.subscribe((data)=>{
this.setData(data);
})
}
sortByPopulation(data, direction){
if(direction =="asc"){
data.sort((a, b)=>{
return a["population"] - b["population"]
})
} else{
data.sort((a, b)=>{
return b["population"] - a["population"]
})
}
return data
}
sortByArea(data, direction){
if(direction =="asc"){
data.sort((a, b)=>{
return a["areaInSqKm"] - b["areaInSqKm"]
})
} else{
data.sort((a, b)=>{
return b["areaInSqKm"] - a["areaInSqKm"]
})
}
return data
}
updateFilters(filters){
this.filters = filters
}
setData(data){
this.data.next(data)
}
如您所见,我将数据作为 BehaviorSubject 的值传递,并且每次有人修改表单时我都会收到此值更改的信息。
稍后我在 chartComponent 中创建图表如下:
@Component({
selector: 'chart',
templateUrl: './chart.component.html',
styleUrls: ['./chart.component.scss']
})
export class ChartComponent implements OnInit, AfterViewInit {
element : any;
opts: Object = {};
container : any;
@Input()
values: Array<Object>;
getCountriesSubscription: Subscription = null;
chartValues: any = []
@ViewChild('chart') chart: ElementRef
constructor(
private renderer : Renderer2,
private api : ApiService,
private cdRef : ChangeDetectorRef
) { }
ngOnInit() {
}
ngAfterViewInit(){
this.getCountriesSubscription = this.api.dataObservable
.subscribe((data)=>{
if(data){
data.map((element)=>{
this.generateChartValues(element, this.api.filters.metric)
})
this.generateChartOptions(this.chartValues);
this.createChart()
this.cdRef.markForCheck();
console.log(this.chartValues[0])
}
})
}
createChart(){
this.container = this.renderer.createElement("div");
this.renderer.addClass(this.container, "mychart");
let chart = new Highcharts.Chart(this.container,this.opts)
this.renderer.appendChild(this.chart.nativeElement, this.container)
console.log(this.container)
this.cdRef.markForCheck();
}
generateChartOptions(chartValues){
this.opts = {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: `Countries in by ${this.api.filters.metric}`
},
series: [{
name: 'Total',
colorByPoint: true,
data: chartValues
}]
};
}
generateChartValues(data, metric){
if(metric == "population"){
this.chartValues.push({ name: data.countryName, y: parseInt(data.population) });
}
if(metric == "areaInSqKm"){
this.chartValues.push({ name: data.countryName, y: parseInt(data.areaInSqKm) });
}
if(metric == "None"){
this.chartValues.push({ name: data.countryName, y: 1});
}
}
}
<div #chart class="chartplace">
</div>
主要问题是我无法检查之前是否存在图表,如果存在则删除它并创建一个新图表,结果通过订阅捕获。我想我应该使用 Rederer2 服务在 createChart 函数的开头添加一些内容,但我不知道该怎么做。
谢谢!
我会完全避免使用渲染器并使用 angular2-highcharts 库。
您可以将选项传递给库提供的 chart
元素。您还可以附加一个事件,该事件将在图表呈现后为您提供图表对象。这将允许您根据需要 remove/add 系列。
// component.html
<chart [options]="options" (load)="saveInstance($event.context)"></chart>
// component.ts
saveInstance(chartInstance) {
this.chart = chartInstance;
}
在你订阅你的行为主题observable中,你可以检查图表是否存在。如果是,请更新现有图表。如果没有,创建初始图表
// component.ts
.subscribe(data => {
// if chart exists, update chart
if(this.chart){
// remove existing series, and add new series
this.chart.series[0].remove(false);
this.chart.addSeries({
data: data
}, true);
}else{
// else generate chart initially
this.options = this.generateOptions(data);
}
});
这里是 plnkr 演示此功能
旁注:您通常不应在您的服务中订阅。相反,服务应该公开组件可以订阅的可观察对象。在这种情况下,解决方案可能看起来像这样 plnkr