Jeril
Jeril

Reputation: 8521

Responsive PlotlyJS chart in Bootstrap card

The following is my js code to plot a reponsive plot using PlotlyJS.

var trace1 = {
  x: ['Category A', 'Category B', 'Category C', 'Category D ', 'Category E', 'Category F', 'Category G', 'Category H'],
  y: [20, 14, 23, 20, 14, 23, 34, 26],
  marker: {
    color: ['rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)']
  },
  name: 'Item 1',
  type: 'bar'
};

var trace2 = {
  x: ['Category A', 'Category B', 'Category C', 'Category D ', 'Category E', 'Category F', 'Category G', 'Category H'],
  y: [12, 18, 29, 12, 18, 29, 24, 22],
  marker: {
    color: ['rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)']
  },
  name: 'Item 2',
  type: 'bar'
};

var trace3 = {
  x: ['Category A', 'Category B', 'Category C', 'Category D ', 'Category E', 'Category F', 'Category G', 'Category H'],
  y: [12, 18, 29, 12, 18, 29, 24, 22],
  marker: {
    color: ['rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)']
  },
  name: 'Item 3',
  type: 'bar'
};

var data = [trace1, trace2, trace3];

var layout = {
  barmode: 'stack',
};

Plotly.newPlot('myDivPlotly', data, layout);

// code to make plotlyjs responsive
(function() {
  var d3 = Plotly.d3;
  var WIDTH_IN_PERCENT_OF_PARENT = 100,
      HEIGHT_IN_PERCENT_OF_PARENT = 100;

  var gd3 = d3.selectAll(".responsive-plot")
      .style({
        width: WIDTH_IN_PERCENT_OF_PARENT + '%',
        'margin-left': (100 - WIDTH_IN_PERCENT_OF_PARENT) / 2 + '%',

        height: HEIGHT_IN_PERCENT_OF_PARENT + 'vh',
        'margin-top': (100 - HEIGHT_IN_PERCENT_OF_PARENT) / 2 + 'vh'
      });

  var nodes_to_resize = gd3[0]; //not sure why but the goods are within a nested array
  window.onresize = function() {
    for (var i = 0; i < nodes_to_resize.length; i++) {
      Plotly.Plots.resize(nodes_to_resize[i]);
    }
  };

})();

The following is my HTML code to plot the plotlyJS chart in Bootstrap card.

<div class="container">
  <div class="row">
    <div class="col-md-6">
      <div class="card">
        <h5 class="card-header">Featured</h5>
        <div class="card-body">
          <h5 class="card-title">Special title treatment</h5>
          <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
          <a href="#" class="btn btn-primary">Go somewhere</a>
        </div>
      </div>
    </div>
    <div class="col-md-6">
      <div class="card">
        <h5 class="card-header">Featured</h5>
        <div class="card-body">
          <div class="responsive-plot" id="myDivPlotly">
        </div>
      </div>
    </div>
  </div>
</div>

The chart is now reponsive, but the problem is there is lot of empty space above and below that plot. How to remove the empty spaces surrounding the plot or reduce the height of the card.

enter image description here

Kindly help. Thanks.

Upvotes: 0

Views: 2738

Answers (3)

Tharu1515
Tharu1515

Reputation: 85

You have to do a small thing to remove the blank spaces bottom. But in the top margin there is plotly bar which is hidden and showing only when mouse-over on it. You have to change these in your .js file.

var gd3 = d3.selectAll(".responsive-plot")
        .style({
          width: 'fit-content',
          'margin-left': (100 - WIDTH_IN_PERCENT_OF_PARENT) / 2 + '%',

          height: 'fit-content',
          'margin-top': '0vh'
        });

Upvotes: 2

Jeril
Jeril

Reputation: 8521

Finally I got the answer, all I had to do is the following:

var data = [trace1, trace2, trace3];

var layout = {
  barmode: 'stack',
  margin: {
    t: 0
  },
  autosize: true // set autosize to rescale
};

var config = {
  'displayModeBar': false
}

Plotly.newPlot('myDivPlotly', data, layout, config);

// update the layout to expand to the available size
// when the window is resized
window.onresize = function() {
    Plotly.relayout('myDivPlotly', {
        'xaxis.autorange': true,
        'yaxis.autorange': true
    });
};

Upvotes: 0

shrys
shrys

Reputation: 5960

You can use the properties in layout.margin:

var trace1 = {
  x: ['Category A', 'Category B', 'Category C', 'Category D ', 'Category E', 'Category F', 'Category G', 'Category H'],
  y: [20, 14, 23, 20, 14, 23, 34, 26],
  marker: {
    color: ['rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)', 'rgba(0,152,212,0.5)']
  },
  name: 'Item 1',
  type: 'bar'
};

var trace2 = {
  x: ['Category A', 'Category B', 'Category C', 'Category D ', 'Category E', 'Category F', 'Category G', 'Category H'],
  y: [12, 18, 29, 12, 18, 29, 24, 22],
  marker: {
    color: ['rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)', 'rgba(0,152,212,1)']
  },
  name: 'Item 2',
  type: 'bar'
};

var trace3 = {
  x: ['Category A', 'Category B', 'Category C', 'Category D ', 'Category E', 'Category F', 'Category G', 'Category H'],
  y: [12, 18, 29, 12, 18, 29, 24, 22],
  marker: {
    color: ['rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)', 'rgba(0,54,136,1)']
  },
  name: 'Item 3',
  type: 'bar'
};

var data = [trace1, trace2, trace3];

var layout = {
  barmode: 'stack',
  margin: {
    l: 60,
    r: 10,
    b: 10,
    t: 10,
    pad: 4
  }
};

Plotly.newPlot('myDivPlotly', data, layout);

// code to make plotlyjs responsive
(function() {
  var d3 = Plotly.d3;
  var WIDTH_IN_PERCENT_OF_PARENT = 100,
    HEIGHT_IN_PERCENT_OF_PARENT = 100;

  var gd3 = d3.selectAll(".responsive-plot")
    .style({
      width: WIDTH_IN_PERCENT_OF_PARENT + '%',
      'margin-left': (100 - WIDTH_IN_PERCENT_OF_PARENT) / 2 + '%',

      height: HEIGHT_IN_PERCENT_OF_PARENT + 'vh',
      'margin-top': (100 - HEIGHT_IN_PERCENT_OF_PARENT) / 2 + 'vh'
    });

  var nodes_to_resize = gd3[0]; //not sure why but the goods are within a nested array
  window.onresize = function() {
    for (var i = 0; i < nodes_to_resize.length; i++) {
      Plotly.Plots.resize(nodes_to_resize[i]);
    }
  };

})();
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div class="container">
  <div class="row">
    <div class="col-md-6">
      <div class="card">
        <h5 class="card-header">Featured</h5>
        <div class="card-body">
          <h5 class="card-title">Special title treatment</h5>
          <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
          <a href="#" class="btn btn-primary">Go somewhere</a>
        </div>
      </div>
    </div>
    <div class="col-md-6">
      <div class="card">
        <h5 class="card-header">Featured</h5>
        <div class="card-body">
          <div class="responsive-plot" id="myDivPlotly">
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Upvotes: 0

Related Questions