从搜索栏向Angular中的chart.js图形调用数据

问题描述 投票:1回答:1

我想在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,而我在这里尽头了。谢谢!

angular typescript chart.js
1个回答
0
投票

在主页组件中,this.post表示对象的数组。要从对象数组生成数组,请使用map()。尝试以下]]

home-page.component.ts:

© www.soinside.com 2019 - 2024. All rights reserved.