Search code examples
angularjssvgangularjs-ng-repeatrectangles

Make multiple small rectangles inside big rectangle using svg and ng-repeat


I have this code where I need to display multiple small rectangles inside a big rectangle and I need to do this entire process multiple times.

here is my data:

"data": {
  "rect1": { 
     "a":[10,20],
     "b":[35,10] 
   },
   "rect2": {
     "y":[25,10],
     "z":[55,20] 
   }
}

This data should make two rectangles rect1 and rect2 and two rectangles inside each of them a,b and y,z respectively. each small rectangle has start position x and width of that small rectangle for example a starts at x 10 and width=20.

<ul>
    <li ng-repeat="(rect,coords) in data">
    <svg>
    <rect x=1 y=1 width=1000 height=50 style="fill:grey;" />
    <span ng-repeat="coord in coords">
    <rect x={{coord[0]}} y=1 width={{coord[1]}} height=50 style="fill:blue;" />             


enter code here

But this code is not working as I have added ng-repeat line between the two tags.

image of what the final result should look like

I made this image in powerpoint so ignore the background.


Solution

  • You were pretty close. You can't use <span> inside an SVG. But most of the rest was correct.

    Also it is better to use ng-attr-x="{{value}} instead of x="{{value}}. Otherwise the SVG parser will throw errors because it doesn't understand the string "{{value}}".

    Here is a working example.

    var app = angular.module('myApp', [])
    
    app.controller("AppCtrl", ["$scope", function($scope) {
      
      $scope.data = {
        "rect1": { 
           "a":[10,20],
           "b":[35,10] 
         },
         "rect2": {
           "y":[25,10],
           "z":[55,20] 
         }
      };
    
    }]);
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    
    <div ng-app="myApp">
    
      <ul ng-controller="AppCtrl">
        <li ng-repeat="(rectName, coords) in data">
          <svg id="{{rectName}}" width="100%" height="50">
            <rect x="1" y="1" width="1000" height="50"
                  style="fill: lightgrey;" />
            <rect ng-repeat="(label, coord) in coords"
                  ng-attr-x="{{coord[0]}}" y="1"
                  ng-attr-width="{{coord[1]}}" height="50"
                  style="fill: blue;" />
            <text ng-repeat="(label, coord) in coords"
                  ng-attr-x="{{coord[0]}}" y="25"
                  style="fill: white;">{{label}}</text>
          </svg>
        </li>
      </ul>
    
    </div>