Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions js/src/mpl_widget.css
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
.jupyter-matplotlib {
height: 500px;
flex: 1 1 auto;
width: auto;
height: auto;
}

/* Toolbar */

.jupyter-matplotlib-toolbar {
flex: 0 0 auto;
}

.jupyter-matplotlib-button {
width: calc(var(--jp-widgets-inline-width-tiny) / 2 - 2px);
overflow: hidden;
padding: 0;
}

/* Figure */

.jupyter-matplotlib-figure {
width: 100%;
height: 100%;
width: auto;
height: auto;
overflow: hidden;
}

.jupyter-matplotlib-canvas_div {
Expand Down
75 changes: 68 additions & 7 deletions js/src/mpl_widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ var MPLCanvasView = widgets.DOMWidgetView.extend({

that.model_events();

window.addEventListener('resize', that.request_resize.bind(that));

that.send_initialization_message();
});
},
Expand Down Expand Up @@ -112,6 +110,8 @@ var MPLCanvasView = widgets.DOMWidgetView.extend({
this.el.appendChild(this.toolbar_view.el);
}
}

this.request_resize();
},

clear: function() {
Expand All @@ -123,6 +123,8 @@ var MPLCanvasView = widgets.DOMWidgetView.extend({
_init_header: function() {
this.header = document.createElement('div');
this.header.style.textAlign = 'center';
this.header.style.flexGrow = 0;
this.header.style.flexShrink = 0;
this.header.classList = 'jupyter-widgets widget-label';
this.figure.appendChild(this.header);
},
Expand Down Expand Up @@ -212,15 +214,64 @@ var MPLCanvasView = widgets.DOMWidgetView.extend({
_init_footer: function() {
this.footer = document.createElement('div');
this.footer.style.textAlign = 'center';
this.header.style.flexGrow = 0;
this.header.style.flexShrink = 0;
this.footer.classList = 'jupyter-widgets widget-label';
this.figure.appendChild(this.footer);
},

_calculate_decorations_size: function() {
// Calculate the size of the decorations on the figure.
var decorations_width = 0;
var decorations_height = 0;

// Toolbar size
var toolbar_position = this.model.get('toolbar_position');
if (toolbar_position == 'top' || toolbar_position == 'bottom') {
decorations_height += utils.get_full_size(this.toolbar_view.el).height;
} else {
decorations_width += utils.get_full_size(this.toolbar_view.el).width;
}

// Label sizes
decorations_height += utils.get_full_size(this.header).height;
decorations_height += utils.get_full_size(this.footer).height;

// Margins on the canvas
var canvas_div_margins = utils.get_margin_size(this.canvas_div);
decorations_width += canvas_div_margins.width;
decorations_height += canvas_div_margins.height;

// Margins on the figure div
var figure_margins = utils.get_margin_size(this.figure);
decorations_width += figure_margins.width;
decorations_height += figure_margins.height;

return {
width: decorations_width,
height: decorations_height
};
},

request_resize: function() {
// Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,
// which will in turn request a refresh of the image.
var rect = this.canvas_div.getBoundingClientRect();
this.send_message('resize', {'width': rect.width, 'height': rect.height});
// Ensure that the image already exists. We ignore the first calls to resize
// because we want the widget to first adapt to the figure size set in
// matplotlib.
if (!this.image.src) {
return;
}

// Using the given widget size, figure out how big the canvas should be.
var decorations_size = this._calculate_decorations_size();

var new_canvas_width = this.el.clientWidth - decorations_size.width;
var new_canvas_height = this.el.clientHeight - decorations_size.height;

// Ensure that the canvas size is a positive number.
new_canvas_width = new_canvas_width < 1 ? 1 : new_canvas_width;
new_canvas_height = new_canvas_height < 1 ? 1 : new_canvas_height;

this.send_message('resize', {'width': new_canvas_width, 'height': new_canvas_height});
},

_resize_canvas: function(width, height) {
Expand All @@ -231,6 +282,16 @@ var MPLCanvasView = widgets.DOMWidgetView.extend({

this.rubberband_canvas.setAttribute('width', width);
this.rubberband_canvas.setAttribute('height', height);

this.canvas_div.style.width = width + 'px';
this.canvas_div.style.height = height + 'px';

// Figure out the widget size.
var decorations_size = this._calculate_decorations_size();

// Reset the widget size to adapt to this figure.
this.el.style.width = width + decorations_size.width + 'px';
this.el.style.height = height + decorations_size.height + 'px';
},

send_message: function(type, message = {}) {
Expand Down Expand Up @@ -368,12 +429,12 @@ var MPLCanvasView = widgets.DOMWidgetView.extend({

switch (msg.type) {
case 'resize':
// case 'after-show':
this.request_resize();
break;
}
},


mouse_event: function(name) {
var that = this;
var last_update = 0;
Expand Down
35 changes: 34 additions & 1 deletion js/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,41 @@ function get_simple_keys(original) {
}, {});
}

/*
* Return the total size of the margins for an element in both width and height.
*/
function get_margin_size(el) {
var style = getComputedStyle(el);

var margin_width = parseFloat(style.marginLeft) + parseFloat(style.marginRight);
var margin_height = parseFloat(style.marginTop) + parseFloat(style.marginBottom);

return {
width: margin_width,
height: margin_height,
};
}


/*
* Return the full size of an element, including margins.
*/
function get_full_size(el) {
var margin_size = get_margin_size(el);

var full_width = el.scrollWidth + margin_size.width;
var full_height = el.scrollHeight + margin_size.height;

return {
width: full_width,
height: full_height,
};
}

module.exports = {
offset: offset,
get_mouse_position: get_mouse_position,
get_simple_keys: get_simple_keys
get_simple_keys: get_simple_keys,
get_margin_size: get_margin_size,
get_full_size: get_full_size,
}