9

I have drawn a rect in svg using d3 and would like to stroke only the left and right side.

<rect class="extent" x="578" width="356" height="250"
      style="cursor: move; opacity: 0.2; fill: #FF9000;" ></rect>
KyleMit
  • 30,350
  • 66
  • 462
  • 664
imrane
  • 1,542
  • 2
  • 16
  • 29
  • possible duplicate of [How to set a stroke-width:1 on only certain sides of SVG shapes?](http://stackoverflow.com/questions/8976791/how-to-set-a-stroke-width1-on-only-certain-sides-of-svg-shapes) – KyleMit Jan 10 '15 at 00:52
  • Here's another SO question that has suggests a hack to do this: http://stackoverflow.com/questions/8976791/how-to-set-a-stroke-width1-on-only-certain-sides-of-svg-shapes – Jonah Apr 17 '13 at 23:07
  • 2
    You can just add `.attr("stroke-dasharray", [0, rectWidth, rectHeight, 0] )` to your rectangle and replace `rectWidth` and `rectHeight` with your values or variables. See the @Jonah comment above or the @tripathy answer https://stackoverflow.com/a/59773921 – Bemipefe Oct 26 '20 at 16:33

5 Answers5

5

It's another hack, but you can add a filter to your shape and clip the top and bottom by your strokewidth - which here I'm assuming is 1 unit.

<defs>
   <filter id="clippy" x="0" y="1" height="248" width="356">
     <feColorMatrix type="identity"/>
   </filter>
</defs>
<rect filter="url(#clippy)" class="extent" width="356" height="250"
      style="cursor: move;opacity: 0.2; fill: #FF9000;" x="578"></rect>

Update:

Here is the d3.js version of the answer created by Christopher Chiche (see original lower down):

svg.append("defs").append("filter")
    .attr("id", "clippy")
    .attr("x", "0")
    .attr("y", "1")
    .attr("height", "248")
    .attr("width" "356")
    .append("feColorMatrix")
    .attr("type", "identity")

svg.append("rect")
    .attr("filter", "url(#clippy)")
    .attr("class", "extent") 
    .attr("style", "cursor:move; opacity:0.2; fill: #FF9000")
    .attr("x", "578")
    .attr("height", "250")
    .attr("width" "356")

Edit:

Really, The best answer is probably to use the stroke-dasharray method - linked in the question comment above, rather than mess with filters.

Michael Mullany
  • 30,283
  • 6
  • 81
  • 105
4

Here is the d3.js version of the answer posted by Michael Mullany. I just did this as an exercise to have fun:

svg.append("defs").append("filter")
    .attr("id", "clippy")
    .attr("x", "0")
    .attr("y", "1")
    .attr("height", "248")
    .attr("width" "356")
    .append("feColorMatrix")
    .attr("type", "identity")

svg.append("rect")
    .attr("filter", "url(#clippy)")
    .attr("class", "extent") 
    .attr("style", "cursor:move; opacity:0.2; fill: #FF9000")
    .attr("x", "578")
    .attr("height", "250")
    .attr("width" "356")
General Grievance
  • 4,555
  • 31
  • 31
  • 45
Christopher Chiche
  • 15,075
  • 9
  • 59
  • 98
3

[Codepen] (https://codepen.io/shaswatatripathy/pen/oNgPpyd)

HTML

    <rect x="0.5" y="0.5" width="50" height="50" class="topBottom"/>


    <rect x="70.5" y="0.5" width="50" height="50" class="left"/>
    <rect x="140.5" y="0.5" width="50" height="50" class="topRight"/>
    <rect x="200.5" y="0.5" width="50" height="50" class="top"/>
  <rect x="260.5" y="0.5" width="50" height="50" class="bottomLeft"/>
  <rect x="320.5" y="0.5" width="50" height="50" class="bottomRight"/>

  <rect x="380.5" y="0.5" width="50" height="50" class="topLeft"/>

   <rect x="440.5" y="0.5" width="50" height="50" class="right"/>
  <rect x="500.5" y="0.5" width="50" height="50" class="bottom"/>

  <rect x="560.5" y="0.5" width="50" height="50" class="leftRight"/>

</svg>

CSS

rect { fill: none; stroke: black; }
.topBottom { stroke-dasharray: 50 }
.leftRight { stroke-dasharray: 0,50,50,0 }

.bottomLeft { stroke-dasharray: 0,100,150 }
.bottomRight { stroke-dasharray: 0,50,50 }
.topRight { stroke-dasharray: 100 }
.topLeft { stroke-dasharray: 50,100 }

.left { stroke-dasharray: 0,150,50 }
.top { stroke-dasharray: 50,150 }
.bottom { stroke-dasharray: 0,100,50,100 }
.right { stroke-dasharray: 0,50, 50,50 }
tripathy
  • 375
  • 2
  • 6
  • 23
0

My example was when using d3.js and the brush tool.

# Brush object
brush.x(core.xScale()).on("brush", onBrush)         

# Call the brush object
container.call(brush).selectAll("rect").attr("height", core.height())

# Method on brush
onBrush = () ->
  extent = brush.extent()
  extent = if brush.empty() then core.xScale().domain() else extent

Anyway, as part of the brush tool, 2 rectangles are added as left and right bounds to the brush. You can simply select these using css and restyle them. This is what I ended up doing and here is my solution in .less

.resize {
    rect { 
        visibility: visible !important;
        fill: #444444;
    }
}
imrane
  • 1,542
  • 2
  • 16
  • 29
-1

You can't seem to do that.

You probably need to draw a line on both sides and subtract those line-widths from the rect's current width.

  • This is not true. See the __Jonah__ comment above or the @tripathy answer stackoverflow.com/a/59773921 – Bemipefe Oct 26 '20 at 16:29