d3-tip 不适用于 webpack

Posted

技术标签:

【中文标题】d3-tip 不适用于 webpack【英文标题】:d3-tip doesn't work with webpack 【发布时间】:2017-01-17 13:49:32 【问题描述】:

我使用 webpack 和 TypeScript,d3-tip 似乎无法与 webpack 一起使用。我收到鼠标悬停事件错误 "Uncaught TypeError: Cannot read property 'target' of null".

这个错误是因为d3-tip模块中的d3.event为空。

我包含的模块如下:

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

但我猜那里的 d3 和 d3-tip 模块中的 d3 是不同的,这是问题的根源,但我不知道如何解决。在 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) 
...

并通过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) 
...

很明显,AMD 正在使用。如果我能得到 d3-tip 的工厂,我会解决这个问题。

【问题讨论】:

【参考方案1】:

将目标元素作为最后一个参数传递给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]);
    );

d3-tip 会拾取它并用作目标。来自source:

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

另一种方式:

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

【讨论】:

【参考方案2】:

我找到了解决方案。我认为 webpack 在需要时会为每个模块生成许多实例。我用过single-module-instance-webpack-plugin,它解决了我的问题。

您还只需要在第一次初始化 d3 的某个地方,它应该是像 vendor.ts 这样的文件,其中包含供应商库:

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

对于纯 JS 的初始化会很容易。

【讨论】:

您使用的是 d3 版本 3 还是 4?我在使用带有 webpack 的 d3 版本 3 时遇到了类似的问题。

以上是关于d3-tip 不适用于 webpack的主要内容,如果未能解决你的问题,请参考以下文章

d3-tip中show在自己调用时需要改变this值

Tensorflow - 多 GPU 不适用于模型(输入),也不适用于计算梯度

为啥 UITableViewAutomaticDimension 不适用于 sectionFooterHeight?

为啥排序不适用于矢量?

验证不适用于 saveMany

UipanGesture 不适用于 Uiswitch