(function() { 'use strict'; //************************************************************ // Set up variables //************************************************************ var data = []; var items = 9; // data items (used by slider) function addData(n) { for (var i=0; i<=n; i++) { data.push({value: _.random(10,200), ref: i+1}); } } var dataReference = []; var n = 0, // set initial value w = 800, // width h = 200; // height var c20 = d3.scale.category20(); // add yScale var yScale = d3.scale.linear() .domain([0, 200]) .range([h, 0]); // ----------------------------- function createLines(selection) { selection .append('line') .attr({ x1: function(d, i) { return i *20 +10; }, y1: function(d) { return yScale(d.value); }, x2: function(d, i) { return i *20 +10; }, y2: yScale(0), id: function(d,i) { return 'line-' + i; }, class: 'line' }) .style({ 'stroke-width': 5, stroke: function(d,i) { if (i < 10) { return c20(i); } else { var j = i % 20; return c20(j); } } }) .on('mouseover', function(d,i) { // move legend on mouse over moveLegend('li-' + i); // update n for the buttons n = i; }); } var svg = d3.select('#chart') .append('svg') .attr({ width: w, height: h }); //************************************************************ // Legend //************************************************************ function renderLegend(data) { // create legend var legend = d3.eesur.legend() .dataKeys(dataReference); // event to update yScale when toggling line series legend.on('toggleLegend', function(d, i) { // console.log('toggleLegend: ' + d, i); // reference line via it's id var line = d3.select('#line-' + i); // reference legend item via it's ID e.g. 'li-0', 'li-1' etc var liID = 'li-' + i; // toggle item in array if (line.classed('legend-active')) { // toggle line line .style('opacity', 1) .classed('legend-active', false); // toggle legend item d3.select('#' + liID).style('opacity', 1); } else { // fade line line .style('opacity', 0.2) .classed('legend-active', true); // fade legend item d3.select('#' + liID).style('opacity', 0.2); } }); d3.select('#legend-list') .call(legend); } //************************************************************ // navigation for legend //************************************************************ var legendNavContainer = d3.select('#legend'); function addLegendNav() { legendNavContainer .append('button') .attr({ class: 'legendNav', id: 'legendPrev' }) .html('‹'); legendNavContainer .append('button') .attr({ class: 'legendNav', id: 'legendNext' }) .html('›'); } // controls to navigate back and forward function legendControls(data, index) { var nextBtn = d3.select('#legendNext'); var prevBtn = d3.select('#legendPrev'); d3.select('#legendNext').on('click', function() { // ensure buttons can't be clicked where there are no items if (n < data.length-4) { // ensure buttons are 'visually' active nextBtn.style('opacity', 1); prevBtn.style('opacity', 1); // update value of counter n++; // set index to the value of i index = n; console.log('value of i NEXT: ' + n); moveLegend('li-' + index); } else { // set n to be value not including the visible legend items // so that the prev button can be clicked with staggering n = data.length-4; // fade button out for user feedback nextBtn.style('opacity', 0.2); } }); d3.select('#legendPrev').on('click', function() { if (n >= 1) { prevBtn.style('opacity', 1); nextBtn.style('opacity', 1); n--; index = n; console.log('value of i PREV: ' + n); moveLegend('li-' + index); } else { prevBtn.style('opacity', 0.2); } }); } // offset items in list via their id function moveLegend(reference) { var list = document.getElementById('legend-list'), targetLi = document.getElementById(reference); // id tag of the
  • element list.scrollLeft = (targetLi.offsetLeft - 80); console.log(reference + ': ' +targetLi.offsetLeft); } // ----------------------------- // render function render(newDataAmount) { // remove old items d3.selectAll('.line').remove(); d3.selectAll('.legendNav').remove(); d3.select('#legend-list').remove(); // update data data = []; addData(items); // give some fake key values to the dummy data dataReference = data.map(function(d, i) { return 'bar ' + i; }); // create the lines var lines = svg.selectAll('line') .data(data) .enter() .call(createLines); // create legend renderLegend(data); // only show the controls if needed if (data.length > 4) { addLegendNav(); legendControls(dataReference, 1); } } render(items); // ----------------------------- // slider code to change number of data items/lines // https://github.com/turban/d3.slider // ensure slider text is showing current render values d3.select('#slider-text-items').text(items); // update items d3.select('#slider-items').call(d3.slider().value(items).min(0).max(40).on('slide', function(evt, value) { items = d3.round(value); // ensure whole number d3.select('#slider-text-items').text(items + 1); // update the text to show value render(items); // update with new amount of items })); })();