Skip to content

Commit

Permalink
feat(ui): truncate long layer names + tooltip
Browse files Browse the repository at this point in the history
  • Loading branch information
AleksueiR committed Mar 3, 2017
1 parent 6ee95de commit f3e9e8a
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 12 deletions.
20 changes: 19 additions & 1 deletion src/app/common/graphics.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
svgToCanvas,
createSvg,
createCanvas,
mergeCanvases
mergeCanvases,
getTextWidth
};

return service;
Expand Down Expand Up @@ -110,5 +111,22 @@

return baseCanvas;
}

/**
* Returns width of the supplied text string.
* @function getTextWidth
* @param {Object} canvas cached canvas node
* @param {String} text string of text to measure
* @param {String} font text font and size https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font
* @return {Number} width of the text
*/
function getTextWidth(canvas, text, font) {
const context = canvas.getContext('2d');
context.font = font;

// measure text width on the canvas: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/measureText
const metrics = context.measureText(text);
return metrics.width;
}
}
})();
82 changes: 81 additions & 1 deletion src/app/ui/common/truncate.directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
*/
angular
.module('app.ui.common')
.directive('rvTruncate', rvTruncate);
.directive('rvTruncate', rvTruncate)
.directive('rvTruncateTitle', rvTruncateTitle);

/**
* `rvTruncate` directive body.
Expand Down Expand Up @@ -68,4 +69,83 @@
});
}
}

/**
* `rvTruncateTitle` truncates a given string be taking the middle part of the string out leaving the beginning and end intact.
*
* @function rvTruncateTitle
* @return {object} directive body
*/
function rvTruncateTitle(graphicsService) {
const directive = {
restrict: 'A',
scope: {
rvTruncateTitle: '='
},
link,
controller: () => {},
controllerAs: 'self',
bindToController: true
};

const canvas = document.createElement('canvas');

return directive;

function link(scope, el, attr) {
const self = scope.self;

let string = '';

scope.$watch('self.rvTruncateTitle', newString => {
if (newString) { string = newString; }
update();
});

scope.$watch(() => el.width(), () => update());

el.addClass('rv-truncate-title');

/**
* Updates the split string DOM node.
*
* @function update
* @private
*/
function update() {
const [left, right] = splitString(string, el.width() - 10); // 10 accounts for letter spacing

el.empty().append(`
<span class="rv-truncate-title-left">${left}</span>
<span calss="rv-truncate-title-right">${right}</span>
`);
}

/**
* Splits the given string into two parts:
* left string can be arbitrary long and it will be truncated with an ellipsis using CSS but using flex-shrink;
* right string must be smaller than the width of the container; this part will not be shrinkable;
*
* @function splitString
* @private
* @param {String} string title text
* @param {Number} widthToFit container width that the title text needs to fit in
* @return {Array} [leftString, rightString] parts of the original string
*/
function splitString(string, widthToFit) {
const stringWidth = graphicsService.getTextWidth(canvas, string, 'normal 16px Roboto');

if (stringWidth < widthToFit) {
return [string, ''];
}

const desiredStringLength = Math.floor(string.length * widthToFit / stringWidth * 0.3);

return [
string.substring(0, string.length - desiredStringLength),
string.substring(string.length - desiredStringLength, string.length)
];
}
}
}
})();
4 changes: 2 additions & 2 deletions src/app/ui/loader/loader-service.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@
</div-->
</md-input-container>

<img
<!--img
src="https://d13yacurqjgara.cloudfront.net/users/355650/screenshots/2181500/unicorn_drib_v2.gif"
style="width: 100%;"
alt=""
ng-switch-when="unicorn"/>
ng-switch-when="unicorn"/-->

<p class="md-caption">{{ 'stepper.unresponsive' | translate }}</p>

Expand Down
8 changes: 4 additions & 4 deletions src/app/ui/toc/templates/group-entry.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
ng-if="!self.isReorder"
class="rv-group-body-button rv-button-square"
ng-click="self.defaultAction(self.entry)"
rv-help="group-toggle"></md-button>
rv-help="group-toggle">
<md-tooltip md-delay="700" md-direction="right">{{ self.entry.name }}</md-tooltip>
</md-button>

<div class="rv-icon-24 rv-group-toggle-icon">
<md-icon
Expand All @@ -11,9 +13,7 @@
md-svg-src="hardware:keyboard_arrow_down"></md-icon>
</div>

<span class="rv-group-name">
{{ self.entry.name }}
</span>
<span class="rv-group-name" rv-truncate-title="self.entry.name"></span>

<div class="rv-toc-entry-controls" ng-if="self.isReorder">
<rv-toc-entry-control rv-drag-handle option="reorder"></rv-toc-entry-control>
Expand Down
10 changes: 7 additions & 3 deletions src/app/ui/toc/templates/layer-entry.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@
ng-if="self.entry.options.data.enabled"
ng-click="self.defaultAction(self.entry)">
<!-- TODO: add aria attribues on the button to provide context on what it does; also mute the actual layer name below, so a screen reader wouldn't pronounce it twice-->

<md-tooltip md-delay="700" md-direction="right">{{ self.entry.name }}</md-tooltip>
</md-button>

<div
class="rv-layer-body-button rv-button-square"
ng-mouseover="self.entry.wiggleSymbology(true)"
ng-mouseleave="self.entry.wiggleSymbology(false)"
ng-if="!self.entry.options.data">
ng-if="!self.entry.options.data || !self.entry.options.data.enabled">

<md-tooltip md-delay="700" md-direction="right">{{ self.entry.name }}</md-tooltip>
</div>

<rv-toc-entry-symbology entry="self.entry" type="self.entry.layerType" symbology="self.entry.symbology"></rv-toc-entry-symbology>

<div class="rv-layer-item-content">
<div class="rv-layer-item-name">
{{ self.entry.name }}

<div class="rv-layer-item-name" rv-truncate-title="self.entry.name">
</div>

<div class="rv-toc-entry-flags">
Expand Down
2 changes: 1 addition & 1 deletion src/content/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
@import "_shame.scss";
}

@import "vendor/_special.scss";
@import "vendor/_special.scss";
2 changes: 2 additions & 0 deletions src/content/styles/modules/_all.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
@import "_side-nav.scss";
@import "_tooltip.scss";
@import "_geosearch.scss";
@import "_truncate.scss";

@include core;
@include loading;
Expand Down Expand Up @@ -61,3 +62,4 @@
@include export;
@include side-nav;
@include tooltip;
@include truncate;
17 changes: 17 additions & 0 deletions src/content/styles/modules/_truncate.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@mixin truncate {
.rv-truncate-title {
display: flex;

&-left {
flex-shrink: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

&-right {
flex-shrink: 0;
text-overflow: clip !important;
}
}
}

0 comments on commit f3e9e8a

Please sign in to comment.