簡體   English   中英

適當縮放比例(Y軸,X軸)的圖的D3縮放問題

[英]D3 Scaling issue of Graph with appropriate scaling of Scales(Y-axis,X-axis)

示例代碼小提琴

我正在制作熱圖。 在其中,我根據數據以編程方式制作熱圖的矩形(寬度,高度)。

我想添加滑塊以在X軸(時間范圍),Y軸(距離范圍)上縮放。 我嘗試了d3縮放選項,效果很好。 但是比例(x軸,y軸)並不與圖形的矩形成比例。 就像矩形在y軸刻度10,20英里之間。 擴展規模超過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 ) {


                    });
        });

我假設您可能想通過鼠標滾輪將熱圖單元縮放到軸未縮放的位置。 這里有一些建議。 試試看。

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+")")
}

發生縮放事件時,僅編輯yAxisScale的域。

這是更新的小提琴。

首先,刪除zoom中的y方法。 它有助於自動縮放軸,但不是您的情況。 最后我會解釋。

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();
}

為什么要使用除法而不是乘法? 因為如果縮放兩次,則軸值僅顯示為其原始值的一半。

如果您使用zoomy方法,它將使用乘法自動縮放yAxisScale 所以,我說的不是你上面的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM