我想在Angular 9中创建chart.js的条形图。用户应该在搜索栏中输入字符串,搜索条会在.json文件中找到相应的条目,并将其属性返回到条形图中。例如,您可以输入“甜椒”,它会显示一个图表,其中一个柱形被称为“甜”,其高为3,然后一个名为“酸”的柱为1高。搜索组件有效,我可以输入一个名称,然后它将值作为文本返回。但是,我无法获得它返回正确的图表。
对不起,如果这是你们的基本问题,我只是一个业余爱好者,正在学习如何编码。我到处都在查找问题,但找不到此问题或任何解决方法。
这是home-page.component.ts:
import { Component, OnInit } from '@angular/core';
import { DataService } from '../../data.service';
import { Post } from '../../post';
import { Chart } from 'chart.js';
@Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent implements OnInit {
post: Post[]
constructor(
public dataService: DataService
) { }
ngOnInit() {
this.dataService.getPosts().subscribe(posts => {
this.post = posts
this.dataService.postsData = posts
});
}
onSelectedFilter(e) {
this.getFilteredExpenseList();
let postname = this.post.name;
let postsour = this.post.sour;
let postsweet = this.post.sweet;
this.chart = new Chart('canvas', {
type: 'bar',
data: {
labels: postname,
datasets: [
{
data: postsour,
borderColor: "#3cba9f",
fill: false
},
{
data: postsweet,
borderColor: "#ffcc00",
fill: false
},
]
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}],
}
}
});
}
getFilteredExpenseList() {
if (this.dataService.searchOption.length > 0)
this.post = this.dataService.filteredListOptions();
else {
this.post = this.dataService.filteredListOptions();
}
}
}
这是search-bar.component.ts:
import { Component, OnInit, ViewChild, ElementRef, EventEmitter, Output } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { DataService } from '../../data.service';
import { Post } from '../../post';
@Component({
selector: 'app-search-bar',
templateUrl: './search-bar.component.html',
styleUrls: ['./search-bar.component.css']
})
export class SearchBarComponent implements OnInit {
myControl = new FormControl();
filteredOptions: Observable<string[]>;
allPosts: Post[];
autoCompleteList: any[]
@ViewChild('autocompleteInput') autocompleteInput: ElementRef;
@Output() onSelectedOption = new EventEmitter();
constructor(
public dataService: DataService
) { }
ngOnInit() {
// get all the post
this.dataService.getPosts().subscribe(posts => {
this.allPosts = posts
});
// when user types something in input, the value changes will come through this
this.myControl.valueChanges.subscribe(userInput => {
this.autoCompleteExpenseList(userInput);
})
}
private autoCompleteExpenseList(input) {
let categoryList = this.filterCategoryList(input)
this.autoCompleteList = categoryList;
}
// this is where filtering the data happens according to you typed value
filterCategoryList(val) {
var categoryList = []
if (typeof val != "string") {
return [];
}
if (val === '' || val === null) {
return [];
}
return val ? this.allPosts.filter(s => s.name.toLowerCase().indexOf(val.toLowerCase()) != -1)
: this.allPosts;
}
// after you clicked an autosuggest option, this function will show the field you want to show in input
displayFn(post: Post) {
let k = post ? post.name : post;
return k;
}
filterPostList(event) {
var posts = event.source.value;
if (!posts) {
this.dataService.searchOption = []
}
else {
this.dataService.searchOption.push(posts);
this.onSelectedOption.emit(this.dataService.searchOption)
}
this.focusOnPlaceInput();
}
removeOption(option) {
let index = this.dataService.searchOption.indexOf(option);
if (index >= 0)
this.dataService.searchOption.splice(index, 1);
this.focusOnPlaceInput();
this.onSelectedOption.emit(this.dataService.searchOption)
}
// focus the input field and remove any unwanted text.
focusOnPlaceInput() {
this.autocompleteInput.nativeElement.focus();
this.autocompleteInput.nativeElement.value = '';
}
}
这是所引用的post.ts:
export interface Post {
name: string,
type: string,
sweet: number,
sour: number,
salty: number,
bitter: number,
fatty: number,
umami: number,
spicy: number,
}
这是.json文件的示例:
[
{
"name": "bell pepper",
"type": "vegetable",
"sweet": 3,
"sour": 1,
"salty": 1,
"bitter": 2,
"fatty": 0,
"umami": 0,
"spicy": 2
},
{
"name": "salt",
"type": "spice",
"sweet": 0,
"sour": 0,
"salty": 10,
"bitter": 0,
"fatty": 0,
"umami": 0,
"spicy": 0
},
{
"name": "beef",
"type": "meat",
"sweet": 1,
"sour": 0,
"salty": 2,
"bitter": 0,
"fatty": 4,
"umami": 5,
"spicy": 0
},
{
"name": "Apple",
"type": "fruit",
"sweet": 6,
"sour": 3,
"salty": 0,
"bitter": 0,
"fatty": 0,
"umami": 0,
"spicy": 0
}
]
这里是数据服务:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Post } from './post';
@Injectable({
providedIn: 'root'
})
export class DataService {
searchOption = []
public postsData: Post[]
postUrl: string = "../assets/posts.json";
constructor(
private http: HttpClient
) { }
getPosts(): Observable<Post[]> {
return this.http.get<Post[]>("../assets/flavors.json");
}
filteredListOptions() {
let posts = this.postsData;
let filteredPostsList = [];
for (let post of posts) {
for (let options of this.searchOption) {
if (options.name === post.name) {
filteredPostsList.push(post);
}
}
}
console.log(filteredPostsList);
return filteredPostsList;
}
}
再次,非常感谢您的帮助。这是我第一次使用Angular,而我在这里尽头了。谢谢!
在主页组件中,this.post
表示对象的数组。要从对象数组生成数组,请使用map()
。尝试以下]]
home-page.component.ts: