Black Lives Matter. Please consider donating to Black Girls Code today.
Dash HoloViews is now available! Check out the docs.

Scaling plotly plots not working: Why are there two svg directives with a class of "main-svg"?

I have been trying to re-size plotly plots that I have on a web application that I am building. We are using AngularJS for the front-end and using plotly for our plots.

At the moment I have a page view with three boxplot plotly plots next to each other (inside a div with class set to col-md-8). These three boxplots visibility should be able to be turned on/off while centering the boxplots that are visible. I have come as far as drawing the boxplots, and centering the divs which contain the boxplots, but for some reason the actual canvas on which the plotly plot is, sometimes doesn’t scale/resize properly, and stays to “stretched” out.

In the attached image, I have forced the canvas width to remain within the parent div by setting the width to 100% (not sure if it is a bad idea or bad practise, but it seemed to work.) However, my issue now is that the actual boxplot inside, goes “underneath” the parent div, and some of the plot is “missing”. I have added (as you can see in the image) a “Scale” button, which I tied up so that a new plot is created (relayout, restyle and redraw didn’t help either). Any help here? (Code is below)

While debugging my problem, I came upon two tags, both with a class of “main-svg”. They looked very similar to me, and I couldn’t figure out what makes them different?

// Need to redraw the boxplots everytime a "re-scaling" is done, otherwise, the plot won't re-scale
scope.$on('redraw_boxplots', function () {
  var graph, layout, options, data;
  graph = plotlyProcessing.makeGraph(scope.plots,
                                                      scope.graphType,
                                                      scope.params);
   data = graph[0];
   // Merges while maintaining the original data in graph[1]/[2]
   layout = angular.merge({}, defaultLayout, graph[1]);
   options = angular.merge({}, defaultOptions, graph[2]);

   Plotly.newPlot(graphDiv, data, layout, options);
});

While debugging I realised something: because the three box plots visibility should be able to be toggled while centring the box plots that are visible, I used a dynamic variable to set the col width in my html. So the code for one of the rows (the dotted green line in the image) would look something like:

<div class="row new-line-padding"
     ng-repeat="row in profile.row"
     style="border: 6px dotted green">
  
  <div class="col-md-2">
  </div>

  <div class="col-md-8">
    <div class="{{htmlClass_1}}">
      <plotly box plot 1>
    </div>

    <div class="{{htmlClass_2}}">
      <plotly box plot 2>
    </div>

    <div class="{{htmlClass_3}}">
      <plotly box plot 3>
    </div>
  </div>

  <div class="col-md-2">
  </div>
  
</div>

Now, if all three box plots are visible, as in the image, then I expect htmlClass_1, htmlClass_2 and htmlClass_3 to be equal to col-md-4. However, instead of the draglayer being within a col-md-4, the draglayer is extended across the entire div whose col width is col-md-8. I tested this by replacing the htmlClass lines (so essentially hard coding it for one scenario) to:

<div class="col-md-4">

for each one. This was successful and the draglayer (as in the image) was this time not stretched out to the full width of the div whose col width is col-md-8 but instead to the full width of the col-md-4 div.

So, my question is how can I fix this problem now that it is (hopefully) clear where the problem lies? Do I remove the {{htmlClass_n}} lines and use some clever if logic to identify which plots are selected and then use col-md-4, col-md-6 or col-md-12 as necessary? This will mean the html code will will be longer with duplicated snippets:

<div class="col-md-8">
    <div class="row" ng-if="three plots are selected...">
        <div class="col-md-4">
            <plotly box plot 1>
        </div>
        <div class="col-md-4">
            <plotly box plot 2>
        </div>
        <div class="col-md-4">
            <plotly box plot 3>
        </div>
    </div>
    <div class="row" ng-if="two plots are selected...">
        <div class="col-md-6">
            <plotly box plot 1>
        </div>
        <div class="col-md-6">
            <plotly box plot 2>
        </div>
    </div>
    <div class="row" ng-if="one plot is selected...">
        <div class="col-md-12">
            <plotly box plot 1>
        </div>
    </div>
</div>

Or is there some clever way to get the drag layer to “resize” to a new col width as specified by htmlClass?