简体   繁体   English

如何在我的AngularJS中获取这个D3.js HTML元素,以便我可以操作它?

[英]How can I get this D3.js HTML element in my AngularJS so that I can manipulate it?

I'm trying to draw a graph using the D3.js graphical library for Javascript on my webpage. 我正在尝试使用D3.js图形库为我的网页上的Javascript绘制图形。 I can draw a gray line on an SVG using HTML. 我可以使用HTML在SVG上绘制一条灰线。 And I can draw a red line using Javascript on a new SVG container that I also created in the Javascript. 我可以在我在J​​avascript中创建的新SVG容器上使用Javascript绘制一条红线。 But I cannot figure out how to draw the readline on the SVG element created in the HTML. 但我无法弄清楚如何在HTML中创建的SVG元素上绘制readline。

I tried var svgContainer = document.getElementById("my_svg_widget") but that didn't work. 我尝试了var svgContainer = document.getElementById("my_svg_widget")但是没有用。

How can I draw the red line on the SVG element that is already declared in HTML file (with the same endpoint as the gray line) 如何在已在HTML文件中声明的SVG元素上绘制红线(与灰线的端点相同)

Here is the Plunker: https://plnkr.co/edit/F6deVZU3NNADOeIdC5Iy?p=preview 这是Plunker: https ://plnkr.co/edit/F6deVZU3NNADOeIdC5Iy p = preview

Below are my files for your reference. 以下是我的文件供您参考。

Javascript: 使用Javascript:

myApp = angular.module('myApp', ['ui.router'] );

myApp.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
    $stateProvider.state('myState', {url: '/myState', params: {slug: {value: null, squash: true} }, templateUrl: 'my-state-page1.html', controller: 'MyStateCtrl'} );
  } 
);

myApp.controller('MyStateCtrl', function($scope, $http) {
      var self = this;

      $scope.$watch(function() {return self.myDataFromAPI}, function (objVal) {
          console.log('objVal = ', objVal);
          x = objVal.origin.split('.');
          console.log("X = ", x)

          var svgContainer = d3.select("body") 
                               .append("svg") 
                               .attr("width", 1000) 
                               .attr("height", 1000); 

          var line = svgContainer.append("line") 
                                 .attr("x1", 0) 
                                 .attr("y1", 0) 
                                 .attr("x2", Number(x[2])) 
                                 .attr("y2", Number(x[3])) 
                                 .attr("stroke-width", 2) 
                                 .attr("stroke", "red");
        },
        true
      );


      self.httpFailure = function(response) {
        console.log('Failure');
        self.myDataFromAPI = null;
      }

      self.httpSuccess = function(response) {
        console.log('\n\n\nGot the data from the API!');
        self.myDataFromAPI = response.data;
        console.log('\n\n\self.myDataFromAPI =', self.myDataFromAPI);
      }

      $http.get(
        'https://httpbin.org/get'
      ).then(self.httpSuccess, self.httpFailure);
    }
);


myApp.directive('mypMyDirective',function(){
    return {
      restrict:'E',
      scope: {
        myDataFromAPI: '='
      },
      controller: 'MyStateCtrl',
      controllerAs: 'myStateCtrl',
      bindToController: true,
      templateUrl: 'myD3Diagram.html'
    };
  }
);

index.html: index.html的:

<!DOCTYPE html>
<html ng-app="myApp">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.js"></script>
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    HELLO!
    <div ng-controller="MyStateCtrl as myStateCtrl">
      <myp-my-directive mydatafromapi="myStateCtrl.myDataFromAPI"></myp-my-directive>
    </div>
  </body>
</html>

myD3Diagram.html: myD3Diagram.html:

<svg id="my_svg_widget" width="500" height="500">
  <line x1="5" y1="5" x2="40" y2="40" stroke="gray" stroke-width="5"  />
</svg>

In this you are appending a new svg every time the watch function is called. 在这里,每次调用watch函数时,你都会附加一个新的svg。

var svgContainer = d3.select("body") 
                               .append("svg") 
                               .attr("width", 1000) 
                               .attr("height", 1000); 

Correct way in your watch function instead of creating a new svg just do a select d3.select("svg") or d3.select("#my_svg_widget") to get the svg already present and append line to it. 在你的watch函数中正确的方式而不是创建一个新的svg只需要选择d3.select("svg")d3.select("#my_svg_widget")来获取svg已经存在并向其添加行。

 $scope.$watch(function() {return self.myDataFromAPI}, function (objVal) {
          console.log('objVal = ', objVal);
          x = objVal.origin.split('.');
          console.log("X = ", x)

          var svgContainer = d3.select("svg");


          var line = svgContainer.append("line")
                         .attr("x1", 0)
                         .attr("y1", 0)
                         .attr("x2", Number(x[2]))
                         .attr("y2", Number(x[3]))
                         .attr("stroke-width", 2)
                         .attr("stroke", "red");

        },
        true
      );

working code here 这里工作代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM