2017-02-25 5 views
0

Ich bin derzeit eine Choroplethenkarte in Angular 2 mit dem folgend als Leitfaden Aufbau: http://cartographicperspectives.org/index.php/journal/article/view/cp78-sack-et-al/1359Verständnis d3.scaleQuantile() für Choroplethenkarte

Bisher funktioniert alles gut, außer die d3.scaleQuantile().range() Funktion.

In d3 Version 3 war die obige Funktion d3.scale.quantile().range().

Im obigen Karten-Tutorial, das die Version 3 verwendet, akzeptiert d3.scale.quantile().range() eine Liste von Farben: [“#D4B9DA”,“#C994C7”, “#DF65B0”, “#DD1C77”, “#980043”]. Doch dies scheint nicht auf die neue d3.scaleQuantile().range() Funktion in Version 4 anzuwenden, wenn ich die gleiche Liste setzen in.

Die Konsole einen Fehler von Type 'string' is not assignable to type 'number'.) und in WebStorm gibt, sagt der Fehler Argument types do not match parameters

Wenn jemand kann mir in die richtige Richtung zeigen, wie man die Entfernungsfunktion benutzt, um die Farben einzustellen, ich würde es begrüßen. Relevante Teile des Codes unten.

colorScale(csvData: any): any { 

    var range = []; 

    var color = d3.scaleQuantile() 
     .range(range); 

    var domainArray = []; 

    for (var i in csvData){ 
     domainArray.push(Number(csvData[i]["PROP"])); 
    }; 

    //pass array of expressed values as domain 
    color.domain(domainArray); 

    return color; //return the color scale generator 
} 

choropleth(d: any, recolorMap: any): any{ 

    //get data value 
    var value = d.properties["PROP"]; 
    //if value exists, assign it a color; otherwise assign gray 
    if (value) { 
     return recolorMap(value); 
    } else { 
     return "#ccc"; 
    }; 
}; 

buildMap(csvData: any){ 
    //code removed to keep short 
    var recolorMap = this.colorScale(csvData); 

    this.g = this.svg.append("g") 
      .selectAll("path") 
      .data(xFeatures) 
      .enter() 
      .append("path") 
      .attr("d", this.geoPath) 
      .style("fill", (d) => { //color enumeration units 
       return this.choropleth(d, recolorMap) 
      }); 
} 
+0

Was ist der Wert von 'csvData' ist? Es sieht so aus, als könnte ein Parsingfehler auftreten, weil Sie 'csvData [i] ['PROP']' in eine Zahl konvertieren. –

+0

Die 'csvData'-Variable ist die CSV-Daten mit den Namen und Nummern, die auf jeden Zustand angewendet werden. Ich schaute durch und machte eine Reihe von Konsolen-Log-Anweisungen, um zu sehen, was mitgereicht wurde und es ausgecheckt hat. Es ist die Bereichsfunktion, die scheinbar nur ein Array von Zahlen und kein Array von Strings benötigt. – mikey8989

+1

Für den von Ihnen geposteten Code-Block rufen Sie 'd3.scaleQuantile(). Range (range)' auf, aber 'range' ist ein leeres Array an diesem Punkt. Ist das der Punkt, an dem Probleme auftreten? Oder ist es woanders, für das Sie den Code nicht gepostet haben? –

Antwort

1

Wenn jemand mich in die richtige Richtung, wie die Reichweite Funktion nutzen Punkt können die Farben einzustellen, würde ich es zu schätzen wissen.

Von der API documentation:

Wenn Bereich festgelegt ist, werden die diskreten Werte im Bereich. Das Array darf nicht leer sein und kann einen beliebigen Werttyp enthalten.

So sollten Sie in der Lage sein, Saiten für Quantil Skala in d3 v4 im Bereich Array zu verwenden, und wenn nicht, gibt es wahrscheinlich ein anderes Problem:

var scale = d3.scaleQuantile().domain([0,99]).range(["steelblue","#aaa","lightgreen"]); 
 

 
var svg = d3.select('body').append('svg').attr('width',500).attr('height',300); 
 

 
var rects = svg.selectAll('rect') 
 
    .data(d3.range(100)) 
 
    .enter() 
 
    .append('rect') 
 
    .attr('width',18) 
 
    .attr('height',18) 
 
    .attr('fill', function(d,i) { return scale(i); }) 
 
    .attr('x', function(d,i) { return i%10 * 20 + 30; }) 
 
    .attr('y', function(d,i) { return Math.floor(i/10) * 20 + 30; }); 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>

Diese sollte auch für andere Skalen gelten. Wie wenn Sie die Kontrolle über die Schwellen in der choropleth unter Verwendung einer Schwelle Skala verwendet haben wollen:

var scale = d3.scaleThreshold().domain([10,25,90]).range(["#bae4bc","#7bccc4","#2b8cbe","#0868ac"]); 
 

 
var svg = d3.select('body').append('svg').attr('width',500).attr('height',300); 
 

 
var rects = svg.selectAll('rect') 
 
    .data(d3.range(100)) 
 
    .enter() 
 
    .append('rect') 
 
    .attr('width',18) 
 
    .attr('height',18) 
 
    .attr('fill', function(d,i) { return scale(i); }) 
 
    .attr('x', function(d,i) { return i%10 * 20 + 30; }) 
 
    .attr('y', function(d,i) { return Math.floor(i/10) * 20 + 30; });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>

+0

Danke für die Erklärung. Ihr Beispiel gab mir Zuversicht, dass ich nicht verrückt war! lol. In der Typoskript-Version von d3 scheint es den Eingabetyp des Bereichs auf ein Zahlenfeld zu beschränken. Ich habe 'import * als d3 von" d3 "' in 'var d3: any = require ('d3')' geschaltet, wodurch die Typeinschränkung aufgehoben wurde und es perfekt funktioniert. – mikey8989

+0

Manchmal wissen Sie nur, dass Sie nicht verrückt sind. Freut mich, dass Sie das Problem gelöst haben. –

Verwandte Themen