Inconsistent line width - D3 or SVG quirks?

2,373 views
Skip to first unread message

Curran

unread,
Sep 16, 2013, 11:43:41 PM9/16/13
to d3...@googlegroups.com
Greetings,

I've created a simple line chart visualization of population over time and am seeing two small quirks:
  1. The line on the Y axis sometimes renders as one pixel thick (which I want), but sometimes renders as two pixels thick.
  2. The box around the visualization sometimes renders as a single pixel (which I want), but sometimes it doesn't render at all.
For both 1.) and 2.), in an attempt to get lines to be one pixel all the time, I ended up with the following CSS:

  fill: none;
  stroke: black;
  stroke-width: 1px;
  shape-rendering: crispEdges;

Can anyone spot something I am doing wrong that is causing the inconsistent line width?

Here is a screenshot of the errors happening (the Y axis is too thick, and the right side of the frame rectangle is missing). Here's the full code in GitHub (main files are main.js and styles.css). Here's the running code. Any help or general advice would be greatly appreciated.

Thank you all for your great work on D3!

Best regards,
Curran

Shreeram Kushwaha

unread,
Sep 16, 2013, 11:56:23 PM9/16/13
to d3...@googlegroups.com
Dear Curran

Here it goes. 

1.)This is the CSS for the x and y axes

.axis path,
.axis line {
  fill: none;
  stroke: black;
  stroke-width: 1px;
  shape-rendering: crispEdges;
}

I don't see where you have defined a class called axis in your code. Because the class names are 'x axis' and 'y axis'

Solution: rename the classes to 'xaxis' and 'yaxis' instead of 'x axis' or 'y axis'.
Change the CSS to 
.xaxis path,
.xaxis line,
.yaxis path,
.yaixs line {
  fill: none;
  stroke: black;
  stroke-width: 1px;
  shape-rendering: crispEdges;
}


2.) See this line

<rect x="0" y="0" width="1440" height="457" stroke-width="1.5" stroke="black" fill-opacity="0" style="shape-rendering: crispedges;"></rect>
You haven't set the stoke width for the box around the visualization to 1px rather its 1.5px. 



--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Regards,

(Voice  +91-7849069144)
( Shreeram Kushwaha )
Software Engineer
Samsung R&D Institute India - Bangalore

Kai Chang

unread,
Sep 17, 2013, 1:03:34 AM9/17/13
to d3...@googlegroups.com
crispEdges is causing lines to either not show up or be double width.

It's like rounding, but for pixels. Sometimes it rounds down or up depending on where the line ends up between pixels.

Curran

unread,
Sep 20, 2013, 3:39:07 PM9/20/13
to d3...@googlegroups.com, kai.s...@gmail.com
Shreeram, thank you for your comments. D3 creates elements with the "axis" class. The CSS does indeed apply to the axes elements. When I change, for example, "stroke-width: 1px;" to "stroke-width: 10px;", I get 10 pixel wide axes lines.

Kai, thank you for pointing out the behavior of crisp-edges. It seems that this makes crisp-edges unusable for getting consistent 1 pixel lines.

From these replies and everything I have tried, it seems impossible to get axis lines to draw as 1 pixel wide, and impossible to get a rectangle to always draw with a 1 pixel border (with D3 and SVG in Chrome). Can this be true? Has anyone faced a similar issue before and found a solution? Are there any other approaches for 1-pixel lines besides CSS crisp-edges?

I suppose my best option here is to give up the idea of crispness in my visualization and just use the anti-aliased version of everything, which does not look good, but is better than random glitches.

If anyone wants to check it out, here's the code in GitHub and the running visualization.

On another note, the stacked areas are not on the bottom and I'm not sure why. Can anyone see where I'm going wrong?

Thank you for your replies.

Best regards,
Curran

Riccardo Scalco

unread,
Dec 16, 2014, 11:22:11 AM12/16/14
to d3...@googlegroups.com
Try adding the viewBox attribute to the svg element, with entries equals to the svg width and height.
Reply all
Reply to author
Forward
0 new messages