(function(){ var schemeSelect = d3.select("#schemeSelect"), margin = 50, width = document.body.clientWidth-margin*2, height = document.body.clientHeight-margin*2, domain = randDomain(), range = { Default: ["#190729", "#191996", "#2F972F", "#FFFF66", "#FF1919"], Warm: ['#FFFFB2', '#FECC5C', '#FD8D3C', '#F03B20', '#BD0026'], Cool: ['#F1EEF6', '#5CFECC', '#74A9CF', '#2B8CBE', '#045A8D'], DkLg: ['#000000', '#444444', '#898989', '#CCCCCC', '#FFFFFF'], LgDk: ['#FFFFFF', '#CCCCCC', '#898989', '#444444', '#000000'], Spectral: ["#D7191C", "#FDAE61", "#FFFFBF", "#ABDDA4", "#2B83BA"], Earth: ['#030371', '#80CDC1', '#F5F5F5', '#DFC27D', '#037103'], Parula: ["#352A87", "#1481D6", "#25B5A9", "#E9B94E", "#F9FB0E"], Jet: ["#00008F", "#0050FF", "#70FF8F", "#FF6000", "#750505"], HSV: ["#FF0000", "#FFD700", "#00FF58", "#0028FF", "#FF00D7"], Accent: ["#7FC97F", "#BEAED4", "#FDC086", "#FFFF99", "#386CB0"], Paired: ["#A6CEE3", "#1F78B4", "#B2DF8A", "#33A02C", "#FB9A99"], Set: ["#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00"] }, selectedRange = range.Default, svg = d3.select("#colourGradient") .append("g") .attr("transform", "translate(" + margin + "," + margin + ")"), defs = svg.append('defs'), linearGradinet = defs.append('linearGradient') .attr("id", "gradient") .attr("x2", "100%"); max = d3.max(domain), cscale = d3.scale.linear() .domain(domain) .range(selectedRange) .interpolate(d3.interpolateRgb), xscale = d3.scale.linear(), xAxis = d3.svg.axis() .scale(xscale) .orient("bottom") .tickValues(domain) .tickSize(20) .tickFormat(function(d) { var percent = Math.round((d / max) * 100); return d + " [" + percent + "%]" }) drag = d3.behavior.drag() .on("dragstart", function(){ d3.event.sourceEvent.stopPropagation(); }) .on("drag", function(d, i){ // ignore first and last ticks if(i === 0 || i === domain.length-1) { return; } // keep within horizontal bounds if(d3.event.x < 0 || d3.event.x > width) { return; } // stop tick reordering var value = Math.round(xscale.invert(d3.event.x)); // -1 and +1 are ok indecies as we ingnored fist and last. if(value <= domain[i-1] || value >= domain[i+1]) { return; } domain[i] = value; d3.select(this).attr("transform", "translate(" + d3.event.x + ",0)"); paint(); // redraw on drag... }) .on("dragend", function(d){}); // returns a random number between min and max inclusive function randRange(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } // creates a random domain function randDomain() { return [0, randRange(5, 10), randRange(12, 20), randRange(22, 35), randRange(38, 50)]; } // init (function() { // build the scheme select options for (var scheme in range) { schemeSelect.append("option").text(scheme); } // set up the scheme select change event handler schemeSelect.on("change", function () { // get the selected scheme var index = schemeSelect.property("selectedIndex"), option = schemeSelect.node()[index]; selectedRange = range[option.text]; domain = randDomain(); max = d3.max(domain); paint(); // redaw on selection... }); // set up the window resize event handler d3.select(window).on('resize', function(){ width = document.body.clientWidth-margin*2; height = document.body.clientHeight-margin*2; paint(); // redraw on resize... }); // apend the various elements linearGradinet.selectAll("stop") .data(selectedRange) .enter() .append("stop"); svg.append("rect") .attr("id", "gradientFill") .attr("fill", "url(#gradient)"); svg.append("rect") .attr("id", "panel") .style("fill", "white"); svg.append("text") .attr("id", "range-label"); svg.append("text") .attr("id", "domain-label"); svg.append("g") .attr("class", "x axis"); paint(); // inital draw... })(); // draw function paint() { xscale.domain(d3.extent(domain)).range([0, width]); xAxis.scale(xscale).tickValues(domain); svg.select(".x.axis").call(xAxis) .attr("transform", "translate(0," + (height-60) + ")"); svg.selectAll(".tick").call(drag); svg.select("#domain-label") .attr("dy", height) .text("domain: " + domain.toString()); svg.select("#range-label") .attr("dy", height+margin/2) .text("range: " + selectedRange.toString()); svg.select("#panel") .attr("y", height-60) .attr("width", width) .attr("height", 60); svg.select("#gradientFill") .style("width", width) .style("height", height); svg.selectAll(".tick") .append("rect") .attr("x", -5) .attr("width", 10) .attr("height", 10) .style("fill", function(d, i){ return selectedRange[i]; }); linearGradinet.selectAll("stop") .data(selectedRange) .attr("offset", function (d, i) { var percent = (domain[i] / max) * 100; return percent + "%"; }) .style("stop-color", function (d) { return d; }); } })();