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

我正在尝试将 D3 v4 与 Angular 2 (Typescript) 一起使用。我目前正在研究 D3 v4。我能够在stackoverflow中遵循一些答案,但没有成功。我已经导入了大部分 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 设置。这并不容易!当基础知识不起作用时,我能够将其范围缩小到类型。

标签: angular d3.js typescript typescript-typings


【解决方案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()
    

    【讨论】:

      猜你喜欢
      • 2017-04-09
      • 1970-01-01
      • 2017-10-26
      • 2020-06-30
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      • 2016-08-16
      • 2017-01-19
      相关资源
      最近更新 更多