在使图表响应时,x,y轴线消失

时间:2016-06-05 09:21:59

标签: angularjs d3.js svg

我让我的图表响应,但我注意到的是调整x线的大小,y轴正在消失。

我正在分享



var app = angular.module('chartApp', []);

app.controller('LineGraphCtrl', ['$scope','$http',

    function($scope,$http){

        $scope.lineGraph={
            72:{company:{ais_time:0},user:{ais_time:0}},
            73:{company:{ais_time:3},user:{ais_time:2}},
            74:{company:{ais_time:2},user:{ais_time:1}},
            75:{company:{ais_time:2},user:{ais_time:3}},
            76:{company:{ais_time:3},user:{ais_time:4}},
            77:{company:{ais_time:1},user:{ais_time:1}},
            78:{company:{ais_time:2},user:{ais_time:0}},
            79:{company:{ais_time:4},user:{ais_time:3}}};
        console.log($scope.lineGraph);

        $scope.lineaGraphData=[];

        $scope.UservsCompanyAIData=[];

        for(var i in $scope.lineGraph) {

            console.log(i);

            for (var j in $scope.lineGraph[i]) {
                if(j=="company") {
                    $scope.lineaGraphData.push({
                        "week": i,
                        "AI": $scope.lineGraph[i].company.ais_time,
                        "key": "company"
                    });
                } else {
                    $scope.lineaGraphData.push({
                        "week": i,
                        "AI": $scope.lineGraph[i].user.ais_time,
                        "key": "user"
                    });
                }
            }
        }

        function getDateOfISOWeek(w, y) {
            var simple = new Date(y, 0, 1 + (w - 1) * 7);
            var dow = simple.getDay();
            var ISOweekStart = simple;
            if (dow <= 4)
                ISOweekStart.setDate(simple.getDate() - simple.getDay() + 1);
            else
                ISOweekStart.setDate(simple.getDate() + 8 - simple.getDay());
            return ISOweekStart;
        };

        for(var i=0;i<$scope.lineaGraphData.length;i++){
            var weekStart=getDateOfISOWeek($scope.lineaGraphData[i].week,2015);
            $scope.UservsCompanyAIData.push({"Date":weekStart,"Label":$scope.lineaGraphData[i].key,"AIvalue":$scope.lineaGraphData[i].AI});
        }



        console.log($scope.UservsCompanyAIData);




    }]);

app.directive('userVsCompanyAI', function($parse, $window){
    return{
        restrict:'EA',
        scope: {data: '=data'},
        link: function(scope, element, attrs) {

            scope.$watch('data', function (data) {

                if (data) {

                    var data = scope.data;
                    //Dimensions of the Graph
                     var margin={top:30,right:20,left:50,bottom:80},
                     width=800-margin.left -margin.right,
                     height=400-margin.top-margin.bottom;

                     var color = d3.scale.category10();

                     var parseDate =d3.time.format("%d/%m").parse;

                     //Range of the Graph
                     var x = d3.time.scale().range([0,width]);
                     var y = d3.scale.linear().range([height,0]);

                     //Defining the Axis
                     var xAxis=d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format("%d/%m")).ticks(5);
                     var yAxis=d3.svg.axis().scale(y).orient("left").ticks(5);

                     //Defining the line for user & company's Avg

                     var AILine =d3.svg.line()
                     .x(function (d){return x(d.Date)})
                     .y(function (d) {return y(d.AIvalue)});

                     var el = element[0];

                     //Adding the SVG to the Graph
                     var UserVsCompanyAILineChart=d3.select(el)
                         .classed("svg-container", true) //container class to make it responsive
                         .append("svg")
                         //responsive SVG needs these 2 attributes and no width and height attr
                         .attr("preserveAspectRatio", "xMinYMin meet")
                         .attr("viewBox", "0 0 900 400")
                         //class to make it responsive
                         .classed("svg-content-responsive", true)
                         .append("g")
                     .attr("transform","translate("+margin.left+","+margin.top+")");

                     data.forEach(function (d) {
                     d.Date=d.Date;
                     d.AIvalue=+d.AIvalue;

                     });


                     //Setting the Domain of Scales based on Data

                     x.domain(d3.extent(data,function (d) {
                     return d.Date;
                     }));

                     y.domain([0,d3.max(data,function (d) {
                     return d.AIvalue;
                     })]);

                     var dataNest=d3.nest()
                     .key(function (d) {
                     return d.Label;
                     })
                     .entries(data);

                    var legendRectSize = 16;

                    var legendSpace = (width)/dataNest.length;

                     dataNest.forEach(function (d,i) {
                     UserVsCompanyAILineChart.append("path")
                     .attr("class","line")
                     .style("stroke", function() {
                     return d.color = color(d.key); })
                     .attr("d",AILine(d.values));

                         UserVsCompanyAILineChart.append("text")
                             .attr("x", (legendSpace/2)+i*legendSpace)
                             .attr("y", height + (margin.bottom/2)+ 30)
                             .attr("class", "WizUservsCompanyAvgReportLegend")
                             .style("fill", function() {
                                 return d.color = color(d.key); })
                             .text(d.key);

                         UserVsCompanyAILineChart.append('rect')
                             .attr('width', legendRectSize)
                             .attr('height', legendRectSize)
                             .attr("x", ((legendSpace/2)-30)+i*(legendSpace))
                             .attr("y", height + (margin.bottom/2)+ 15)
                             .style('fill',  function() {
                                 return d.color = color(d.key); })
                             .style('stroke',  function() {
                                 return d.color = color(d.key); });
                     });

                     UserVsCompanyAILineChart.append("g")
                     .attr("class","x axis")
                     .attr("transform","translate(0,"+height+")")
                     .call(xAxis)


                     UserVsCompanyAILineChart.append("g")
                     .attr("class","y axis")
                     .call(yAxis)

                }

            })
        }
    };
});
&#13;
/* Styles go here */

