首页 > 解决方案 > Angular 中可重用的 D3 图表

问题描述

我是新手,还在学习,所以我在这方面有点挣扎。

目标:我想在 services.ts 中创建可重复使用的图表,这意味着我只想传递参数来获取图表。我设法创建了简单的条形图,但它不可重复使用,尤其是在涉及 x 和 y 轴和值时。应传递 Json 结构,例如 ({cluster:name1, value:1},{cluster:name2, value:7})。然后在组件中添加参数就很容易了。

ISSUE: 传递参数当前失败。通常失败,类型不可分配给提供的类型,如下

'(string | number | undefined)[]' 类型的参数不可分配给'Iterable' 类型的参数。'Symbol.iterator.next(...)' 返回的类型在这些类型之间不兼容。输入'IteratorResult<string | 号码 | undefined, any>' 不能分配给类型 'IteratorResult<NumberValue, any>'。类型 'IteratorYieldResult<string | 号码 | undefined>' 不可分配给类型 'IteratorResult<NumberValue, any>'。类型 'IteratorYieldResult<string | 号码 | undefined>' 不可分配给类型 'IteratorYieldResult'。键入'字符串 | 号码 | undefined' 不可分配给类型 'NumberValue'。类型“未定义”不可分配给类型“NumberValue”。

代码(visuals.services.ts):

import { Injectable } from '@angular/core';
import * as d3 from 'd3';
@Injectable({
  providedIn: 'root',
})
    export class Visuals {
     
    
      BarChart(
        margin: number,
        domSelector: string,
        colour: string,
        dataAdd: any,
        barValues: string,
        barName: string
      ) {
        var svgBar = undefined;
    
        width = 550 - margin * 2;
        height = 200 - margin * 2;
    
        svgBar = d3
          .select(domSelector)
          .append('svg')
          .attr('width', width + margin * 2)
          .attr('height', height + margin * 2)
          .append('g')
          .attr('transform', 'translate(' + margin + ',' + margin + ')');
    
    
        var x = d3
          .scaleBand()
          .range([0, width])
          .domain(dataAdd.map((d: any) => d[barName])) //above error
          .padding(0.2);
    
    
        svgBar
          .append('g')
          .attr('transform', 'translate(0,' + height + ')')
          .call(d3.axisBottom(x))
          .selectAll('text')
          .attr('transform', 'translate(-10,0)')
          .style('text-anchor', 'middle')
          .style('font-size', 7);
    
        var y = d3
          .scaleLinear()
          .domain([0, d3.max(dataAdd, (d) => d[barValues])]) 
    
        svgBar.append('g').call(d3.axisLeft(y));
    
        svgBar
          .selectAll('bars')
          .data(dataAdd)
          .enter()
          .append('rect')
          .attr('x', (d: any) => x(d[barName])) //and similar here
          .attr('y', (d: any) => y(d[barValues]))
          .attr('width', x.bandwidth())
          .attr('height', (d: any) => height - y(d[barValues]))
          .attr('fill', colour);
      }

代码(即-comp.component.ts):

import { Component, OnInit } from '@angular/core';
import { DataFetch } from '../datafetch.service';//another service to get the data
import { Visuals } from '../visuals.service';

@Component({
  selector: 'app-data-viz',
  templateUrl: './data-viz.component.html',
  styleUrls: ['./data-viz.component.css'],
  providers: [DataFetch, Visuals],
})
export class DataVizComponent implements OnInit {
  constructor(
    private datafetch: DataFetch,
    private dataviz: Visuals
  ) {}

  ngOnInit(): void {
    let br = new DatavizService();
    br.BarChart(
      20,
      '#barChart',
      '#121926',
      this.datafetch.Clusters,
      'count',
      'cluster'
    );
    console.log(this.datafetch.Clusters);
  }
}

标签: javascriptangulartypescriptd3.js

解决方案


推荐阅读