block by nitaku 6f734fee239757282bbe

HCL decomposition: linL quadC 'cubehelix' rainbow

Full Screen

-

index.js

(function() {
  var c_axis, c_line, c_y, h_axis, h_line, h_y, l_axis, l_line, l_y, palette, svg, x;

  palette = d3.range(256).map(function(i) {
    return d3.hcl(340 - 480 * i / 256, 40 - Math.pow(128 - i, 2) / 400, 100 * i / 256);
  });

  svg = d3.select('svg');

  svg.selectAll('.colored_band').data(palette).enter().append('rect').attr('class', 'colored_band').attr('x', function(d, i) {
    return 32 + 3.5 * i;
  }).attr('y', 21).attr('width', 3.5).attr('height', 120).attr('fill', function(d) {
    return d;
  });

  svg.selectAll('.hue_band').data(palette).enter().append('rect').attr('class', 'hue_band').attr('x', function(d, i) {
    return 32 + 3.5 * i;
  }).attr('y', 166).attr('width', 3.5).attr('height', 60).attr('fill', function(d) {
    var hcl;

    hcl = d3.hcl(d);
    hcl.c = 60;
    hcl.l = 60;
    return hcl;
  });

  svg.selectAll('.chroma_band').data(palette).enter().append('rect').attr('class', 'chroma_band').attr('x', function(d, i) {
    return 32 + 3.5 * i;
  }).attr('y', 237).attr('width', 3.5).attr('height', 116).attr('fill', function(d) {
    var hcl;

    hcl = d3.hcl(d);
    hcl.l = hcl.c / 1.4;
    hcl.h = 80;
    hcl.c = 25;
    return hcl;
  });

  svg.selectAll('.luminance_band').data(palette).enter().append('rect').attr('class', 'luminance_band').attr('x', function(d, i) {
    return 32 + 3.5 * i;
  }).attr('y', 364).attr('width', 3.5).attr('height', 116).attr('fill', function(d) {
    var hcl;

    hcl = d3.hcl(d);
    hcl.c = 0;
    return hcl;
  });

  x = d3.scale.linear().domain([0, 255]).range([32, 928]);

  h_y = d3.scale.linear().domain([0, 360]).range([166 + 60, 166]);

  c_y = d3.scale.linear().domain([0, 150]).range([237 + 116, 237]);

  l_y = d3.scale.linear().domain([0, 100]).range([364 + 116, 364]);

  h_line = d3.svg.line().x(function(_, i) {
    return x(i);
  }).y(function(d, i) {
    var h;

    h = d3.hcl(d).h;
    return h_y(h >= 0 ? h : h + 360);
  });

  c_line = d3.svg.line().x(function(_, i) {
    return x(i);
  }).y(function(d, i) {
    return c_y(d3.hcl(d).c);
  });

  l_line = d3.svg.line().x(function(_, i) {
    return x(i);
  }).y(function(d, i) {
    return l_y(d3.hcl(d).l);
  });

  svg.append('path').datum(palette).attr('class', 'hue').attr('d', h_line);

  svg.append('path').datum(palette).attr('class', 'chroma').attr('d', c_line);

  svg.append('path').datum(palette).attr('class', 'luminance').attr('d', l_line);

  h_axis = d3.svg.axis().scale(h_y).tickValues([0, 360]).orient('right').tickSize(3, 5);

  c_axis = d3.svg.axis().scale(c_y).ticks(4).orient('right').tickSize(3, 5);

  l_axis = d3.svg.axis().scale(l_y).ticks(2).orient('right').tickSize(3, 5);

  svg.append('g').attr('class', 'axis').attr('transform', 'translate(932,0)').call(h_axis);

  svg.append('g').attr('class', 'axis').attr('transform', 'translate(932,0)').call(c_axis);

  svg.append('g').attr('class', 'axis').attr('transform', 'translate(932,0)').call(l_axis);

}).call(this);

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="description" content="HCL decomposition: linL quadC 'cubehelix' rainbow" />
    <title>HCL decomposition: linL quadC 'cubehelix' rainbow</title>
    <link rel="stylesheet" href="index.css">
    <script src="//d3js.org/d3.v3.min.js"></script>
</head>
<body>
  <svg height="500" width="960">
    <text class="label" x="16" y="198" dy="0.35em">H</text>
    <text class="label" x="16" y="295" dy="0.35em">C</text>
    <text class="label" x="16" y="420" dy="0.35em">L</text>
  </svg>
  
  <script src="index.js"></script>
