mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-07-28 00:49:46 +03:00
Merge d3tooltip from romseguy/d3tooltip
This commit is contained in:
parent
fb9d826f61
commit
c4e6588c22
3
packages/d3tooltip/.babelrc
Normal file
3
packages/d3tooltip/.babelrc
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"presets": ["es2015-loose", "stage-0"]
|
||||||
|
}
|
4
packages/d3tooltip/.eslintignore
Normal file
4
packages/d3tooltip/.eslintignore
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
lib
|
||||||
|
**/node_modules
|
||||||
|
**/webpack.config.js
|
||||||
|
examples/**/server.js
|
16
packages/d3tooltip/.eslintrc
Normal file
16
packages/d3tooltip/.eslintrc
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"extends": "eslint-config-airbnb",
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"mocha": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"react/jsx-uses-react": 2,
|
||||||
|
"react/jsx-uses-vars": 2,
|
||||||
|
"react/react-in-jsx-scope": 2
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"react"
|
||||||
|
]
|
||||||
|
}
|
5
packages/d3tooltip/.npmignore
Normal file
5
packages/d3tooltip/.npmignore
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.DS_Store
|
||||||
|
*.log
|
||||||
|
test
|
||||||
|
examples
|
||||||
|
coverage
|
21
packages/d3tooltip/LICENSE.md
Normal file
21
packages/d3tooltip/LICENSE.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 romseguy
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
54
packages/d3tooltip/README.md
Normal file
54
packages/d3tooltip/README.md
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
d3tooltip
|
||||||
|
=========================
|
||||||
|
|
||||||
|
This tooltip aims for a minimal yet highly configurable API. It has a long way to go, but the essentials are there.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
`npm install d3-state-visualizer`
|
||||||
|
|
||||||
|
## Quick usage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import d3 from 'd3';
|
||||||
|
import d3tooltip from 'd3tooltip';
|
||||||
|
|
||||||
|
const DOMNode = document.getElementById('chart');
|
||||||
|
const root = d3.select(DOMNode);
|
||||||
|
const vis = root.append('svg');
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
offset: {left: 30, top: 10}
|
||||||
|
};
|
||||||
|
|
||||||
|
vis.selectAll('circle').data(someData).enter()
|
||||||
|
.append('circle')
|
||||||
|
.attr('r', 10)
|
||||||
|
.call(
|
||||||
|
d3tooltip(d3, 'tooltipClassName', options)
|
||||||
|
.text((d, i) => toStringOrHtml(d))
|
||||||
|
.attr({ 'class': 'anotherClassName' })
|
||||||
|
.style({ 'min-width': '50px', 'border-radius: 5px' })
|
||||||
|
)
|
||||||
|
.on({
|
||||||
|
mouseover(d, i) {
|
||||||
|
d3.select(this).style({
|
||||||
|
fill: 'skyblue'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
mouseout(d, i) {
|
||||||
|
d3.select(this).style({
|
||||||
|
fill: 'black'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
Option | Type | Default | Description
|
||||||
|
--------------------------|--------------|---------------------|--------------------------------------------------------------
|
||||||
|
`root` | DOM.Element | `body` | The tooltip will be added as a child of that element. You can also use a D3 [selection](https://github.com/mbostock/d3/wiki/Selections#d3_select)
|
||||||
|
`left` | Number | `undefined` | Sets the tooltip `x` absolute position instead of the mouse `x` position, relative to the `root` element
|
||||||
|
`top` | Number | `undefined` | Sets the tooltip `y` absolute position instead of the mouse `y` position, relative to the `root` element
|
||||||
|
`offset` | Object | `{left: 0, top: 0}` | Sets the distance, starting from the cursor position, until the tooltip is rendered. **Warning**: only applicable if you don't provide a `left` or `top` option
|
49
packages/d3tooltip/package.json
Normal file
49
packages/d3tooltip/package.json
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{
|
||||||
|
"name": "d3tooltip",
|
||||||
|
"version": "1.2.2",
|
||||||
|
"description": "A highly configurable tooltip for d3",
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"clean": "rimraf lib dist",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"build": "npm run build:lib && npm run build:umd && npm run build:umd:min",
|
||||||
|
"build:lib": "babel src --out-dir lib",
|
||||||
|
"build:umd": "webpack src/index.js dist/d3tooltip.js --config webpack.config.development.js",
|
||||||
|
"build:umd:min": "webpack src/index.js dist/d3tooltip.min.js --config webpack.config.production.js",
|
||||||
|
"version": "npm run build",
|
||||||
|
"postversion": "git push && git push --tags && npm run clean",
|
||||||
|
"prepublish": "npm run clean && npm run build"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/romseguy/d3tooltip.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"d3",
|
||||||
|
"tooltip"
|
||||||
|
],
|
||||||
|
"author": "romseguy",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/romseguy/d3tooltip/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/romseguy/d3tooltip",
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-cli": "^6.3.15",
|
||||||
|
"babel-core": "^6.1.20",
|
||||||
|
"babel-eslint": "^5.0.0-beta4",
|
||||||
|
"babel-loader": "^6.2.0",
|
||||||
|
"babel-preset-es2015-loose": "^6.1.3",
|
||||||
|
"babel-preset-react": "^6.3.13",
|
||||||
|
"babel-preset-stage-0": "^6.3.13",
|
||||||
|
"eslint": "^0.23",
|
||||||
|
"eslint-config-airbnb": "0.0.6",
|
||||||
|
"eslint-plugin-react": "^3.6.3",
|
||||||
|
"rimraf": "^2.3.4",
|
||||||
|
"webpack": "^1.9.6",
|
||||||
|
"webpack-dev-server": "^1.8.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ramda": "^0.17.1"
|
||||||
|
}
|
||||||
|
}
|
84
packages/d3tooltip/src/index.js
vendored
Normal file
84
packages/d3tooltip/src/index.js
vendored
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
import { is } from 'ramda';
|
||||||
|
import utils from './utils';
|
||||||
|
const { prependClass, functor } = utils.default || utils;
|
||||||
|
|
||||||
|
const defaultOptions = {
|
||||||
|
left: undefined, // mouseX
|
||||||
|
top: undefined, // mouseY
|
||||||
|
offset: {left: 0, top: 0},
|
||||||
|
root: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function tooltip(d3, className = 'tooltip', options = {}) {
|
||||||
|
const {
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
offset,
|
||||||
|
root
|
||||||
|
} = {...defaultOptions, ...options};
|
||||||
|
|
||||||
|
let attrs = {'class': className};
|
||||||
|
let text = () => '';
|
||||||
|
let styles = {};
|
||||||
|
|
||||||
|
let el;
|
||||||
|
const anchor = root || d3.select('body');
|
||||||
|
const rootNode = anchor.node();
|
||||||
|
|
||||||
|
function tip(selection) {
|
||||||
|
selection.on({
|
||||||
|
'mouseover.tip': node => {
|
||||||
|
let [mouseX, mouseY] = d3.mouse(rootNode);
|
||||||
|
let [x, y] = [left || mouseX + offset.left, top || mouseY - offset.top];
|
||||||
|
|
||||||
|
anchor.selectAll(`div.${className}`).remove();
|
||||||
|
|
||||||
|
el = anchor.append('div')
|
||||||
|
.attr(prependClass(className)(attrs))
|
||||||
|
.style({
|
||||||
|
position: 'absolute',
|
||||||
|
'z-index': 1001,
|
||||||
|
left: x + 'px',
|
||||||
|
top: y + 'px',
|
||||||
|
...styles
|
||||||
|
})
|
||||||
|
.html(() => text(node));
|
||||||
|
},
|
||||||
|
|
||||||
|
'mousemove.tip': node => {
|
||||||
|
let [mouseX, mouseY] = d3.mouse(rootNode);
|
||||||
|
let [x, y] = [left || mouseX + offset.left, top || mouseY - offset.top];
|
||||||
|
|
||||||
|
el
|
||||||
|
.style({
|
||||||
|
left: x + 'px',
|
||||||
|
top: y + 'px'
|
||||||
|
})
|
||||||
|
.html(() => text(node));
|
||||||
|
},
|
||||||
|
|
||||||
|
'mouseout.tip': () => el.remove()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tip.attr = function setAttr(d) {
|
||||||
|
if (is(Object, d)) {
|
||||||
|
attrs = {...attrs, ...d};
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
tip.style = function setStyle(d) {
|
||||||
|
if (is(Object, d)) {
|
||||||
|
styles = {...styles, ...d};
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
tip.text = function setText(d) {
|
||||||
|
text = functor(d);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
return tip;
|
||||||
|
}
|
5
packages/d3tooltip/src/utils/functor.js
vendored
Normal file
5
packages/d3tooltip/src/utils/functor.js
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import { is } from 'ramda';
|
||||||
|
|
||||||
|
export default function functor(v) {
|
||||||
|
return is(Function, v) ? v : () => v;
|
||||||
|
}
|
7
packages/d3tooltip/src/utils/index.js
vendored
Normal file
7
packages/d3tooltip/src/utils/index.js
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import prependClass from './prependClass';
|
||||||
|
import functor from './functor';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
prependClass,
|
||||||
|
functor
|
||||||
|
};
|
20
packages/d3tooltip/src/utils/prependClass.js
vendored
Normal file
20
packages/d3tooltip/src/utils/prependClass.js
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { mapObjIndexed, join } from 'ramda';
|
||||||
|
import functor from './functor';
|
||||||
|
|
||||||
|
export default function prependClass(className) {
|
||||||
|
return mapObjIndexed((value, key) => {
|
||||||
|
if (key === 'class') {
|
||||||
|
const fn = functor(value);
|
||||||
|
|
||||||
|
return (d, i) => {
|
||||||
|
const classNames = fn(d, i);
|
||||||
|
if (classNames !== className) {
|
||||||
|
return join(' ', [className, classNames]);
|
||||||
|
}
|
||||||
|
return classNames;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
}
|
16
packages/d3tooltip/webpack.config.base.js
Normal file
16
packages/d3tooltip/webpack.config.base.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
module: {
|
||||||
|
loaders: [
|
||||||
|
{ test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
library: 'd3tooltip',
|
||||||
|
libraryTarget: 'umd'
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['', '.js']
|
||||||
|
}
|
||||||
|
};
|
14
packages/d3tooltip/webpack.config.development.js
Normal file
14
packages/d3tooltip/webpack.config.development.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var webpack = require('webpack');
|
||||||
|
var baseConfig = require('./webpack.config.base');
|
||||||
|
|
||||||
|
var config = Object.create(baseConfig);
|
||||||
|
config.plugins = [
|
||||||
|
new webpack.optimize.OccurenceOrderPlugin(),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': JSON.stringify('development')
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = config;
|
20
packages/d3tooltip/webpack.config.production.js
Normal file
20
packages/d3tooltip/webpack.config.production.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var webpack = require('webpack');
|
||||||
|
var baseConfig = require('./webpack.config.base');
|
||||||
|
|
||||||
|
var config = Object.create(baseConfig);
|
||||||
|
config.plugins = [
|
||||||
|
new webpack.optimize.OccurenceOrderPlugin(),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': JSON.stringify('production')
|
||||||
|
}),
|
||||||
|
new webpack.optimize.UglifyJsPlugin({
|
||||||
|
compressor: {
|
||||||
|
screw_ie8: true,
|
||||||
|
warnings: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = config;
|
Loading…
Reference in New Issue
Block a user