D3使用适当的比例缩放(Y轴,X轴)缩放Graph的问题

时间:2016-07-21 20:56:11

标签: javascript css d3.js svg visualization

Example Code Fiddle

我正在制作热图。其中我根据数据以编程方式制作热图(宽度,高度)的矩形。

我想添加滑块以放大X轴(时间范围),Y轴(距离范围)。 我尝试了d3缩放选项,工作正常。但是尺度(x轴,y轴)不会与图形的矩形成比例地缩放。就像一个矩形在10,20英里的y轴刻度之间。它在缩放时超过20英里。

然后我在svg上尝试了viewbox。有用 。比例与图表保持成比例。

我想保持缩放比例和图表的比例,但不想增加比例标签的大小,因为它会使图表变得难看。

以下是我最初制作图表的代码段

d3.json('dateWiseNewDataRight.json',function(err,right_dat){
            // console.log(right_dat);
            var dateGroups=_.groupBy(right_dat, "DATE");
            var data = [];
            var x= 0,y=0;
            var tlength=0;
            var totalDates=Object.keys(dateGroups);
            var graphWidth=(total_width/totalDates.length)-6;

            for(var key in dateGroups){
                tlength=0;
                data = [];
                y=0;
                var segmentMiles=0;
                var currentGraphData=dateGroups[key];
                var road=currentGraphData[0]['ROAD'];
                for(var i = 0; i < currentGraphData.length-1; i++) {
                    tlength+=currentGraphData[i].MILES;
                }
                for (var i = 0; i < currentGraphData.length-1; i++) {
                    var height=0;
                    segmentMiles=segmentMiles+currentGraphData[i].MILES;
                    for(var j in times){
                        if(road!=currentGraphData[i]['ROAD']){
                            road=currentGraphData[i]['ROAD'];
                            height=1;
                            for(var k=0;k<times.length;k++){
                                data.push({value:20000,x:x,y:y, height:height ,width:col_width,name:"",tmc:"", length:"",road:""});
                                x=x+col_width;
                            }
                            break;
                        }
                        else{

                            col_width=graphWidth/24;
                            var Congestion= currentGraphData[i][times[j]];
                            height=(currentGraphData[i].MILES/tlength)*total_height;
                            //road=leftDat[i]['ROAD'];
                            data.push({value:Congestion,x:x,y:y, height:height ,width:col_width,name:currentGraphData[i]['NAME'],tmc:currentGraphData[i]['TMC CODE'], length:currentGraphData[i]['MILES'],road:currentGraphData[i]['ROAD'],miles:segmentMiles});
                            // x=x+col_width;
                        }
                        x=x+col_width;
                    }
                    y=y+height;
                    x=0;
                }

                plotSegmentNames(panelData);

                var margin = { top: 50, right: 0, bottom: 10, left: 10 };

                $('.heat-map-2').append('<div class="chart-right-'+key+' " style="width: '+graphWidth+'px;float:left;margin:3px;;overflow:hidden"></div>');
                var graphDiv='.chart-right-'+key;
                var right_Svg = d3.select(graphDiv)
                        .append("svg")
                        .attr("class", "chart")
                        .attr("width",graphWidth)
                        .attr("height", total_height )
                        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
                var right_color_chart = right_Svg.append("g")
                        .attr("class", "rightHeatMap");
                right_color_chart.call(tip);

                var color = d3.scale.linear()
                        .domain([d3.min(data), 1])
                        .range(["blue", "green"]);
                right_color_chart.selectAll("rect")
                        .data(data)
                        .enter()
                        .append("rect")
                        .attr("x", function(d,i) {return d.x; })
                        .attr("y", function(d,i) { return d.y; })
                        .attr("width", col_width)
                        .attr("height",  function(d) { return d.height; })
                        .attr("road",function(d){
                            return d.road;
                        })
                        .attr("miles",  function(d) { return d.miles; })
                        .style("fill", function(d) {return chooseColor(d.value);})
                        .on('mouseover', tip.show)
                        .on('mouseout', tip.hide);
                var   right_xAxisScale = d3.time.scale(),
                        right_xAxis = d3.svg.axis()
                                .orient('bottom')
                                .ticks(d3.time.hour,1)
                                .tickFormat(d3.time.format('%I %p'))
                                .tickSubdivide(6);

                right_xAxis.scale(right_xAxisScale.range([0,graphWidth]).domain([timeFormat.parse(times[0]),timeFormat.parse(times[times.length-1])]));
                right_Svg.append('g')
                        .attr('class','x axis')
                        .call(right_xAxis)
                        .append('text')
                        .attr('transform','translate('+total_width+',0)');

                var    yAxisScale = d3.scale.linear()
                                .range([0,xAxisHeight])
                                .domain([0,tlength]),
                        yAxis = d3.svg.axis()
                                .orient('right')
                                .ticks(5)
                                .scale(yAxisScale);
                right_Svg.append('g')
                        .attr('transform','translate('+1+','+0+')')
                        .attr('class','y axis')
                        .call(yAxis)
//                        .append('text')
//                        .text('Length')
//                        .attr('transform','translate(100,'+total_height+') rotate(-90)');
            }



            var   testTimes =times;
            var distanceRange=[0,60];
            $("#scale-slider")
                    .slider({

                        animate:true,
                        range: true,
                        min: 0,
                        max: 1440,
                        step: 24,
                        values: [0, 1440],
                        slide: function (e, ui) {
                            var sliderTime= calculateSiderTime(e,ui);
                            testTimes=[sliderTime.nob1Time,sliderTime.nob2Time];
                            $('.x.axis').remove();
                            $('.y.axis').remove();
                          /*  redrawHeatMaps('left',left_color_chart,'leftHeatMap',leftDat,testTimes,tlength);
                            redrawHeatMaps('right',right_color_chart,'rightHeatMap',right_dat,testTimes,tlength);*/

                            redrawYHeatMaps('left',left_color_chart,'leftHeatMap',leftDat,testTimes,tlength,distanceRange);
                            redrawYHeatMaps('right',right_color_chart,'rightHeatMap',right_dat,testTimes,tlength,distanceRange);

                        }
                    })
                    .on("slidechange", function( e, ui ) {


                    });

            $("#distance-slider")
                    .slider({

                        animate:true,
                        range: true,
                        min: 0,
                        max: 60,
                        step: 5,
                        values: [0, 60],
                        slide: function (e, ui) {
                            distanceRange=ui.values;
                            $('.x.axis').remove();
                            $('.y.axis').remove();
                         //   left_color_chart.attr("transform", "translate("+ d3.event.translate + ")scale(" + d3.event.scale + ")");
                            redrawYHeatMaps('left',left_color_chart,'leftHeatMap',leftDat,testTimes,tlength,distanceRange);
                            redrawYHeatMaps('right',right_color_chart,'rightHeatMap',right_dat,testTimes,tlength,distanceRange);
                            $('.slider-distance1').html(ui.values[0]);
                            $('.slider-distance2').html( ui.values[1]);
                        }
                    })
                    .on("slidechange", function( e, ui ) {


                    });
        });

