in src/carousel.js [20:414]
function carousel (selection) {
selection.each(function (data){
this_carousel = d3.select(this);
this_carousel.interrupt();
svg_height = d3.select('#carousel_svg').style('height');
svg_height = +svg_height.substr(0,svg_height.indexOf('px'));
svg_width = d3.select('#carousel_svg').style('width');
svg_width = +svg_width.substr(0,svg_width.indexOf('px'));
var center_y = svg_height * 0.5;
var focus_height = (svg_height <= svg_width) ? (svg_width / 7 - 6) : (svg_height / 7 - 6); // same as button height
var clutch = this_carousel.selectAll('.carousel_clutch')
.data([null]);
var clutch_enter = clutch.enter()
.append('g')
.style('display','none')
.attr('class','carousel_clutch');
var defs = clutch_enter.append('defs');
var grad1 = defs.append('linearGradient')
.attr('id','grad1')
.attr('x1','0%')
.attr('x2','0%')
.attr('y1','0%')
.attr('y2','100%');
grad1.append('stop')
.attr('offset','0%')
.style('stop-color','#222')
.style('stop-opacity',1);
grad1.append('stop')
.attr('offset','100%')
.style('stop-color','#333')
.style('stop-opacity',1);
var grad2 = defs.append('linearGradient')
.attr('id','grad2')
.attr('x1','0%')
.attr('x2','0%')
.attr('y1','0%')
.attr('y2','100%');
grad2.append('stop')
.attr('offset','0%')
.style('stop-color','#333')
.style('stop-opacity',1);
grad2.append('stop')
.attr('offset','100%')
.style('stop-color','#222')
.style('stop-opacity',1);
clutch_enter.append('rect')
.attr('class','clutch_enabled')
.attr('rx',5)
.attr('ry',5)
.style('margin', '2px')
.style('fill','url(#grad1)')
.on('touchstart',clutchDown)
.on('touchend',clutchEnd);
clutch_enter.append('text')
.text('⚲')
.attr('id','clutch_search')
.attr('class','clutch_text')
.attr('text-anchor', "middle")
.attr('alignment-baseline','middle')
.on('touchstart',clutchDown)
.on('touchend',clutchEnd);
clutch_enter.append('text')
.text('↑')
.attr('class','clutch_text')
.attr('dy','-1em')
.attr('text-anchor', "middle")
.attr('alignment-baseline','middle')
.on('touchstart',clutchDown)
.on('touchend',clutchEnd);
clutch_enter.append('text')
.text('↓')
.attr('class','clutch_text')
.attr('dy','1em')
.attr('text-anchor', "middle")
.attr('alignment-baseline','middle')
.on('touchstart',clutchDown)
.on('touchend',clutchEnd);
function clutchDown() {
d3.event.preventDefault();
d3.event.stopPropagation();
carousel_touching = true;
touching = false;
carousel_items.call(position);
d3.select('.clutch_enabled')
.attr('class','clutch_touch')
.style('fill','url(#grad2)');
d3.select('.carousel_clutch').selectAll('text')
.style('fill','gold');
d3.selectAll('.carousel_item').style('display','inline');
}
function clutchEnd() {
d3.event.preventDefault();
d3.event.stopPropagation();
carousel_touching = false;
touching = true;
d3.select('.clutch_touch')
.attr('class','clutch_enabled')
.style('fill','url(#grad1)');
d3.select('.carousel_clutch').selectAll('text')
.style('fill','#ccc');
// d3.selectAll('.carousel_item').style('display','none');
}
var clutch_update = clutch;
clutch_update.select('rect')
.attr('width',focus_height - 4)
.attr('height',svg_height - 4)
.attr('x',svg_width-focus_height - 2)
.attr('y',2);
clutch_update.selectAll('text')
.attr('transform','translate('+ (svg_width - 2 - 0.5 * focus_height) + ',' + (svg_height / 2) +')');
clutch_update.select('#clutch_search')
.attr('transform','translate('+ (svg_width - 2 - 0.5 * focus_height) + ',' + (svg_height / 2) +')rotate(-45)');
clutch.exit()
.remove();
var highlight_points = chart_instance.highlight_points();
focus_element = highlight_points[carousel_focus];
function pinDown(item) {
d3.event.preventDefault();
d3.event.stopPropagation();
carousel_touching = true;
touching = false;
console.log(item);
if (chart_instance.bubbleset_points().indexOf(item) == -1) {
chart_instance.bubbleset_points().push(item);
d3.select('#carousel_item_' + item).select('rect')
.style('stroke','gold');
// var outside_ind = chart_instance.outside_points().indexOf(item);
// chart_instance.outside_points().splice(outside_ind,1);
chart_g.call(chart_instance);
}
else {
var bubble_ind = chart_instance.bubbleset_points().indexOf(item);
chart_instance.bubbleset_points().splice(bubble_ind,1);
d3.select('#carousel_item_' + item).select('rect').style('stroke','#fff');
chart_g.call(chart_instance);
var updated_highlight_points = chart_instance.highlight_points();
carousel_g.datum(updated_highlight_points);
carousel_instance.carousel_focus(Math.floor((updated_highlight_points.length - 1) / 2));
carousel_g.call(carousel_instance);
setTimeout(function(){
carousel_g.call(carousel_instance);
}, 275);
var bubbleset_points = chart_instance.bubbleset_points();
if (bubbleset_points.length == 0 && updated_highlight_points.length == 0) {
d3.selectAll('.carousel_item').style('display','none');
d3.selectAll('.carousel_clutch').style('display','none');
}
}
}
function pinEnd() {
d3.event.preventDefault();
d3.event.stopPropagation();
carousel_touching = false;
touching = false;
d3.selectAll('.carousel_item').style('display','none');
}
function position(item) {
var item_transition = item.transition()
.ease(d3.easeLinear)
.duration(250);
item_transition.attr('transform',function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
var dir_from_focus = Math.sign(i - carousel_focus);
var x_translate = (svg_width * 0.5 + 0.5 * ((focus_height * 2) - 4)) - ((focus_height * 2) - 4) * (1 - (dist_from_focus * 0.05)) - 2;
var y_translate = 0;
if (dist_from_focus == 0) {
y_translate = center_y - (focus_height * 0.5) - 2;
}
else {
var offset = 0;
var j = (dir_from_focus == -1) ? 1 : 2;
var buffer = (dir_from_focus == -1) ? 6 : 10;
for (j; j <= dist_from_focus; j++){
offset = offset + buffer + d3.max([0,(focus_height - 4) * (1 - (j * 0.1))]);
}
if (dir_from_focus == -1) {
y_translate = center_y - ((focus_height - 4) * 0.5) - 4 - offset;
}
else {
y_translate = center_y + ((focus_height - 4) * 0.5) + 2 + offset;
}
}
return 'translate('+ x_translate + ',' + y_translate + ')';
});
item_transition.select('.carousel_rect')
.attr('x',0)
.attr('y',0)
.attr('height', function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
if (dist_from_focus == 0) {
return (focus_height - 4);
}
else {
return d3.max([0,(focus_height - 4) * (1 - (dist_from_focus * 0.1))]);
}
})
.attr('width', function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
return d3.max([0,((focus_height * 2) - 4) * (1 - (dist_from_focus * 0.1))]);
})
.style('opacity',function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
return 1 * (1 - (dist_from_focus * 0.25));
})
.attr('stroke', '#fff');
item_transition.select('.carousel_text')
.attr('y', function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
if (dist_from_focus == 0) {
return focus_height / 2;
}
else {
return d3.max([0,(focus_height - 4) * (1 - (dist_from_focus * 0.1))]) / 2;
}
})
.attr('x', function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
return d3.max([0,((focus_height * 2) - 4) * (1 - (dist_from_focus * 0.1))]) / 2;
})
.style('font-size',function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
return 0.7 * (1 - (dist_from_focus * 0.1)) + 'em';
})
.style('opacity',function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
return 0.75 * (1 - (dist_from_focus * 0.25));
});
}
//carousel item enter
var carousel_items = this_carousel.selectAll('.carousel_item')
.data(data, function(d){
return d;
});
var carousel_item_enter = carousel_items.enter()
.append('g')
.attr('class','carousel_item')
.attr('id',function(d){
return 'carousel_item_' + d;
})
.style('display','none')
.attr('transform',function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
var dir_from_focus = Math.sign(i - carousel_focus);
var x_translate = (svg_width * 0.5 + 0.5 * ((focus_height * 2) - 4)) - ((focus_height * 2) - 4) * (1 - (dist_from_focus * 0.05)) - 2;
var y_translate = 0;
if (dist_from_focus == 0) {
y_translate = center_y - (focus_height * 0.5) - 2;
}
else {
var offset = 0;
var j = (dir_from_focus == -1) ? 1 : 2;
var buffer = (dir_from_focus == -1) ? 6 : 10;
for (j; j <= dist_from_focus; j++){
offset = offset + buffer + d3.max([0,(focus_height - 4) * (1 - (j * 0.1))]);
}
if (dir_from_focus == -1) {
y_translate = center_y - ((focus_height - 4) * 0.5) - 4 - offset;
}
else {
y_translate = center_y + ((focus_height - 4) * 0.5) + 2 + offset;
}
}
return 'translate('+ x_translate + ',' + y_translate + ')';
});
carousel_item_enter.append('rect')
.attr('class', 'carousel_rect')
.attr('rx',5)
.attr('ry',5)
.attr('id',function(d){
return d + '_bttn';
})
.attr('stroke', '#fff')
.style('stroke-width','2px')
.style('fill',function(d){
return d3.select('.circle_mark_' + d).style('fill');
})
.attr('x',0)
.attr('y',0)
.attr('height', function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
if (dist_from_focus == 0) {
return (focus_height - 4);
}
else {
return d3.max([0,(focus_height - 4) * (1 - (dist_from_focus * 0.1))]);
}
})
.attr('width', function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
return d3.max([0,((focus_height * 2) - 4) * (1 - (dist_from_focus * 0.1))]);
})
.style('opacity',function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
return 0.75 * (1 - (dist_from_focus * 0.25));
})
.on('touchstart', function(d){
pinDown(d);
})
.on('touchend', pinEnd);
carousel_item_enter.append('text')
.style('font-size','0em')
.attr('class', 'carousel_text')
.attr('text-anchor', "middle")
.attr('alignment-baseline','middle')
.text(function(d){
return d;
})
.attr('y', function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
if (dist_from_focus == 0) {
return focus_height / 2;
}
else {
return d3.max([0,(focus_height - 4) * (1 - (dist_from_focus * 0.1))]) / 2;
}
})
.attr('x', function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
return d3.max([0,((focus_height * 2) - 4) * (1 - (dist_from_focus * 0.1))]) / 2;
})
.style('font-size',function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
return 0.7 * (1 - (dist_from_focus * 0.1)) + 'em';
})
.style('opacity',function(d,i){
var dist_from_focus = Math.abs(i - carousel_focus);
return 0.75 * (1 - (dist_from_focus * 0.25));
})
.on('touchstart', function(d){
pinDown(d);
})
.on('touchend', pinEnd);
//carousel item exit
var carousel_items_exit = carousel_items.exit()
.transition()
.ease(d3.easeLinear)
.duration(250)
.remove();
carousel_items_exit.attr('transform', 'translate('+ svg_width + ',0)');
carousel_items_exit.select('.carousel_text')
.style('font-size','0em');
//carousel item update
carousel_items.call(position);
});
}