mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-23 08:39:56 +02:00
Begin d3 v4 update
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
export function bindOnce(target, type, listener, capture) {
|
||||
var typeOnce = type + ".once";
|
||||
function one() {
|
||||
target.on(typeOnce, null);
|
||||
listener.apply(this, arguments);
|
||||
}
|
||||
target.on(typeOnce, one, capture);
|
||||
return this;
|
||||
};
|
||||
@@ -0,0 +1,131 @@
|
||||
import { getDimensions } from './dimensions';
|
||||
import { rebind } from '../../modules/util/rebind';
|
||||
import * as d3 from 'd3';
|
||||
|
||||
// Tooltips and svg mask used to highlight certain features
|
||||
export function d3curtain() {
|
||||
|
||||
var event = d3.dispatch(),
|
||||
surface,
|
||||
tooltip,
|
||||
darkness;
|
||||
|
||||
function curtain(selection) {
|
||||
|
||||
surface = selection.append('svg')
|
||||
.attr('id', 'curtain')
|
||||
.style({
|
||||
'z-index': 1000,
|
||||
'pointer-events': 'none',
|
||||
'position': 'absolute',
|
||||
'top': 0,
|
||||
'left': 0
|
||||
});
|
||||
|
||||
darkness = surface.append('path')
|
||||
.attr('x', 0)
|
||||
.attr('y', 0)
|
||||
.attr('class', 'curtain-darkness')
|
||||
|
||||
d3.select(window).on('resize.curtain', resize);
|
||||
|
||||
tooltip = selection.append('div')
|
||||
.attr('class', 'tooltip')
|
||||
.style('z-index', 1002);
|
||||
|
||||
tooltip.append('div').attr('class', 'tooltip-arrow');
|
||||
tooltip.append('div').attr('class', 'tooltip-inner');
|
||||
|
||||
resize();
|
||||
|
||||
function resize() {
|
||||
surface
|
||||
.attr('width', window.innerWidth)
|
||||
.attr('height', window.innerHeight);
|
||||
curtain.cut(darkness.datum());
|
||||
}
|
||||
}
|
||||
|
||||
curtain.reveal = function(box, text, tooltipclass, duration) {
|
||||
if (typeof box === 'string') box = d3.select(box).node();
|
||||
if (box.getBoundingClientRect) box = box.getBoundingClientRect();
|
||||
|
||||
curtain.cut(box, duration);
|
||||
|
||||
if (text) {
|
||||
// pseudo markdown bold text hack
|
||||
var parts = text.split('**');
|
||||
var html = parts[0] ? '<span>' + parts[0] + '</span>' : '';
|
||||
if (parts[1]) html += '<span class="bold">' + parts[1] + '</span>';
|
||||
|
||||
var dimensions = getDimensions(tooltip.classed('in', true)
|
||||
.select('.tooltip-inner')
|
||||
.html(html));
|
||||
|
||||
var pos;
|
||||
|
||||
var w = window.innerWidth,
|
||||
h = window.innerHeight;
|
||||
|
||||
if (box.top + box.height < Math.min(100, box.width + box.left)) {
|
||||
side = 'bottom';
|
||||
pos = [box.left + box.width / 2 - dimensions[0]/ 2, box.top + box.height];
|
||||
|
||||
} else if (box.left + box.width + 300 < window.innerWidth) {
|
||||
side = 'right';
|
||||
pos = [box.left + box.width, box.top + box.height / 2 - dimensions[1] / 2];
|
||||
|
||||
} else if (box.left > 300) {
|
||||
side = 'left';
|
||||
pos = [box.left - 200, box.top + box.height / 2 - dimensions[1] / 2];
|
||||
} else {
|
||||
side = 'bottom';
|
||||
pos = [box.left, box.top + box.height];
|
||||
}
|
||||
|
||||
pos = [
|
||||
Math.min(Math.max(10, pos[0]), w - dimensions[0] - 10),
|
||||
Math.min(Math.max(10, pos[1]), h - dimensions[1] - 10)
|
||||
];
|
||||
|
||||
|
||||
if (duration !== 0 || !tooltip.classed(side)) tooltip.call(iD.ui.Toggle(true));
|
||||
|
||||
tooltip
|
||||
.style('top', pos[1] + 'px')
|
||||
.style('left', pos[0] + 'px')
|
||||
.attr('class', 'curtain-tooltip tooltip in ' + side + ' ' + tooltipclass)
|
||||
.select('.tooltip-inner')
|
||||
.html(html);
|
||||
|
||||
} else {
|
||||
tooltip.call(iD.ui.Toggle(false));
|
||||
}
|
||||
};
|
||||
|
||||
curtain.cut = function(datum, duration) {
|
||||
darkness.datum(datum);
|
||||
|
||||
(duration === 0 ? darkness : darkness.transition().duration(duration || 600))
|
||||
.attr('d', function(d) {
|
||||
var string = "M 0,0 L 0," + window.innerHeight + " L " +
|
||||
window.innerWidth + "," + window.innerHeight + "L" +
|
||||
window.innerWidth + ",0 Z";
|
||||
|
||||
if (!d) return string;
|
||||
return string + 'M' +
|
||||
d.left + ',' + d.top + 'L' +
|
||||
d.left + ',' + (d.top + d.height) + 'L' +
|
||||
(d.left + d.width) + ',' + (d.top + d.height) + 'L' +
|
||||
(d.left + d.width) + ',' + (d.top) + 'Z';
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
curtain.remove = function() {
|
||||
surface.remove();
|
||||
tooltip.remove();
|
||||
};
|
||||
|
||||
return rebind(curtain, event, 'on');
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
function refresh(target, node) {
|
||||
var cr = node.getBoundingClientRect();
|
||||
var prop = [cr.width, cr.height];
|
||||
target.property('__dimensions__', prop);
|
||||
return prop;
|
||||
}
|
||||
|
||||
export function getDimensions (target) {
|
||||
if (!target) return [0, 0];
|
||||
var node = target.node();
|
||||
return target.property('__dimensions__') || refresh(target, node);
|
||||
}
|
||||
|
||||
export function setDimensions (target, dimensions) {
|
||||
var node = target.node();
|
||||
if (dimensions === null) {
|
||||
if (!node) return [0,0];
|
||||
return refresh(target, node);
|
||||
}
|
||||
return target
|
||||
.property('__dimensions__', [dimensions[0], dimensions[1]])
|
||||
.attr('width', dimensions[0])
|
||||
.attr('height', dimensions[1])
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Like selection.property('value', ...), but avoids no-op value sets,
|
||||
// which can result in layout/repaint thrashing in some situations.
|
||||
export function getSetValue (target, value) {
|
||||
function d3_selection_value(value) {
|
||||
function valueNull() {
|
||||
delete target.value;
|
||||
}
|
||||
|
||||
function valueConstant() {
|
||||
if (target.value !== value) target.value = value;
|
||||
}
|
||||
|
||||
function valueFunction() {
|
||||
var x = value.apply(target, arguments);
|
||||
if (x == null) delete target.value;
|
||||
else if (target.value !== x) target.value = x;
|
||||
}
|
||||
|
||||
return value == null
|
||||
? valueNull : (typeof value === "function"
|
||||
? valueFunction : valueConstant);
|
||||
}
|
||||
|
||||
if (!arguments.length) return target.property('value');
|
||||
return target.each(d3_selection_value(value));
|
||||
}
|
||||
@@ -14,5 +14,6 @@ export { fastMouse } from './util';
|
||||
export { getPrototypeOf } from './util';
|
||||
export { asyncMap } from './util';
|
||||
export { wrap } from './util';
|
||||
export { functor } from './util';
|
||||
export { SessionMutex } from './session_mutex';
|
||||
export { SuggestNames } from './suggest_names';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as d3 from 'd3';
|
||||
var jsonpCache = {};
|
||||
window.jsonpCache = jsonpCache;
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copies a variable number of methods from source to target.
|
||||
export function rebind(target, source) {
|
||||
var i = 1, n = arguments.length, method;
|
||||
while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
|
||||
return target;
|
||||
};
|
||||
|
||||
// Method is assumed to be a standard D3 getter-setter:
|
||||
// If passed with no arguments, gets the value.
|
||||
// If passed with arguments, sets the value and returns the target.
|
||||
function d3_rebind(target, source, method) {
|
||||
return function() {
|
||||
var value = method.apply(source, arguments);
|
||||
return value === source ? target : value;
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import { functor } from './index';
|
||||
import * as d3 from 'd3';
|
||||
export function tooltip() {
|
||||
|
||||
var tooltip = function(selection) {
|
||||
selection.each(setup);
|
||||
},
|
||||
animation = d3.functor(false),
|
||||
html = d3.functor(false),
|
||||
animation = functor(false),
|
||||
html = functor(false),
|
||||
title = function() {
|
||||
var title = this.getAttribute('data-original-title');
|
||||
if (title) {
|
||||
@@ -18,11 +20,11 @@ export function tooltip() {
|
||||
},
|
||||
over = 'mouseenter.tooltip',
|
||||
out = 'mouseleave.tooltip',
|
||||
placement = d3.functor('top');
|
||||
placement = functor('top');
|
||||
|
||||
tooltip.title = function(_) {
|
||||
if (arguments.length) {
|
||||
title = d3.functor(_);
|
||||
title = functor(_);
|
||||
return tooltip;
|
||||
} else {
|
||||
return title;
|
||||
@@ -31,7 +33,7 @@ export function tooltip() {
|
||||
|
||||
tooltip.html = function(_) {
|
||||
if (arguments.length) {
|
||||
html = d3.functor(_);
|
||||
html = functor(_);
|
||||
return tooltip;
|
||||
} else {
|
||||
return html;
|
||||
@@ -40,7 +42,7 @@ export function tooltip() {
|
||||
|
||||
tooltip.placement = function(_) {
|
||||
if (arguments.length) {
|
||||
placement = d3.functor(_);
|
||||
placement = functor(_);
|
||||
return tooltip;
|
||||
} else {
|
||||
return placement;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export function triggerEvent(target, type) {
|
||||
target.each(function() {
|
||||
var evt = document.createEvent('HTMLEvents');
|
||||
evt.initEvent(type, true, true);
|
||||
this.dispatchEvent(evt);
|
||||
});
|
||||
};
|
||||
@@ -1,3 +1,5 @@
|
||||
import { functor } from '../index';
|
||||
import * as d3 from 'd3';
|
||||
import { t } from './locale';
|
||||
import { Detect } from './detect';
|
||||
import { remove as removeDiacritics } from 'diacritics';
|
||||
@@ -193,3 +195,16 @@ export function wrap(index, length) {
|
||||
index += Math.ceil(-index/length)*length;
|
||||
return index % length;
|
||||
}
|
||||
|
||||
/**
|
||||
* a replacement for functor
|
||||
*
|
||||
* @param {*} value any value
|
||||
* @returns {Function} a function that returns that value or the value if it's a function
|
||||
*/
|
||||
export function functor(value) {
|
||||
if (typeof value === 'function') return value;
|
||||
return function() {
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user