2 个答案:

答案 0 :(得分:2)

我假设您可能希望通过鼠标滚轮将轴缩放到热图单元格中。 以下是一些建议。试一试。

1)将缩放行为更改为:

              zoom = d3.behavior.zoom().scaleExtent([0,5]).scale(1).on("zoom", zoomIn);

2)删除缩放功能并更改zoomIn:

function zoomIn(){
var t = d3.event.translate,
s = d3.event.scale;
left_color_chart.attr("transform","translate("+t+")scale("+s+")")
}

答案 1 :(得分:1)

仅在发生缩放事件时编辑yAxisScale的域名。

Here is updated fiddle.

首先,删除y中的zoom方法。它有助于自动缩放轴,但事实并非如此。我最后会给出解释。

zoom = d3.behavior.zoom()
  .scaleExtent([0, 5])
  .scale(1)
  .on("zoom", zoomed);

之后,在缩放值更改时调整yAxisScale域。

function zoomed() {
  yAxisScale.domain([0, tlength / d3.event.scale]); // added
  leftSvg.select(".y.axis").call(yAxis);
  zoomIn();
}

为什么使用除法而不是乘法?因为如果缩放两次,则轴值仅显示与原始值相比的一半。

如果您使用zoom的{​​{1}}方法,则会使用乘法自动缩放y。所以,我说上面不是你的情况。