D3、TS 和 Angular 2

Posted

技术标签:

【中文标题】D3、TS 和 Angular 2【英文标题】:D3, TS and Angular 2 【发布时间】:2017-04-16 14:34:31 【问题描述】:

我正在尝试将 D3 v4 与 Angular 2 (Typescript) 一起使用。我目前正在研究 D3 v4。我能够在***中遵循一些答案,但没有成功。我已经导入了大部分 D3 库及其类型(我使用的是 TS 2.0),并且在我的组件文件中我需要 import * as d3 from 'd3';。对我来说,这个问题可能是 Angular 2、Typescript 和 3rd 方库......到目前为止一团糟。

在我的组件文件中,我有一些这样的代码:

        let arc = d3.arc()
            .outerRadius(chartHeight / 2)
            .innerRadius(chartHeight / 4)
            .padAngle(0.03)
            .cornerRadius(8);

        let pieG = chartLayer.selectAll("g")
            .data([data])
            .enter()
            .append("g")
            .attr("transform", "translate(" + [chartWidth / 2, chartHeight / 2] + ")");

        let block = pieG.selectAll(".arc")
            .data(arcs);

        let newBlock = block.enter().append("g").classed("arc", true);

        newBlock.append("path")
            .attr("d", arc)
            .attr("id", function (d, i) 
                return "arc-" + i
            )
            .attr("stroke", "gray")
            .attr("fill", function (d, i) 
                return d3.interpolateCool(Math.random())
            );

如您所见,我在第一行定义了 arc 并在第 19 行使用它,但出现错误:

[at-loader] src\piechart\piechart.component.ts:19:28
    Argument of type 'Arc<any, DefaultArcObject>' is not assignable to      parameter of type '(this: BaseType, datum: PieArcDatum<number |  valueOf():    number; >, index: num
  ber, groups: Base...'.
  Types of parameters 'd' and 'datum' are incompatible.
    Type 'PieArcDatum<number |  valueOf(): number; >' is not assignable to type 'DefaultArcObject'.
      Property 'innerRadius' is missing in type 'PieArcDatum<number |  valueOf(): number; >'.

Arch 和 arc 似乎是在 d3-shape 类型和 d3-path 类型中定义的。

任何可以帮助我的人...我花了几天时间尝试使用 angular 2、TS 和 D3 v4 进行 POC,但到目前为止没有运气...我已经在网上看到了所有关于它的文章,其中大多数都有旧版本或不工作。我也觉得这是一个打字问题。 Angular 2 和第三方库是一场噩梦。

【问题讨论】:

