Skip to content

Commit

Permalink
Merge pull request #3068 from plotly/3063-modebar-style
Browse files Browse the repository at this point in the history
modeBar styling
  • Loading branch information
antoinerg authored Oct 5, 2018
2 parents a285aeb + db9edd1 commit 88d48c5
Show file tree
Hide file tree
Showing 11 changed files with 293 additions and 49 deletions.
14 changes: 7 additions & 7 deletions build/plotcss.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,21 @@ var rules = {
"X .cursor-n-resize": "cursor:n-resize;",
"X .cursor-ne-resize": "cursor:ne-resize;",
"X .cursor-grab": "cursor:-webkit-grab;cursor:grab;",
"X .modebar": "position:absolute;top:2px;right:2px;z-index:1001;background:rgba(255,255,255,0.7);",
"X .modebar": "position:absolute;top:2px;right:2px;z-index:1001;",
"X .modebar--hover": "opacity:0;-webkit-transition:opacity 0.3s ease 0s;-moz-transition:opacity 0.3s ease 0s;-ms-transition:opacity 0.3s ease 0s;-o-transition:opacity 0.3s ease 0s;transition:opacity 0.3s ease 0s;",
"X:hover .modebar--hover": "opacity:1;",
"X .modebar-group": "float:left;display:inline-block;box-sizing:border-box;margin-left:8px;position:relative;vertical-align:middle;white-space:nowrap;",
"X .modebar-group:first-child": "margin-left:0px;",
"X .modebar-btn": "position:relative;font-size:16px;padding:3px 4px;cursor:pointer;line-height:normal;box-sizing:border-box;",
"X .modebar-btn": "position:relative;font-size:16px;padding:3px 4px;height:22px;cursor:pointer;line-height:normal;box-sizing:border-box;",
"X .modebar-btn svg": "position:relative;top:2px;",
"X .modebar-btn path": "fill:rgba(0,31,95,0.3);",
"X .modebar-btn.active path,X .modebar-btn:hover path": "fill:rgba(0,22,72,0.5);",
"X .modebar-btn.modebar-btn--logo": "padding:3px 1px;",
"X .modebar-btn.modebar-btn--logo path": "fill:#447adb !important;",
"X .modebar.vertical": "top:-1px;",
"X .modebar.vertical .modebar-group": "display:block;float:none;margin-left:0px;margin-bottom:8px;",
"X .modebar.vertical .modebar-group .modebar-btn": "display:block;text-align:center;",
"X [data-title]:before,X [data-title]:after": "position:absolute;-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-o-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);display:none;opacity:0;z-index:1001;pointer-events:none;top:110%;right:50%;",
"X [data-title]:hover:before,X [data-title]:hover:after": "display:block;opacity:1;",
"X [data-title]:before": "content:'';position:absolute;background:transparent;border:6px solid transparent;z-index:1002;margin-top:-12px;border-bottom-color:#69738a;margin-right:-6px;",
"X [data-title]:after": "content:attr(data-title);background:#69738a;color:white;padding:8px 10px;font-size:12px;line-height:12px;white-space:nowrap;margin-right:-18px;border-radius:2px;",
"X .vertical [data-title]:before,X .vertical [data-title]:after": "top:0%;right:200%;",
"X .vertical [data-title]:before": "border:6px solid transparent;border-left-color:#69738a;margin-top:8px;margin-right:-30px;",
"X .select-outline": "fill:none;stroke-width:1;shape-rendering:crispEdges;",
"X .select-outline-1": "stroke:white;",
"X .select-outline-2": "stroke:black;stroke-dasharray:2px 2px;",
Expand Down
8 changes: 6 additions & 2 deletions build/ploticon.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ module.exports = {
'transform': 'matrix(1 0 0 -1 0 850)'
},
'zoom_plus': {
'width': 1000,
'width': 875,
'height': 1000,
'path': 'm1 787l0-875 875 0 0 875-875 0z m687-500l-187 0 0-187-125 0 0 187-188 0 0 125 188 0 0 187 125 0 0-187 187 0 0-125z',
'transform': 'matrix(1 0 0 -1 0 850)'
},
'zoom_minus': {
'width': 1000,
'width': 875,
'height': 1000,
'path': 'm0 788l0-876 875 0 0 876-875 0z m688-500l-500 0 0 125 500 0 0-125z',
'transform': 'matrix(1 0 0 -1 0 850)'
Expand Down Expand Up @@ -120,5 +120,9 @@ module.exports = {
'height': 1000,
'path': 'M512 409c0-57-46-104-103-104-57 0-104 47-104 104 0 57 47 103 104 103 57 0 103-46 103-103z m-327-39l92 0 0 92-92 0z m-185 0l92 0 0 92-92 0z m370-186l92 0 0 93-92 0z m0-184l92 0 0 92-92 0z',
'transform': 'matrix(1.5 0 0 -1.5 0 850)'
},
'newplotlylogo': {
'name': 'newplotlylogo',
'svg': '<svg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 132 132\'><defs><style>.cls-1 {fill: #119dff;} .cls-2 {fill: #25fefd;} .cls-3 {fill: #fff;}</style></defs><title>plotly-logomark</title><g id=\'symbol\'><rect class=\'cls-1\' width=\'132\' height=\'132\' rx=\'6\' ry=\'6\'/><circle class=\'cls-2\' cx=\'78\' cy=\'54\' r=\'6\'/><circle class=\'cls-2\' cx=\'102\' cy=\'30\' r=\'6\'/><circle class=\'cls-2\' cx=\'78\' cy=\'30\' r=\'6\'/><circle class=\'cls-2\' cx=\'54\' cy=\'30\' r=\'6\'/><circle class=\'cls-2\' cx=\'30\' cy=\'30\' r=\'6\'/><circle class=\'cls-2\' cx=\'30\' cy=\'54\' r=\'6\'/><path class=\'cls-3\' d=\'M30,72a6,6,0,0,0-6,6v24a6,6,0,0,0,12,0V78A6,6,0,0,0,30,72Z\'/><path class=\'cls-3\' d=\'M78,72a6,6,0,0,0-6,6v24a6,6,0,0,0,12,0V78A6,6,0,0,0,78,72Z\'/><path class=\'cls-3\' d=\'M54,48a6,6,0,0,0-6,6v48a6,6,0,0,0,12,0V54A6,6,0,0,0,54,48Z\'/><path class=\'cls-3\' d=\'M102,48a6,6,0,0,0-6,6v48a6,6,0,0,0,12,0V54A6,6,0,0,0,102,48Z\'/></g></svg>'
}
};
65 changes: 49 additions & 16 deletions src/components/modebar/modebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var isNumeric = require('fast-isnumeric');

var Lib = require('../../lib');
var Icons = require('../../../build/ploticon');

var Parser = new DOMParser();

/**
* UI controller for interactive plots
Expand Down Expand Up @@ -45,13 +45,29 @@ var proto = ModeBar.prototype;
proto.update = function(graphInfo, buttons) {
this.graphInfo = graphInfo;

var context = this.graphInfo._context;
var context = this.graphInfo._context,
fullLayout = this.graphInfo._fullLayout,
modeBarId = 'modebar-' + fullLayout._uid;

this.element.setAttribute('id', modeBarId);
this._uid = modeBarId;

if(context.displayModeBar === 'hover') {
this.element.className = 'modebar modebar--hover';
}
else this.element.className = 'modebar';

if(fullLayout.modebar.orientation === 'v') {
this.element.className += ' vertical';
buttons = buttons.reverse();
}

Lib.deleteRelatedStyleRule(modeBarId);
Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId, 'background-color: ' + fullLayout.modebar.bgcolor);
Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId + ' .modebar-btn .icon path', 'fill: ' + fullLayout.modebar.color);
Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId + ' .modebar-btn:hover .icon path', 'fill: ' + fullLayout.modebar.activecolor);
Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId + ' .modebar-btn.active .icon path', 'fill: ' + fullLayout.modebar.activecolor);

// if buttons or logo have changed, redraw modebar interior
var needsNewButtons = !this.hasButtons(buttons);
var needsNewLogo = (this.hasLogo !== context.displaylogo);
Expand All @@ -65,7 +81,12 @@ proto.update = function(graphInfo, buttons) {
this.updateButtons(buttons);

if(context.displaylogo) {
this.element.appendChild(this.getLogo());
if(fullLayout.modebar.orientation === 'v') {
this.element.prepend(this.getLogo());
} else {
this.element.appendChild(this.getLogo());
}

this.hasLogo = true;
}
}
Expand Down Expand Up @@ -173,31 +194,42 @@ proto.createButton = function(config) {
* @Param {object} thisIcon
* @Param {number} thisIcon.width
* @Param {string} thisIcon.path
* @Param {string} thisIcon.color
* @Return {HTMLelement}
*/
proto.createIcon = function(thisIcon) {
var iconHeight = isNumeric(thisIcon.height) ?
Number(thisIcon.height) :
thisIcon.ascent - thisIcon.descent,
svgNS = 'http://www.w3.org/2000/svg',
icon = document.createElementNS(svgNS, 'svg'),
path = document.createElementNS(svgNS, 'path');
icon;

icon.setAttribute('height', '1em');
icon.setAttribute('width', (thisIcon.width / iconHeight) + 'em');
icon.setAttribute('viewBox', [0, 0, thisIcon.width, iconHeight].join(' '));
if(thisIcon.path) {
icon = document.createElementNS(svgNS, 'svg');
icon.setAttribute('viewBox', [0, 0, thisIcon.width, iconHeight].join(' '));
icon.setAttribute('class', 'icon');

var path = document.createElementNS(svgNS, 'path');
path.setAttribute('d', thisIcon.path);

path.setAttribute('d', thisIcon.path);
if(thisIcon.transform) {
path.setAttribute('transform', thisIcon.transform);
}
else if(thisIcon.ascent !== undefined) {
// Legacy icon transform calculation
path.setAttribute('transform', 'matrix(1 0 0 -1 0 ' + thisIcon.ascent + ')');
}

if(thisIcon.transform) {
path.setAttribute('transform', thisIcon.transform);
icon.appendChild(path);
}
else if(thisIcon.ascent !== undefined) {
// Legacy icon transform calculation
path.setAttribute('transform', 'matrix(1 0 0 -1 0 ' + thisIcon.ascent + ')');

if(thisIcon.svg) {
var svgDoc = Parser.parseFromString(thisIcon.svg, 'application/xml');
icon = svgDoc.childNodes[0];
}

icon.appendChild(path);
icon.setAttribute('height', '1em');
icon.setAttribute('width', '1em');

return icon;
};
Expand Down Expand Up @@ -272,7 +304,7 @@ proto.getLogo = function() {
a.setAttribute('data-title', Lib._(this.graphInfo, 'Produced with Plotly'));
a.className = 'modebar-btn plotlyjsicon modebar-btn--logo';

a.appendChild(this.createIcon(Icons.plotlylogo));
a.appendChild(this.createIcon(Icons.newplotlylogo));

group.appendChild(a);
return group;
Expand All @@ -288,6 +320,7 @@ proto.removeAllButtons = function() {

proto.destroy = function() {
Lib.removeElement(this.container.querySelector('.modebar'));
Lib.deleteRelatedStyleRule(this._uid);
};

function createModeBar(gd, buttons) {
Expand Down
28 changes: 13 additions & 15 deletions src/css/_modebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
top: 2px;
right: 2px;
z-index: 1001;
background: rgba(255,255,255,0.7);
}

.modebar--hover {
Expand All @@ -23,17 +22,13 @@
position: relative;
vertical-align: middle;
white-space: nowrap;

&:first-child {
margin-left: 0px;
}
}


.modebar-btn {
position: relative;
font-size: 16px;
padding: 3px 4px;
height: 22px;
/* display: inline-block; including this breaks 3d interaction in .embed mode. Chrome bug? */
cursor: pointer;
line-height: normal;
Expand All @@ -44,19 +39,22 @@
top: 2px;
}

path {
fill: rgba(0,31,95,0.3);
}
&.modebar-btn--logo {

&.active path, &:hover path {
fill: rgba(0,22,72,0.5);
}
}

&.modebar-btn--logo {
padding: 3px 1px;
.modebar.vertical {
top: -1px;
.modebar-group {
display: block;
float: none;
margin-left: 0px;
margin-bottom: 8px;

path {
fill: $color-brand-primary !important;
.modebar-btn {
display: block;
text-align: center;
}
}
}
17 changes: 16 additions & 1 deletion src/css/_tooltip.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ $successColor: hsl(121, 32%, 40%) !default;
opacity: 1;
}

// Arrow
// Top arrow
&:before {
content: '';
position: absolute;
Expand All @@ -78,3 +78,18 @@ $successColor: hsl(121, 32%, 40%) !default;
border-radius: 2px;
}
}

.vertical [data-title] {
&:before, &:after {
top: 0%;
right: 200%;
}

// Right arrow
&:before {
border: $arrowBorderWidth solid transparent;
border-left-color: $defaultColor;
margin-top: $verticalPadding;
margin-right: -1 * ($arrowOffsetX + 2 * $arrowBorderWidth);
}
}
24 changes: 22 additions & 2 deletions src/fonts/ploticon/ploticon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 23 additions & 4 deletions src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -679,14 +679,24 @@ lib.removeElement = function(el) {
* by all calls to this function
*/
lib.addStyleRule = function(selector, styleString) {
if(!lib.styleSheet) {
var style = document.createElement('style');
lib.addRelatedStyleRule('global', selector, styleString);
};

/**
* for dynamically adding style rules
* to a stylesheet uniquely identified by a uid
*/
lib.addRelatedStyleRule = function(uid, selector, styleString) {
var id = 'plotly.js-style-' + uid,
style = document.getElementById(id);
if(!style) {
style = document.createElement('style');
style.setAttribute('id', id);
// WebKit hack :(
style.appendChild(document.createTextNode(''));
document.head.appendChild(style);
lib.styleSheet = style.sheet;
}
var styleSheet = lib.styleSheet;
var styleSheet = style.sheet;

if(styleSheet.insertRule) {
styleSheet.insertRule(selector + '{' + styleString + '}', 0);
Expand All @@ -697,6 +707,15 @@ lib.addStyleRule = function(selector, styleString) {
else lib.warn('addStyleRule failed');
};

/**
* to remove from the page a stylesheet identified by a given uid
*/
lib.deleteRelatedStyleRule = function(uid) {
var id = 'plotly.js-style-' + uid,
style = document.getElementById(id);
if(style) style.remove();
};

lib.isIE = function() {
return typeof window.navigator.msSaveBlob !== 'undefined';
};
Expand Down
29 changes: 29 additions & 0 deletions src/plots/layout_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,5 +224,34 @@ module.exports = {
'or a logo image, for example. To omit one of these items on the plot,',
'make an item with matching `templateitemname` and `visible: false`.'
].join(' ')
},
modebar: {
orientation: {
valType: 'enumerated',
values: ['v', 'h'],
dflt: 'h',
role: 'info',
editType: 'modebar',
description: 'Sets the orientation of the modebar.'
},
bgcolor: {
valType: 'color',
role: 'style',
editType: 'modebar',
description: 'Sets the background color of the modebar.'
},
color: {
valType: 'color',
role: 'style',
editType: 'modebar',
description: 'Sets the color of the icons in the modebar.'
},
activecolor: {
valType: 'color',
role: 'style',
editType: 'modebar',
description: 'Sets the color of the active or hovered on icons in the modebar.'
},
editType: 'modebar'
}
};
6 changes: 6 additions & 0 deletions src/plots/plots.js
Original file line number Diff line number Diff line change
Expand Up @@ -1337,6 +1337,12 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {

coerce('datarevision');

coerce('modebar.orientation');
coerce('modebar.bgcolor', Color.addOpacity(layoutOut.paper_bgcolor, 0.5));
var modebarDefaultColor = Color.contrast(Color.rgb(layoutOut.modebar.bgcolor));
coerce('modebar.color', Color.addOpacity(modebarDefaultColor, 0.3));
coerce('modebar.activecolor', Color.addOpacity(modebarDefaultColor, 0.7));

Registry.getComponentMethod(
'calendars',
'handleDefaults'
Expand Down
Loading

0 comments on commit 88d48c5

Please sign in to comment.