2015-02-20 7 views
6

Nun in meinem Projekt erstelle ich Flusslinien von Pathes. Und aufgrund meiner Art von großen Hub-Breite es ist sehr zackig:Erstellen eines SVG-Pfads wie eine glatte Linie statt zerlumpt

enter image description here

ich bereits um gesucht. Aber das einzige, was ich fand, war stroke-linejoin: round;. Wie Sie hier sehen können:

enter image description here

es ist viel besser, aber ich bin noch nicht zufrieden.

Gibt es eine Möglichkeit, eine wirklich glatte Linie zu bekommen. Oder sagen wir mal, haben Sie auch eine "Rounder" linejoin?

Antwort

7

Eine interessante Richtung besteht darin, d3.svg.line zu nutzen, um Pfade aus den Koordinaten Ihrer geoJSON-Funktion zu erzeugen. An diesem Punkt könnten Sie die interpolierten Methoden von D3 verwenden.

Siehe D3js-Topojson : how to move from pixelized to Bézier curves? und Geodata to d3.svg.line interpolation von E. Meeks und Crispy edges with topojson?.


Edit: Es gibt eine minimal stand alone case study for line smoothing, die Sie über seinen zugeordneten Kern des Git Repository verzweigen kann. Die Idee von d3.svg.line zusammen mit Interpolationen von y Koordinaten für Linien Glättung ist von E.Meeks. E. Meeks erklärt seinen Ansatz here.


EDIT2 & Lösung: erinnerte ich mich plötzlich, wo topojson in GeoJSON on the fly umgewandelt wird. Im Folgenden können Sie mit Topojson-Dateien arbeiten und schließlich Bezier-Kurven mit der Extrapolation Ihrer Wahl erhalten. Im Folgenden wird funktionieren:

d3.json("./world-110m.json", function(data){ 
    console.log(data) 
    var geojson = topojson.feature(data, data.objects.countries); 
    var newJson = newgeoson(geojson); 
    console.log(JSON.stringify(newJson)) 

    d3.select("body").append("svg").attr("id","world") 
     .selectAll("path") 
     .data(newJson) 
     .enter() 
     .append("path") 
     .style("stroke-width", 1) 
     .style("stroke", "black") 
     .style("fill-opacity", .5) 
     .attr("d", d3.svg.line() 
      .x(function(d){ return d[0] }) 
      .y(function(d){ return d[1] }).interpolate("cardinal")) 
     .style("fill", "#7fc97f"); 
}) 

Live-Demo: Minimal d3js line smoothing, topojson version

enter image description here

+0

Ja das sieht gut aus. Will Lesezeichen und versuche, wenn ich etwas Zeit dafür habe. Vielen Dank. – kwoxer

+2

Ich selbst wählte schließlich eher eine subtilere Topojson-Vereinfachung über das Topojson-Kommandozeilen-Tool. Aber dieser @Emeeks Weg hat auch meine Augen angezogen. – Hugolpz

+2

Aber Vereinfachung bedeutet, dass ich Daten verliere. Aber ich möchte, dass es gedruckt wird, so wie ich es gezeichnet habe =) Also das ist keine Lösung für mich. Wie gesagt, wenn ich zurückkomme, wenn ich arbeite oder Probleme habe =) Danke. – kwoxer

2

Wenn Sie sich nicht mit stroke-linejoin:round zufrieden konnte man die path outline,

schaut in der Schaffung, aber vielleicht wäre es einfacher, wenn Sie versuchen, Ihren Weg zu glätten mit cubic beziers.

+0

Cubic beziers sind nicht wirklich eine Option, ich brauche aus irgendwelchen Gründen den Weg zu nehmen. Und das andere Beispiel sieht ziemlich schwierig aus, aber interessant =/Aber keine Ahnung, wie man anfangen soll und eine CSS-Lösung wäre viel besser. – kwoxer

2

Wenn Sie unzufrieden sind mit, wie es aussieht, dann scheint mir, dass das Problem ist, dass Ihr Fluss mit zu wenig Punkten definiert ist.

Jede Technik, die Sie den Pfad glätten verwenden, um, wie ein Kurvenanpassungsalgorithmus, wahrscheinlich in einer Darstellung Ihrer Fluss führt, die als noch weniger genau ist, was Sie jetzt haben.

+0

Eigentlich ist es Topojson und der ursprüngliche Fluss hat wirklich viele verschiedene Punkte in der Linie des Flusses. So könnte es der Topojson sein, dass es die Punkte irgendwie reduziert, um eine kleinere Datei zu erhalten. – kwoxer