简体   繁体   English

D3图表与Angular 4的集成

[英]Integration of D3 chart with Angular 4

I am using D3 charting library to create parallel coordinates visualization chart in my Angular 4 application and i have already installed npm package of D3 in my application. 我正在使用D3图表库在Angular 4应用程序中创建平行坐标可视化图表,并且我已经在应用程序中安装了D3的npm软件包。 D3 version is 4 Following is what I am trying. D3版本是4以下是我正在尝试的。

import { Component, OnInit,ViewEncapsulation } from '@angular/core';
import * as d3 from 'd3';
import * as scale from 'd3-scale';

@Component({
    moduleId: module.id,
    selector: 'app-pcp',
    template:`<div class="col s12" id='test'></div>`,   
  styleUrls: ['./pcpstyle.css'],
  encapsulation: ViewEncapsulation.None

})
export class PCPComponent implements OnInit {
//dimensions:any;
private dimensions: Array<string>;
//private d:any;

  constructor() { }

  ngOnInit() {
    this.drawChart();
  }

 drawChart() {
  var m = [100, 10, 10, 60],
  w = 1000 - m[1] - m[3],
  h = 300 - m[0] - m[2];

//var x = d3.scalePoint().range([0, w]).padding(.1),
var x= d3.scaleBand().rangeRound([0, w]),
  y = {},
  dragging = {};

var line = d3.line(),
  background,
  foreground;

var svg = d3.select("#test").append("svg:svg")
  .attr("width", w + m[1] + m[3])
  .attr("height", h + m[0] + m[2])
  .append("svg:g")
  .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

var data = [{

  "A": 200, 
        "B": 3000, 
        "C": 2300, 
        "D": 4320, 
        "E": 1230, 
        "F": 7400, 
        "G": 1431, 
        "H": 1400, 
        "I": 4300, 
        "J": 6750
}, {

 "A": 1002, 
        "B": 2003, 
        "C": 2773, 
        "D": 3432, 
        "E": 1673, 
        "F": 740, 
        "G": 1231, 
        "H": 1900, 
        "I": 3000, 
        "J": 675
}];

// Extract the list of dimensions and create a scale for each.
x.domain(this.dimensions = d3.keys(data[0]).filter(function(d) {
  if (d === "name") return false;
  if (d === "Plant" || d === "Chemical" || d === "Pathway" || d === "Gene" || d === "Disease") {
    y[d] = d3.scaleOrdinal()
      .domain(data.map(function(p) {
        return p[d];
      }))
      .range([h, 0]);
  } else {
    y[d] = d3.scaleLinear()
      .domain(d3.extent(data, function(p) {
        return +p[d];
      }))
      .range([h, 0]);
  }
  return true;
}));

// Add grey background lines for context.
background = svg.append("svg:g")
  .attr("class", "background")
  .selectAll("path")
  .data(data)
  .enter().append("svg:path")
  .attr("d", path);

// Add blue foreground lines for focus.
foreground = svg.append("svg:g")
  .attr("class", "foreground")
  .selectAll("path")
  .data(data)
  .enter().append("svg:path")
  .attr("d", path);

// Add a group element for each dimension.
var g = svg.selectAll(".dimension")
  .data(this.dimensions)
  .enter().append("svg:g")
  .attr("class", "dimension")
  .attr("transform", function(d) {
    return "translate(" + x(d) + ")";
  }) 

// Add an axis and title.
g.append("svg:g")
  .attr("class", "axis")
  .each(function(d) {
    d3.select(this).call(d3.axisLeft(y[d]));
  })
  .append("svg:text")
  .attr("text-anchor", "middle")
  .attr("y", -50)
  .attr("x",-10)
  .text(String);

function position(d) {
  var v = dragging[d];
  return v == null ? x(d) : v;
}

function transition(g) {
  return g.transition().duration(500);
}

// Returns the path for a given data point.
function path(d) {
  return line(this.dimensions.map(function(p) {
    return [position(p), y[p](d[p])];
  }));
}
    }
}

After the integration of this i am getting below mentioned error: 集成此后,我得到以下提到的错误:

ERROR TypeError: Cannot read property 'map' of undefined 错误TypeError:无法读取未定义的属性“地图”

What needs to be changed so this could work properly? 需要更改什么才能使其正常工作?

the culprit for this is path(d) method And calling it inside the attr() method: 罪魁祸首是path(d)方法,并在attr()方法中调用它:

.attr("d", path);

Solution

.attr("d", path.bind(this));

You can solve this error by using latest JavaScript ES6 arrow function as well. 您也可以通过使用最新的JavaScript ES6箭头功能来解决此错误。 An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. 箭头函数表达式的语法比函数表达式短,并且没有自己的this,arguments,super或new.target。

Alternative Solution 替代解决方案

path = (d) => {
  return line(this.dimensions.map(function(p) {
    return [position(p), y[p](d[p])];
  }));
}

Arrow function does not have this argument, so that you don't need to bind the method. Arrow函数没有此参数,因此您无需绑定该方法。 You can keep .attr("d", path); 您可以保留.attr("d", path); .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM