简体   繁体   English

d3-tip不适用于webpack

[英]d3-tip doesn't work with webpack

I use webpack and TypeScript and it seems that d3-tip isn't able to work with webpack. 我使用webpack和TypeScript,似乎d3-tip无法使用webpack。 I get error on mouseover events "Uncaught TypeError: Cannot read property 'target' of null" . 我在鼠标悬停事件中收到错误"Uncaught TypeError: Cannot read property 'target' of null"

This error occurs because d3.event in the d3-tip module is null. 发生此错误是因为d3-tip模块中的d3.event为null。

I include modules as follows: 我包括如下模块:

const d3: any = require("d3");
d3.tip = require("d3-tip");

but I guess that d3 there and d3 in the d3-tip module are different and this is the source of problems, but I don't know how to solve it. 但是我猜d3-tip模块中的d3和d3是不同的,这是问题的根源,但我不知道如何解决它。 In the d3-tip module we have: 在d3-tip模块中,我们有:

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module with d3 as a dependency.
        define(['d3'], factory)
    } else if (typeof module === 'object' && module.exports) {
        // CommonJS
        var d3 = require('d3')
        module.exports = factory(d3)
    } else {
        // Browser global.
        root.d3.tip = factory(root.d3)
    }
}(this, function (d3) {
...

And it compiles by webpack into 它由webpack编译成

function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// d3.tip
// Copyright (c) 2013 Justin Palmer
//
// Tooltips for d3.js SVG visualizations

(function (root, factory) {
    if (true) {
        // AMD. Register as an anonymous module with d3 as a dependency.
        !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(465)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))
    } else if (typeof module === 'object' && module.exports) {
        // CommonJS
        var d3 = require('d3')
        module.exports = factory(d3)
    } else {
        // Browser global.
        root.d3.tip = factory(root.d3)
    }
}(this, function (d3) {
...

and it's obvious that AMD is using. 而AMD显然正在使用它。 If I could get the factory of d3-tip I would solve that problem. 如果我能得到d3-tip的工厂,我会解决这个问题。

pass the target element as the last parameter to tip.show() 将目标元素作为最后一个参数传递给tip.show()

var tip = require("d3-tip");
var tooltip = tip().html(d => d.value);
vis.call(tooltip)

vis.append("rect")
    // ...
    .on("mouseover", function() {
        tooltip.show.apply(this, [...arguments, this]);
    });

and d3-tip will pick it up and use as target. 并且d3-tip将拾取并用作目标。 From source : 来源

if (args[args.length - 1] instanceof SVGElement) target = args.pop()

another way: 其他方式:

.on("mouseover", function(d) {
    tooltip.show(d, this);
});

I found the solution. 我找到了解决方案。 As I think webpack produces many instances of each module when it's required. 我认为webpack会在需要时生成每个模块的许多实例。 I've used single-module-instance-webpack-plugin and it's solved my problem. 我使用了single-module-instance-webpack-plugin ,它解决了我的问题。

You also just need to initialize d3 in the fisrt time somewhere, it should be file like vendor.ts where you include vendor libraries: 您还需要在vendor.ts time中初始化d3,它应该是像vendor.ts这样的文件,其中包含供应商库:

// D3 and third-party components
const d3: any = require("d3");
d3.tip = require("d3-tip");

For pure JS initialization would be easy. 对于纯JS初始化会很容易。

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

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