dc.js根据第一个图表中的条件将类添加到多个图表中的数据点

时间:2017-05-15 18:44:01

标签: javascript d3.js dc.js

在多图表dc.js / d3.js演示文稿中,我希望用户点击第一个图表中的数据点,并且:

  1. 识别图表1中的所有点,其值在点击点的30点之内; - 完成
  2. 存储这些数据点的索引; - 完成
  3. 着色图表1中存储的数据点; - 需要帮助
  4. 将图表2和3中相同索引位置的点着色 - 需要帮助
  5. 例如,用户点击第一个图表上的第2班次。在那个班次上建造了140辆汽车。在图表1中,三个班次在该班次的生产的30个范围内:2,7,10。我希望将这3个数据点设为绿色,然后在图表2和图3中也进行换班2,7,10绿色。 (另外,原始点击的数据点应该是红色的)

    我不确定如何将greendot类添加到三个图表中的这三个数据点。

    jsFiddle to work with

    clearconsole();
    var chartWidth = 500;
    var myCSV = [	
    {"shift":"1","date":"01/01/2016/08/00/00","car":"178","truck":"125","bike":"317","moto":"237"},
    {"shift":"2","date":"01/01/2016/17/00/00","car":"125","truck":"189","bike":"125","moto":"273"},
    {"shift":"3","date":"02/01/2016/08/00/00","car":"140","truck":"219","bike":"328","moto":"1252"},
    {"shift":"4","date":"02/01/2016/17/00/00","car":"222","truck":"290","bike":"432","moto":"378"},
    {"shift":"5","date":"03/01/2016/08/00/00","car":"200","truck":"250","bike":"420","moto":"319"},
    {"shift":"6","date":"03/01/2016/17/00/00","car":"230","truck":"220","bike":"310","moto":"413"},
    {"shift":"7","date":"04/01/2016/08/00/00","car":"155","truck":"177","bike":"377","moto":"180"},
    {"shift":"8","date":"04/01/2016/17/00/00","car":"179","truck":"203","bike":"405","moto":"222"},
    {"shift":"9","date":"05/01/2016/08/00/00","car":"208","truck":"185","bike":"360","moto":"195"},
    {"shift":"10","date":"05/01/2016/17/00/00","car":"150","truck":"290","bike":"315","moto":"280"},
    {"shift":"11","date":"06/01/2016/08/00/00","car":"200","truck":"220","bike":"350","moto":"205"},
    {"shift":"12","date":"06/01/2016/17/00/00","car":"230","truck":"170","bike":"390","moto":"400"},
    ];
    console.log('Click on a datapoint in chart1 to begin ');
    
    lc1 = dc.lineChart("#line1");
    lc2 = dc.lineChart("#line2");
    lc3 = dc.lineChart("#line3");
    
    var dateFormat = d3.time.format("%d/%m/%Y/%H/%M/%S");
    
    myCSV.forEach(function (d) {
    	d.date = dateFormat.parse(d.date);
    });
    
    myCSV.forEach(function (d) {
    	d['car'] = +d['car'];
    	d['bike'] = +d['bike'];
    	d['moto'] = +d['moto'];
    });
    
    //console.log(myCSV);
    
    var facts = crossfilter(myCSV);
    var dateDim = facts.dimension(function (d) {return d.date});
    
    var carDim = facts.dimension(function (d) {return d['car']});
    var dgCar = dateDim.group().reduceSum(function (d) {return d['car']});
    
    var bikeDim = facts.dimension(function (d) {return d['bike']});
    var dgBike = dateDim.group().reduceSum(function (d) {return d['bike']});
    
    var motoDim = facts.dimension(function (d) {return d['moto']});
    var dgMoto = dateDim.group().reduceSum(function (d) {return d['moto']});
    
    var minDate = new Date ("2016-01-01T08:00:00.000Z");
    var maxDate = new Date ("2016-01-06T17:00:00.000Z");	
    
    var maxY = d3.max(myCSV, function(d) {return d['car']});
    
    lc1
    .renderArea(false)
    .width(chartWidth)
    .height(250)
    .dimension(dateDim)
    .group(dgCar)
    .defined(function(d) {if(d.y !==null) {return d.y;}})
    .transitionDuration(1000)
    .margins({top: 30, right: 20, bottom: 35, left: 60})
    .yAxisLabel('Cars')
    .renderHorizontalGridLines(true)
    .brushOn(false)
    .x(d3.time.scale().domain([minDate,maxDate]));
    lc1.yAxis().ticks(5);
    lc1.xAxis().ticks(3);
    
    lc2
    .renderArea(false)
    .width(chartWidth)
    .height(250)
    .dimension(dateDim)
    .group(dgBike)
    .defined(function(d) {if(d.y !==null) {return d.y;}})
    .transitionDuration(1000)
    .margins({top: 30, right: 20, bottom: 35, left: 60})
    .yAxisLabel('Bikes')
    .renderHorizontalGridLines(true)
    .brushOn(false)
    .x(d3.time.scale().domain([minDate,maxDate]));
    lc2.yAxis().ticks(5);
    lc2.xAxis().ticks(3);
    
    lc3
    .renderArea(false)
    .width(chartWidth)
    .height(250)
    .dimension(dateDim)
    .group(dgMoto)
    .defined(function(d) {if(d.y !==null) {return d.y;}})
    .transitionDuration(1000)
    .margins({top: 30, right: 20, bottom: 35, left: 60})
    .yAxisLabel('Motos')
    .renderHorizontalGridLines(true)
    .brushOn(false)
    .x(d3.time.scale().domain([minDate,maxDate]));
    lc3.yAxis().ticks(5);
    lc3.xAxis().ticks(3);
    
    
    lc1.on('renderlet', function(lc1) {
    console.log('myCSV.length: '+myCSV.length);
       var allDots1 = lc1.selectAll('circle.dot');
       var allDots2 = lc2.selectAll('circle.dot');
       var allDots3 = lc3.selectAll('circle.dot');
       allDots1.on('click', function(d,i) { //i==index, d==obj of clicked point
    console.log(JSON.stringify(myCSV[i]));
          var arrWeeks = [];
          allDots1.filter((d,j)=> j===i).classed('reddot');
          for (var xx=0;xx<myCSV.length;xx++){
          	  var t1 = myCSV[xx].car - d.y;
        	    var t2 = d.y - myCSV[xx].car;
              var looptest = (t1<30 && t1>0) || (t2<30 && t2>0);
    console.log(myCSV[xx].car +' (loop val) is/not within 30 of '+d.y+ '(clicked val)' + looptest);
    					if ( (t1<30 && t1>0) || (t2<30 && t2>0) ){
            			arrWeeks.push(xx); //All index points in "Cars" that are within 30 of clicked point
            	}
              //Next line doesn't work:
    					//allDots2.filter((d,j)=> j===xx).classed('greendot').style('fill-opacity', 1);
          }//ENDFOR
    console.log("%s %o", 'arrWeeks: ', arrWeeks);
    				/*
            		Loop through all 3 "allDotsN" d3 collections and add
                greendot class to each circle that is at one of the 
                index values in arrWeeks. For example, if arrWeeks contains
                [2,4,6] then the 3rd, 5th and 7th dot points in all three
                graphs should be green (and the original clicked-on datapoint should be red)
            */
    //      allDots1.filter((d,j)=> j===arrWeeks[]).classed('greendot').style('fill-opacity', 1);
    //      allDots2.filter((d,j)=> j===arrWeeks[]).classed('greendot').style('fill-opacity', 1);
    //      allDots3.filter((d,j)=> j===arrWeeks[]).classed('greendot').style('fill-opacity', 1);
       });//END allDots1.on(click);
    
    });//END lc1.on(renderlet)
    
    dc.renderAll();
    dc.redrawAll();
    
    function clearconsole(){
    console.API;
    if (typeof console._commandLineAPI !== 'undefined') {
        console.API = console._commandLineAPI; //chrome
    } else if (typeof console._inspectorCommandLineAPI !== 'undefined') {
        console.API = console._inspectorCommandLineAPI; //Safari
    } else if (typeof console.clear !== 'undefined') {
        console.API = console;
    }
    console.API.clear();
    }
    svg{height:280px;width:500px;}
    
    .greendot{stroke:green !important; fill:green !important; fill-opacity:1 !important;}
    
    .reddot{stroke:red !important; fill:red !important; fill-opacity:1 !important;}
    <script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.3.3/d3.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.1/crossfilter.min.js"></script>
    <script src="http://dc-js.github.io/dc.js/js/dc.js"></script>
    <link href="http://dc-js.github.io/dc.js/css/dc.css" rel="stylesheet"/>
    
    <svg id="line1"></svg>
    <svg id="line2"></svg>
    <svg id="line3"></svg>

1 个答案:

答案 0 :(得分:7)

使用.classed('yourclass', true),请参阅docs

allDots1.on('click', function(d, i) { //i==index, d==obj of clicked point
    console.log(JSON.stringify(myCSV[i]));
    var arrWeeks = [i];

    for (var xx = 0; xx < myCSV.length; xx++) {
        var t1 = myCSV[xx].car - d.y;
        var t2 = d.y - myCSV[xx].car;
        var looptest = (t1 < 30 && t1 > 0) || (t2 < 30 && t2 > 0);
        console.log(myCSV[xx].car + ' (loop val) is/not within 30 of ' + d.y + '(clicked val)' + looptest);
        if ((t1 < 30 && t1 > 0) || (t2 < 30 && t2 > 0)) {
            arrWeeks.push(xx); //All index points in "Cars" that are within 30 of clicked point
        }
    } //ENDFOR
    console.log("%s %o", 'arrWeeks: ', arrWeeks);
    allDots1.classed('reddot', false);
    allDots1.classed('greendot', false);
    allDots2.classed('greendot', false);
    allDots3.classed('greendot', false);
    arrWeeks.forEach((i) => {
        allDots1.filter((d, j) => j === i).classed('greendot', true);
        allDots2.filter((d, j) => j === i).classed('greendot', true);
        allDots3.filter((d, j) => j === i).classed('greendot', true);
    });
    allDots1.filter((d, j) => j === i).classed('reddot', true);
});

Working demo