首页 > 解决方案 > d3-lasso 在 Angular 7 中找不到 d3-drag 模块

问题描述

我有这个实现散点图的简单代码(在 Angular 7 应用程序中使用 d3.js),我想在其中启用 d3-lasso 功能来选择点。所以为了做到这一点,我安装了npm i d3-lassonpm i d3-drag.

我正在执行的代码如下:

private buildChart() {

// Set the dimensions of the canvas / graph
let margin = {top: 20, right: 80, bottom: 60, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;

let domainX = d3.extent(this.plotData.scatterDataList, function(d:any){
  return Number(d.x)
})

let domainY = d3.extent(this.plotData.scatterDataList, function(d:any){
  return Number(d.y)
})

// Define the x,y scale functions
let x = d3.scaleLinear()
.range([0, width])
.domain(domainX)
.nice();

let y = d3.scaleLinear()
.range([height, 0])
.domain(domainY)
.nice();

// Create the tooltip area
let tooltip = d3.select(this.chartElement.nativeElement).append("div")
.attr("class", "pca-tooltip")
.style("position","absolute")
.style("background-color", "#f5f5dcd4")
.style("padding","5px")
.style("border-radius","10px")
.style("opacity", 0);

// Tooltip's value parser
let xValue = function (d:any) {
  return d.x;
}; 
let yValue = function (d:any) {
  return d.y;
};

// Define colors
let color = d3.scaleOrdinal(d3.schemeCategory10);

// Prepare the SVG canvas
let svg = d3.select(this.chartElement.nativeElement)
.append('svg')
.attr('width', width + margin.left + margin.right )
.attr('height', height + margin.bottom + margin.top )

// Add the x Axis
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate("+ margin.left + "," + (height + margin.top) + ")")
.call(d3.axisBottom(x));

// Add the y Axis
svg.append("g")
.attr("class", "axis axis--y")
.attr("transform", "translate(" + margin.left + ","+ (margin.top) +")")
.text(this.plotData.yaxis)
.call(d3.axisLeft(y));

// Add points
svg.selectAll(".dot")
.data(this.plotData.scatterDataList)
.enter().append("circle")
.attr("id", function (d:any, i:number) {
  return d.metadatas[0];
}) 
.attr("class", "dot")
.attr("cursor", "crosshair")
.attr("r", 3.5)
.attr("cx", function (d:any) {
  return x(d.x) + margin.left;
})
.attr("cy", function (d:any) {
  return y(d.y) + margin.top;
})
.style("fill", function (d:any) {
  return color(d.classname);
})
.on("mouseover", function (d:any) {
  tooltip.transition()
  .duration(200)
  .style("opacity", .9);
  tooltip.html(d.metadatas[0] + "<br/> (" + xValue(d).toFixed(2) + ", " + yValue(d).toFixed(2) + ")")
  .style("left", (d3.select(this).attr("cx")) + "px")
  .style("top", (d3.select(this).attr("cy")) + "px");
})
.on("mouseout", function (d) {
  tooltip.transition()
  .duration(500)
  .style("opacity", 0);
});


// Create the area where the lasso event can be triggered
let lasso_area = svg.append("rect")
.attr("width", width+margin.left)
.attr("height", height+margin.top)
.style("opacity", 0);

// Lasso functions
let lasso_start = function() {
  lasso().items()
  .attr("r",3.5)                                      // reset size
  .style("fill", null)                                // clear all of the fills
  .classed("not_possible",true)                       // style as not possible
  .classed("selected",false);                         // style as selected
};

let lasso_draw = function() {

  // Style the possible dots
  lasso().possibleItems()
  .classed("not_possible",false)
  .classed("possible",true);
  // Style the not possible dot
  lasso().notPossibleItems()
  .classed("not_possible",true)
  .classed("possible",false);
};

let lasso_end = function() {
  // Reset the color of all dots
  lasso().items()
  .classed("not_possible",false)
  .classed("possible",false);
  // Style the selected dots
  lasso().selectedItems()
  .classed("selected",true)
  .attr("r",7);
  // Reset the style of the not selected dots
  lasso().notSelectedItems()
  .attr("r",3.5);
};

lasso() 
.items(d3.selectAll("dot"))
.targetArea(lasso_area)                                   // area where the lasso can be started
.closePathSelect(true)                                    // can items be selected by closing the path?
.closePathDistance(75)                                    // max distance for the lasso loop to be closed
.hoverSelect(true)                                        // can items by selected by hovering over them?
.on("start", () => { lasso_start() })                     // lasso start functionality
.on("draw", () => { lasso_draw() })                       // lasso draw functionality
.on("end", () => { lasso_end() });                        // lasso end functionality


svg.call(lasso());  

}

在浏览器中我收到以下错误。

ERROR ReferenceError: d3 is not defined
    at lasso (d3-lasso.js:776)
    at Selection.call (call.js:4)
    at PcaPlotComponent.push../src/app/dashComponents/plots/pca-plot/pca-plot.component.ts.PcaPlotComponent.buildChart (pca-plot.component.ts:177)
    at PcaPlotComponent.push../src/app/dashComponents/plots/pca-plot/pca-plot.component.ts.PcaPlotComponent.ngOnChanges (pca-plot.component.ts:19)
    at checkAndUpdateDirectiveInline (core.js:22095)
    at checkAndUpdateNodeInline (core.js:23363)
    at checkAndUpdateNode (core.js:23325)
    at debugCheckAndUpdateNode (core.js:23959)
    at debugCheckDirectivesFn (core.js:23919)
    at Object.eval [as updateDirectives] (AnalysisResultsComponent.html:152)

然后,如果我打开 d3-lasso.js 文件并查看第 776 行,我会看到以下内容:

// Apply drag behaviors
var drag = d3.drag() <------ THIS IS THE LINE WHERE IT CRASHES
    .on("start",dragstart)
    .on("drag",dragmove)
    .on("end",dragend);

由此,我得出结论,要么我使用了错误版本的 d3-lasso,要么 d3-lasso 存在一些问题,无法找到 d3-drag 模块。

如果对我在这里做错了什么有任何想法或提示,那将非常有用并受到欢迎。

编辑:

这是我的进口

import { Component, ElementRef, Input, OnChanges, ViewChild} from '@angular/core';
import * as d3 from 'd3';
import { lasso } from 'd3-lasso';

标签: javascriptangulard3.js

解决方案


推荐阅读