Angular directive code to help resize/redraw non-responsive elements (like D3 charts) in a bootstrap responsive design when the window moves across bootstrap boundaries.
(I edited my boostrap to create an extra size for some 7" tablets and landscape phones @ 600px)
What do you think? Good? Bad? Ugly? How could it be better? What other options exist?
Credit to tagtree for the Rickshaw directive help: http://tagtree.tv/d3-with-rickshaw-and-angular
(function () {
'use strict';
angular.module('yourModule').directive('yourDirectiveName', yourDirectiveName);
function yourDirectiveName($window) {
var directive = {
link: link,
restrict: 'AE',
scope: {
data: '=',
renderer: '='
}
};
return directive;
function link(scope, element, attributes) {
var w = angular.element($window);
// Created a function that can watch the
// width of the window so we know when
// boostrap divs will trigger resizing
scope.getWindowWidth = function () {
return w.width();
}
// Watch for the size of the window changing
// then switch according to the bootstrap
// boundaries listed below.
scope.$watch(scope.getWindowWidth, function (newWidth, oldWidth) {
if (newWidth != oldWidth) {
switch (true) {
// xs/ss boundary (My custom boundary)
case (newWidth < 600): // Resize every time
case (newWidth >= 600 && oldWidth < 600):
// ss/sm boundary
case (oldWidth >= 768 && newWidth < 768):
case (newWidth >= 768 && oldWidth < 768):
// sm/md boundary
case (oldWidth >= 992 && newWidth < 992):
case (newWidth >= 992 && oldWidth < 992):
// md/lg boundary
case (oldWidth >= 1200 && newWidth < 1200):
case (newWidth >= 1200 && oldWidth < 1200):
scope.renderChart(element[0], attributes.color);
break;
default:
break;
}
}
});
// Capture the window event so we can capture
// the bootstrap media query boundaries
w.bind('resize', function () {
scope.$apply();
});
// Watch for the data or chart type changing
scope.$watchCollection('[data, renderer]', function (newValue, oldValue) {
if (!newValue[0]) {
return;
}
scope.renderChart(element[0], attributes.color);
});
// Render the D3 chart through Rickshaw
scope.renderChart = function (element, color) {
element.innerHTML = '';
var graph = new Rickshaw.Graph({
element: element,
series: [{ data: scope.data, color: color }],
renderer: scope.renderer
});
graph.render();
};
}
}
})();
Interesting technique. Thanks!