Reputation: 83
I'm using svg/d3 for creating a chart made of 'rect' elements.
What is the best way for adding a partical border/stroke for each rectangle (only on top of the rectangle)?
Thanks
Upvotes: 3
Views: 5502
Reputation: 21
If you want to go with stroke, then use stroke-dasharray. The simplest way to use it is with two numbers: stroke-dasharray = "length-of-dash, length-of-gap"
. These lengths can either be in the raw units of your SVG parent element (as defined in viewBox
) or as a percentage of the normalized diagonal of the viewBox-defined area or the SVG parent element: Math.sqrt((width ** 2) + (height ** 2)) / Math.sqrt(2)
.
So, if your rectangles and SVG are of a fixed size and you know exactly how big your <rect>
s will be, you can use stroke-dasharray = "width, perimeter - width"
. That's basically saying that your dash will be as long as your <rect>
is wide, and the dash gap will be as long as the length of the rest of the sides. The dash starts at the top-left corner and goes around the <rect>
clockwise, so this works out perfect for your use case.
On the other hand, if your table will be responsive, you'll have to do some math to make the percentages work.
Let's say fullDash = perimeter / normalizedDiagonal * 100
; that will be the percentage value that equates to a dash as long as the perimeter of your <rect>
.
topDash = width / perimeter
is the fraction of the perimeter we want to cover.
Now we can say that we want our dash to be dash = topDash * fullDash
and our gap to be at least fullDash
(but we could be exact if we wanted and call it gap = fullDash - dash
) so our final dasharray will look something like stroke-dasharray = "${dash}%, ${fullDash}%"
.
You can see a rough sketch of this here: https://dkallen78.github.io/math-trainer/experiments/dasharray-test.html
Upvotes: 0
Reputation: 55688
I don't think SVG supports stroking only portions of a rectangle or path - stroke isn't like a CSS border. You're left with a few other options, all of which take some extra work:
Stroke the entire rect
and apply a clipPath to remove the other three edges - probably works best if you make the rectangles bigger than necessary.
Apply a linear gradient fill to each rect, using the gradient definition to show a "border" at the top of the shape.
Add a separate line
element to act as the border for each rect
.
Use the stroke-dasharray
property (docs) to set a dash definition where the "dash" only covers the top of the rect
. This might be tricky to get right, but I suspect it wouldn't be too hard, as the stroke probably begins at the top left of the shape.
Upvotes: 9