body { font: 12px Arial;}

path {
    stroke: steelblue;
    stroke-width: 2;
    fill: none;
}

.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}

.legend {
    font-size: 16px;
    font-weight: bold;
    text-anchor: middle;
}

/*SVG Responsive*/
.svg-container {
    display: inline-block;
    position: relative;
    width: 100%;
    padding-bottom: 100%; /* aspect ratio */
    vertical-align: top;
    overflow: hidden;
}
.svg-content-responsive {
    display: inline-block;
    position: absolute;
    top: 10px;
    left: 0;
}

/*SVG Responsive Ends*/
&#13;
<html>

  <head>
    <script data-require="angularjs@1.5.5" data-semver="1.5.5" src="https://code.angularjs.org/1.5.5/angular.js"></script>
    <link rel="stylesheet" href="style.css" type="text/css" />
    <link rel="stylesheet" href="bootstrap/dist/css/bootstrap.css" type="text/css" />
  </head>

  <body>
    <script src="angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <script src="script.js"></script>
    <div ng-app="chartApp">
      <div class="panel panel-default" data-toggle="modal" data-target="#myModal" ng-controller="LineGraphCtrl" style="height: 30%;width: 30%;float:right">
        <div class="panel-body">
          <div user-vs-company-a-i="" data="UservsCompanyAIData"></div>
        </div>
      </div>
      
       <div  class="panel panel-default"  data-toggle="modal" data-target="#myModal" ng-controller="LineGraphCtrl"   style="height: 70%;width: 70%;float:right" >
        <div   class="panel-body"  >
            <div user-vs-company-a-i data="UservsCompanyAIData"></div>
        </div>
        </div>
    </div>
    </div>
  </body>

</html>
&#13;
&#13;
&#13;

链接到这里。

有2个图表,一个较小,另一个较大。在这里你可以看到尺寸较大的图表显示x,y轴线,但在较小的图表中,x,y轴线不可见。有没有什么方法可以使图表响应,但x,y轴线仍然是可行的。

感谢任何帮助。

提前致谢。

2 个答案:

答案 0 :(得分:0)

要阻止它们消失,请使它们变粗。

目前,您的轴的stroke-width设置为1。主图大约为1:1比例,因此它们的轴线宽度约为一个像素。在您的小型版本中,轴线的绘制厚度相应较小 - 小于半个像素。您无法绘制半个像素,因此浏览器会使用浅灰色调绘制线条,使其几乎看不见。

要修复,请使轴线更粗:

.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 2;
    shape-rendering: crispEdges;
}

如果&#34; 2&#34;对于你来说太厚了,你可以使用一个中间值,比如1.5。

答案 1 :(得分:0)

解决方案

我建议在调整浏览器大小时重绘图表 - 只需向window resize event注册一个监听器即可。不要忘记去抖动/限制事件,以便重绘只发生一次(即去抖动)(或只是几次,即限制)浏览器已完成大小调整。

另一个黑客方法是让stroke-width更厚,但在我看来,这会导致结果在某些分辨率下看起来很好而在其他分辨率上很差。此外,当在移动大小的浏览器窗口中呈现具有较厚stroke-width的图表时,您最终会看到看起来很粗的轴。​​

所以在我看来,最佳选择是在调整大小时重绘图表

原因

当浏览器调整为较小尺寸时,已渲染的SVG会缩小。正如第一个答案已经指出的那样,某个点stroke-width=1的线从原始厚度变为小于0.5,浏览器决定不再绘制它。