.attr("d", arc) 更改为.attr("d", function(d) console.log(d); arc(d); 使用console.log 的输出更新您的问题... newBlock.append("path") .attr("d", (d) =&gt; console.log(d); arc(d); ) .attr("id", (d, i) =&gt; return "arc-" + i ) 我收到两个 ts 错误...和 ​​4 个日志如下:Log: "data":"name":"hoge","value":100,"index":0,"value":100,"startAngle":0,"endAngle":0.7075659129706742,"padAngle":0 试图复制您的问题here,但没有成功。不过,我不确定 plunker 如何编译打字稿:( 谢谢马克。这令人沮丧。我切换到 d3 v3.5.5,这个版本的最新类型是 3.5.36。使用此代码时:` let pie = d3.layout.pie() .sort(null) .value((d) => return d.population; ); ` 我收到一个错误:[at-loader] src/piechart/piechart.component.ts:39:26 类型“数字”上不存在属性“人口”。但是,如果我只是将类型添加到任何它的“d”(内部值)中。我认为问题出在打字上,或者我做错了什么但无法弄清楚。 在显示圆弧/饼图等之前,您是否尝试过在 SVG 中显示最基本的 D3 图像或形状。我正在经历与您相同的繁琐工作,试图获得正确的 d3 版本、类型、Angular2、typeScript 设置。这并不容易!当基础知识不起作用时,我能够将其范围缩小到类型。 【参考方案1】:

只需要将arc 转换为any。所以应该是.attr("d", &lt;any&gt;arc)

【讨论】:

这可能是一个临时解决方法,但我想这应该以适当的方式解决,也许是打字稿定义的错误?【参考方案2】:

我在我的 Angular 2 项目中添加了 import 语句,并且在开发过程中不断出现错误。我正在使用 angular-cli 和 d3 v4。

除了 import * as d3 from "d3"; 之外,将以下代码添加到您的 typings.d.ts 文件中:

declare module 'd3' 
  export * from 'd3-array';
  export * from 'd3-axis';
  export * from 'd3-brush';
  export * from 'd3-chord';
  export * from 'd3-collection';
  export * from 'd3-color';
  export * from 'd3-dispatch';
  export * from 'd3-drag';
  export * from 'd3-dsv';
  export * from 'd3-ease';
  export * from 'd3-force';
  export * from 'd3-format';
  export * from 'd3-geo';
  export * from 'd3-hierarchy';
  export * from 'd3-interpolate';
  export * from 'd3-path';
  export * from 'd3-polygon';
  export * from 'd3-quadtree';
  export * from 'd3-queue';
  export * from 'd3-random';
  export * from 'd3-request';
  export * from 'd3-scale';
  export * from 'd3-selection';
  export * from 'd3-shape';
  export * from 'd3-time';
  export * from 'd3-time-format';
  export * from 'd3-timer';
  export * from 'd3-transition';
  export * from 'd3-voronoi';
  export * from 'd3-zoom';

当我包含此代码时,我遇到的任何错误(并且仅在开发中看到)都消失了。希望这可以帮助您排除打字错误并让您更接近解决方案!

【讨论】:

谢谢布鲁斯。在发布问题之前我已经尝试过,但我仍然遇到错误。我切换到 d3 3.5.5,不幸的是打字版本是 3.3.6。例如,我仍然收到错误:let _data: any = d3.layout.pie().sort(null).value(function (d: any) return d.value; )(data); 如果我没有将 d 声明为任何,则打字稿转译器会抛出一个错误,指出“类型'数字'上不存在属性'值'。”。为了解决这个问题,我需要在 d 中添加任何类型。输入应该是可选的,但实际情况并非如此。【参考方案3】:

您只需要在创建弧时添加一个类型。试试这样的:

interface Datum 
  key: string;
  value: number;


const pieData = d3.pie<Datum>()
  .value(d => d.value)(data);

const arc = d3.arc<d3.PieArcDatum<Datum>>();

d3.select('#pie')
  .data(pieData)
  .enter()
  .append('path')
  .attr('d', arc);

【讨论】:

【参考方案4】:

添加路径时试试这个:

newBlock.append("path")
    .attr("d", arc())
    .attr("id", function (d, i) 
        return "arc-" + i
    )
    .attr("stroke", "gray")
    .attr("fill", function (d, i) 
        return d3.interpolateCool(Math.random())
    );

根据d3 API,使用let arc = d3.arc()构造弧生成器后,必须调用arc()才能生成实际弧。

【讨论】:

我试过你告诉我的,但现在我得到这个错误:[at-loader] src\piechart\piechart.component.ts:19:28 提供的参数与调用目标的任何签名都不匹配。我认为打字不好。 如果在构造弧生成器时还包含 startAngle 和 endAngle(例如.startAngle(0).endAngle(Math.PI / 2)),调用arc() 时仍然会出现该错误,但至少它会返回一个字符串你可以通过路径。【参考方案5】:

以下代码绘制一条弧线。您可以向arcData提供更多物品:

import * as d3 from "d3";

export function run() 
  const chartLayer = d3.select('svg');

  let chartHeight = 500;
  let chartWidth = 500;
  let data = null;

  let arcData = [
          innerRadius: 0,
          outerRadius: 100,
          startAngle: 0,
          endAngle: Math.PI / 2,
          padAngle: 1
       ];

  let arc = d3.arc();

  let pieG = chartLayer 
      .selectAll("g").data([data]).enter()
      .append("g")
      .attr("transform", "translate(" + [chartWidth / 2, chartHeight / 2] + ")");

  let block = pieG.selectAll(".arc")
      .data(arcData);

  let newBlock = block.enter().append("g").classed("arc", true);

  newBlock.append("path")
      .attr("d", function (d)  return arc(d) )
      .attr("id", function (d, i) 
          return "arc-" + i
      )
      .attr("stroke", "gray")
      .attr("fill", function (d, i) 
          return d3.interpolateCool(Math.random())
      );

顺便说一句,我猜你不需要这条线

.selectAll("g").data([data]).enter()

【讨论】:

以上是关于D3、TS 和 Angular 2的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular2 中使用 d3.js

带有 Ionic 2 Angular 2 和 TypeScript 的 OpenPGP

不记名令牌未添加到 HTTP 请求 - MSAL2 Angular

ionic 2 angular 2 在两列中分布绑定记录

Angular 2:将外部js文件导入组件

如何在 Angularfire2 Angular2 中对 FirebaseListObservable 列表进行排序?