2017-11-11 62 views
1

我使用D3圖表庫在我的Angular 4應用程序中創建平行座標可視化圖表,並且我已經在我的應用程序中安裝了D3的npm包。 D3版本是4以下是我正在嘗試。D3圖表與Angular 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])]; 
    })); 
} 
    } 
} 

的這個整合後我得到以下提到的錯誤:

ERROR TypeError: Cannot read property 'map' of undefined

有什麼需要改變,以便這可以正常工作?

+0

@JamesZ:你能幫我找出我做錯的地方嗎? – sam140

+0

請閱讀[本](https://meta.stackoverflow.com/questions/309690/how-do-i-request-a-stack-overflow-user-to-answer-my-question) –

+0

你真的打開一個小時後作爲不同用戶的重複問題?只是不好的形式的人... – Mark

回答

0

的罪魁禍首,這是path(d)方法,把它的attr()方法中:

.attr("d", path); 

解決方案

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

您可以通過使用最新的JavaScript ES6箭頭功能很好的解決了這個錯誤。箭頭函數表達式的語法比函數表達式短,並且沒有自己的this,arguments,super或new.target。

替代解決方案

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

Arrow功能沒有這種說法,這樣就不需要綁定的方法。您可以保留 .attr("d", path);