</body>
</html>

index.coffee

palette = d3.range(256).map (i) -> d3.hcl(340-480*i/256, 40-Math.pow(128-i,2)/400, 100*i/256)

svg = d3.select('svg')

svg.selectAll('.colored_band')
    .data(palette)
  .enter().append('rect')
    .attr('class', 'colored_band')
    .attr('x', (d,i)->32+3.5*i)
    .attr('y', 21)
    .attr('width', 3.5)
    .attr('height', 120)
    .attr('fill', (d)->d )
    
svg.selectAll('.hue_band')
    .data(palette)
  .enter().append('rect')
    .attr('class', 'hue_band')
    .attr('x', (d,i)->32+3.5*i)
    .attr('y', 166)
    .attr('width', 3.5)
    .attr('height', 60)
    .attr('fill', (d) ->
        hcl = d3.hcl(d)
        hcl.c = 60
        hcl.l = 60
        return hcl
    )

svg.selectAll('.chroma_band')
    .data(palette)
  .enter().append('rect')
    .attr('class', 'chroma_band')
    .attr('x', (d,i)->32+3.5*i)
    .attr('y', 237)
    .attr('width', 3.5)
    .attr('height', 116)
    .attr('fill', (d) ->
        hcl = d3.hcl(d)
        hcl.l = hcl.c/1.4
        hcl.h = 80
        hcl.c = 25
        return hcl
    )

svg.selectAll('.luminance_band')
    .data(palette)
  .enter().append('rect')
    .attr('class', 'luminance_band')
    .attr('x', (d,i)->32+3.5*i)
    .attr('y', 364)
    .attr('width', 3.5)
    .attr('height', 116)
    .attr('fill', (d) ->
        hcl = d3.hcl(d)
        hcl.c = 0
        return hcl
    )
    
x = d3.scale.linear()
  .domain([0,255])
  .range([32, 928])
  
h_y = d3.scale.linear()
  .domain([0,360])
  .range([166+60, 166])
c_y = d3.scale.linear()
  .domain([0,150])
  .range([237+116, 237])
l_y = d3.scale.linear()
  .domain([0,100])
  .range([364+116, 364])
  
h_line = d3.svg.line()
    .x((_, i) -> x(i))
    .y((d, i) ->
      h = d3.hcl(d).h
      return h_y( if h >= 0 then h else h+360 )
    )
c_line = d3.svg.line()
    .x((_, i) -> x(i))
    .y((d, i) ->
      c_y( d3.hcl(d).c )
    )
l_line = d3.svg.line()
    .x((_, i) -> x(i))
    .y((d, i) -> l_y( d3.hcl(d).l ) )
    
svg.append('path')
  .datum(palette)
  .attr('class', 'hue')
  .attr('d', h_line)
svg.append('path')
  .datum(palette)
  .attr('class', 'chroma')
  .attr('d', c_line)
svg.append('path')
  .datum(palette)
  .attr('class', 'luminance')
  .attr('d', l_line)
  
h_axis = d3.svg.axis()
  .scale(h_y)
  .tickValues([0,360])
  .orient('right')
  .tickSize(3,5)
  
c_axis = d3.svg.axis()
  .scale(c_y)
  .ticks(4)
  .orient('right')
  .tickSize(3,5)
  
l_axis = d3.svg.axis()
  .scale(l_y)
  .ticks(2)
  .orient('right')
  .tickSize(3,5)
  
svg.append('g')
  .attr('class', 'axis')
  .attr('transform', 'translate(932,0)')
  .call(h_axis)
  
svg.append('g')
  .attr('class', 'axis')
  .attr('transform', 'translate(932,0)')
  .call(c_axis)
  
svg.append('g')
  .attr('class', 'axis')
  .attr('transform', 'translate(932,0)')
  .call(l_axis)

index.css

body {
    background: #272822;
    margin: 0;
    padding: 0;
}
svg {
    background: white;
}
.label {
  text-anchor: middle;
  font-size: 24px;
}
rect {
  shape-rendering: crispEdges;
}
path {
  fill: none;
}
path.hue {
  stroke: white;
  stroke-width: 1;
}
path.chroma {
  stroke: #FF3D00;
  stroke-width: 1;
}
path.luminance {
  stroke: black;
  stroke-width: 0.6;
}

.axis .domain, .axis .tick line {
  stroke: black;
  shape-rendering: crispEdges;
}
.axis {
  font-size: 8px;
  font-family: sans-serif;
}