Created
December 29, 2016 21:51
-
-
Save jonathaneunice/f75a4f2644c0101b0f9159b468c7fbce to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* CSS imperative declarations. | |
* E.g. cssi('div#one.two.three') | |
* yields { element: 'div', | |
* id: 'one', | |
* class: 'two three', | |
* } | |
* Classes are not split out into an array | |
* because that replicates information (anti DRY) | |
* and not especially compatible with D3 .attrs | |
*/ | |
function cssi (s) { | |
s = s.trim(); | |
var eltM = s.match(/^\w+/); | |
var idM = s.match(/#(\w+)/); | |
var classM = s.match(/\.(\w+)/g); | |
var attrM = s.match(/\[[^\]]*\]/g); | |
res = {}; | |
if (eltM && eltM.length) res.element = eltM[0]; | |
if (idM && idM.length) res.id = idM[1]; | |
if (classM && classM.length) | |
res.class = classM.map(s => s.slice(1)).join(' '); | |
if (attrM && attrM.length) { | |
attrM.forEach(a => { | |
var insides = a.slice(1,-1); // take off [ and ] | |
insides.split(';').forEach(assign => { | |
assign = assign.trim(); | |
var [__, left, right] = assign.match(/(.*?)\s*[=:]\s*(.*)/); | |
var rightFC = right.charAt(0); | |
if ((rightFC === '"') || (rightFC === "'")) { | |
right = right.slice(1, -1); // take off quotes | |
} | |
res[left] = right; | |
}); | |
}); | |
} | |
return res; | |
} | |
// does not ahndle typical .attr(name, value) case | |
// but does handle function => map, string => map | |
// and plain map | |
function attrx(map) { | |
var selection = this; | |
var tos = typeof map; | |
console.log('tos', tos) | |
if (tos === 'function') | |
return selection.each(function() { | |
var x = map.apply(this, arguments), s = select(this); | |
for (var name in x) s.attr(name, x[name]); | |
}); | |
if (tos === 'string') | |
map = cssi(map); | |
for (var name in map) selection.attr(name, map[name]); | |
return selection; | |
} | |
function attrx(map) { | |
var selection = this; | |
var mapType = typeof map; | |
if (mapType === 'function') | |
return selection.each(function() { | |
var x = map.apply(this, arguments), s = select(this); | |
for (var name in x) s.attr(name, x[name]); | |
}); | |
if (mapType === 'string') | |
map = cssi(map); | |
for (var name in map) selection.attr(name, map[name]); | |
return selection; | |
} | |
// simpler take on styles than attributes | |
// no functions supported yet; string or map asumed | |
function stylex(map) { | |
var selection = this; | |
var mapType = typeof map; | |
if (mapType === 'string') | |
map = cssi(map); | |
for (var name in map) selection.style(name, map[name]); | |
return selection; | |
} | |
function appendx(selector) { | |
var self = this; | |
var toAdd = cssi(selector); | |
self = self.append(toAdd.element); | |
for (var key in toAdd) { | |
if (key === 'element') continue; | |
self.attr(key, toAdd[key]); | |
} | |
return self; | |
} | |
// FIXME: need either more rigorous parser or to disallow colon on attrx and appendx | |
// link into D3 selection functions | |
d3.selection.prototype.appendx = appendx; | |
d3.selection.prototype.attrx = attrx; | |
d3.selection.prototype.stylex = stylex; | |
// for v3 need to extend the enter selection too | |
if (d3.version.charAt(0) === '3') { | |
d3.selection.enter.prototype.appendx = appendx; | |
d3.selection.enter.prototype.attrx = attrx; | |
d3.selection.enter.prototype.stylex = stylex; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment