flip svg coordinate system

后端 未结 8 608
走了就别回头了
走了就别回头了 2020-12-07 23:55

Is there a way to flip the SVG coordinate system so that [0,0] is in the lower left instead of the upper left?

相关标签:
8条回答
  • 2020-12-08 00:40

    The best all around combo I've found for transforming to a cartesian coordinate system is pretty simple:

    css

    svg.cartesian {
      display:flex;
    }
    
    /* Flip the vertical axis in <g> to emulate cartesian. */
    svg.cartesian > g {
      transform: scaleY(-1);
    }
    
    /* Re-flip all <text> element descendants to their original side up. */
    svg.cartesian > g text {
      transform: scaleY(-1);
    }
    <html>
      <head></head>
      <body>
    
      <svg class="cartesian" viewBox="-100 -100 200 200" preserveAspectRatio="xMidYMid meet">
      <g>
        <!-- SVG Start -->
    
        <!-- Vertical / Horizontal Axis: Can be removed if you don't want x/y axes. -->
        <path d="M0 -100 V 200" stroke="green" stroke-width="0.5" stroke-opacity="0.5" />
        <path d="M-100 0 H 200" stroke="green" stroke-width="0.5" stroke-opacity="0.5" />
        
        <!-- Plotting: This is an example plotting two points at (20, 20) and (-50, -35), replace it with your data. -->
        <g transform="translate(20, 20)">
          <circle r="1" />
          <text>(20, 20)</text>
        </g>
        <g transform="translate(-50, -35)">
          <circle r="0.5" />
          <text>(-50, -35)</text>
        </g>
    
        <!-- SVG End -->
      </g>
      </svg>
        </body>
      </html>

    This will auto-unflip all the text elements on the page via the css scaleY(-1).

    0 讨论(0)
  • 2020-12-08 00:49

    An alternative is to use D3 v4 scaleLinear to create a function that will do the swapping for you.

    import * as d3 from "d3";
    
    ...
    
    // Set the height to the actual value to where you want to shift the coords.
    // Most likely based on the size of the element it is contained within
    let height = 1; 
    let y = d3.scaleLinear()
      .domain([0,1])
      .range([height,0]);
    
    console.log("0 = " + y(0));       // = 1
    console.log("0.5 = " + y(0.5));   // = 0.5
    console.log("1 = " + y(1));       // = 0
    console.log("100 = " + y(100));   // = -99
    console.log("-100 = " + y(-100)); // = 101
    

    See runable code via tonic

    0 讨论(0)
提交回复
热议问题