Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a SVG path like a smooth line instead of being ragged

Well in my project I create river lines from pathes. And due to my kind of big stroke-width it is very ragged:

enter image description here

I already searched around. But the only thing I found was stroke-linejoin: round;. As you can see here:

enter image description here

it is way better but I'm still not satisfied.

Is there any way to get a really smooth line. Or let's say too have a even "rounder" linejoin?

like image 580
kwoxer Avatar asked Feb 20 '15 21:02

kwoxer


People also ask

Is it possible to draw any path in SVG?

It can draw anything! I've heard that under the hood all the other drawing elements ultimately use path anyway. The path element takes a single attribute to describe what it draws: the d attribute.

How do you draw a curved line in SVG?

The other type of curved line that can be created using SVG is the arc, called with the A command. Arcs are sections of circles or ellipses. For a given x-radius and y-radius, there are two ellipses that can connect any two points (as long as they're within the radius of the circle).


2 Answers

An interesting direction is to leverage d3.svg.line to generate paths from the coordinates of your geoJSON feature, at which point you would be able to use D3's interpolate methods.

See D3js-Topojson : how to move from pixelized to Bézier curves? and Geodata to d3.svg.line interpolation by E. Meeks, and Crispy edges with topojson? .


Edit: There is a minimal stand alone case study for line smoothing that you can fork via its associated gist's git repository. The idea of d3.svg.line together with interpolations of y coordinates for lines smoothing is from E.Meeks. E. Meeks explains his approach here.


Edit2 & solution: Í suddenly remembered where topojson is converted into geojson on the fly. Doing the following, you can work with topojson files and eventually get bezier curves, with the extrapolation of your choice. The following will work:

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

like image 87
Hugolpz Avatar answered Sep 28 '22 09:09

Hugolpz


If you're not satisfied with stroke-linejoin:round you could look into creating the path outline ,

but maybe it would be easier if you try to smooth out your path with cubic beziers.

like image 24
maioman Avatar answered Sep 28 '22 09:09

maioman