Storybook:更改控件的值不会重新呈现 Chart.js canvas
Storybook: Changing the value of the control doesnot rerender the Chart.js canvas
我正在使用基于 Angular
的 Storybook
。我只想根据 Storybook 控件中给定的值重新呈现图表。但即使在更改控件的值后,图表仍保持静态。我尝试了很多解决方法,但仍然处于第一位。我要显示的图表是等值线图。我使用 Chartjs
和 chartjs-chart-geo
库来显示图表。
我在 Storybook 中的组件:
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
import * as Chart from 'chart.js';
import * as ChartGeo from 'chartjs-chart-geo';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'storybook-choropleth',
template: `<div>
<canvas id="mapCanvas"></canvas>
</div>
`,
styleUrls: ['./choropleth.css'],
})
export default class ChoroplethComponent implements OnInit {
@Input()
url = 'https://unpkg.com/world-atlas/countries-50m.json';
/**
* Type of projecttion
*/
// @Input()
chartProjection: 'azimuthalEqualArea' | 'azimuthalEquidistant' | 'gnomonic' | 'orthographic' | 'stereographic'
| 'equalEarth' | 'albers' | 'albersUsa' | 'conicConformal' | 'conicEqualArea' | 'conicEquidistant' | 'equirectangular' | 'mercator'
| 'transverseMercator' | 'naturalEarth1' = 'mercator';
chart: any;
geoData: any;
countries: any;
constructor(
private http: HttpClient
) {
}
ngOnInit() {
this.getGeoData();
}
getGeoData() {
this.http.get(this.url).subscribe((data) => {
this.countries = ChartGeo.topojson.feature(data, data['objects']['countries']).features;
let t = <HTMLCanvasElement>document.getElementById('mapCanvas');
if (this.chart !== undefined) {
this.chart.destroy();
}
// exclude antartica
this.countries.splice(239, 1);
console.log(this.countries);
let dts = {
labels: this.countries.map((d) => d.properties.name),
datasets: [{
label: 'Countries',
data: this.countries.map((d) => ({ feature: d, value: Math.random() })),
}]
};
console.log(this.countries);
let configOptions = {
maintainAspectRatio: true,
responsive: true,
showOutline: false,
showGraticule: false,
scale: {
projection: this.chartProjection
} as any,
geo: {
colorScale: {
display: true,
interpolate: 'blues',
missing: 'white',
legend: {
display: 'true',
position: 'bottom-right'
}
}
}
};
this.chart = new Chart(t.getContext('2d'),
{
type: 'choropleth',
data: dts,
options: configOptions
}
);
});
}
getDts() {
this.getGeoData();
let dts = {
labels: this.geoData.map((i) => i.properties.name),
datasets: [
{
outline: this.geoData,
data: this.geoData.map((i) => ({
feature: i,
value: i.properties.confirmed
}))
}
]
};
return dts;
}
getConfigOptions() {
let configOptions = {
maintainAspectRatio: true,
responsive: true,
showOutline: false,
showGraticule: false,
scale: {
projection: 'mercator'
} as any,
geo: {
colorScale: {
display: true,
interpolate: 'reds',
missing: 'white',
legend: {
display: 'true',
position: 'bottom-right'
}
}
}
};
return configOptions;
}
}
我的story.ts:
import { Story, Meta, moduleMetadata } from '@storybook/angular';
import Choropleth from './choropleth.component';
import { HttpClientModule } from '@angular/common/http';
import { withKnobs } from '@storybook/addon-knobs';
import { NO_ERRORS_SCHEMA } from '@angular/core';
export default {
title: 'Choropleth',
component: Choropleth,
decorators: [
withKnobs,
moduleMetadata({
//:point_down: Imports both components to allow component composition with storybook
imports: [HttpClientModule],
schemas: [NO_ERRORS_SCHEMA],
})
],
argTypes: {
backgroundColor: { control: 'color' }
},
} as Meta;
const Template: Story<Choropleth> = (args: Choropleth) => ({
component: Choropleth,
props: args
});
export const Primary = Template.bind({});
Primary.args = {
url: 'https://unpkg.com/world-atlas/countries-50m.json'
};
在此,我想保持 URL 动态。由于 URL 在故事书的控件中发生了变化,我想相应地重新渲染地图。任何帮助将不胜感激。
设置图表的getGeoData
方法只在组件初始化时调用,当@Input
值改变时它不会运行。对于这些场景 Angular 提供了 ngOnChanges
生命周期钩子。这就是我们需要告诉 Angular 当 @Input
值发生变化时需要做什么的地方。
ngOnChanges(changes: SimpleChanges) {
for (const propName in changes) {
switch(propName) {
case 'url':
// action that needs to happen when url changes
break;
case 'chartProjection':
// action that needs to happen when chartProjection changes
break;
}
}
}
我正在使用基于 Angular
的 Storybook
。我只想根据 Storybook 控件中给定的值重新呈现图表。但即使在更改控件的值后,图表仍保持静态。我尝试了很多解决方法,但仍然处于第一位。我要显示的图表是等值线图。我使用 Chartjs
和 chartjs-chart-geo
库来显示图表。
我在 Storybook 中的组件:
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
import * as Chart from 'chart.js';
import * as ChartGeo from 'chartjs-chart-geo';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'storybook-choropleth',
template: `<div>
<canvas id="mapCanvas"></canvas>
</div>
`,
styleUrls: ['./choropleth.css'],
})
export default class ChoroplethComponent implements OnInit {
@Input()
url = 'https://unpkg.com/world-atlas/countries-50m.json';
/**
* Type of projecttion
*/
// @Input()
chartProjection: 'azimuthalEqualArea' | 'azimuthalEquidistant' | 'gnomonic' | 'orthographic' | 'stereographic'
| 'equalEarth' | 'albers' | 'albersUsa' | 'conicConformal' | 'conicEqualArea' | 'conicEquidistant' | 'equirectangular' | 'mercator'
| 'transverseMercator' | 'naturalEarth1' = 'mercator';
chart: any;
geoData: any;
countries: any;
constructor(
private http: HttpClient
) {
}
ngOnInit() {
this.getGeoData();
}
getGeoData() {
this.http.get(this.url).subscribe((data) => {
this.countries = ChartGeo.topojson.feature(data, data['objects']['countries']).features;
let t = <HTMLCanvasElement>document.getElementById('mapCanvas');
if (this.chart !== undefined) {
this.chart.destroy();
}
// exclude antartica
this.countries.splice(239, 1);
console.log(this.countries);
let dts = {
labels: this.countries.map((d) => d.properties.name),
datasets: [{
label: 'Countries',
data: this.countries.map((d) => ({ feature: d, value: Math.random() })),
}]
};
console.log(this.countries);
let configOptions = {
maintainAspectRatio: true,
responsive: true,
showOutline: false,
showGraticule: false,
scale: {
projection: this.chartProjection
} as any,
geo: {
colorScale: {
display: true,
interpolate: 'blues',
missing: 'white',
legend: {
display: 'true',
position: 'bottom-right'
}
}
}
};
this.chart = new Chart(t.getContext('2d'),
{
type: 'choropleth',
data: dts,
options: configOptions
}
);
});
}
getDts() {
this.getGeoData();
let dts = {
labels: this.geoData.map((i) => i.properties.name),
datasets: [
{
outline: this.geoData,
data: this.geoData.map((i) => ({
feature: i,
value: i.properties.confirmed
}))
}
]
};
return dts;
}
getConfigOptions() {
let configOptions = {
maintainAspectRatio: true,
responsive: true,
showOutline: false,
showGraticule: false,
scale: {
projection: 'mercator'
} as any,
geo: {
colorScale: {
display: true,
interpolate: 'reds',
missing: 'white',
legend: {
display: 'true',
position: 'bottom-right'
}
}
}
};
return configOptions;
}
}
我的story.ts:
import { Story, Meta, moduleMetadata } from '@storybook/angular';
import Choropleth from './choropleth.component';
import { HttpClientModule } from '@angular/common/http';
import { withKnobs } from '@storybook/addon-knobs';
import { NO_ERRORS_SCHEMA } from '@angular/core';
export default {
title: 'Choropleth',
component: Choropleth,
decorators: [
withKnobs,
moduleMetadata({
//:point_down: Imports both components to allow component composition with storybook
imports: [HttpClientModule],
schemas: [NO_ERRORS_SCHEMA],
})
],
argTypes: {
backgroundColor: { control: 'color' }
},
} as Meta;
const Template: Story<Choropleth> = (args: Choropleth) => ({
component: Choropleth,
props: args
});
export const Primary = Template.bind({});
Primary.args = {
url: 'https://unpkg.com/world-atlas/countries-50m.json'
};
在此,我想保持 URL 动态。由于 URL 在故事书的控件中发生了变化,我想相应地重新渲染地图。任何帮助将不胜感激。
设置图表的getGeoData
方法只在组件初始化时调用,当@Input
值改变时它不会运行。对于这些场景 Angular 提供了 ngOnChanges
生命周期钩子。这就是我们需要告诉 Angular 当 @Input
值发生变化时需要做什么的地方。
ngOnChanges(changes: SimpleChanges) {
for (const propName in changes) {
switch(propName) {
case 'url':
// action that needs to happen when url changes
break;
case 'chartProjection':
// action that needs to happen when chartProjection changes
break;
}
}
}