react-d3-utils
Advanced tools
Comparing version 0.3.0 to 0.4.0
# Changelog | ||
## [0.4.0](https://www.github.com/zakodium/react-d3-utils/compare/v0.3.0...v0.4.0) (2022-01-24) | ||
### Features | ||
* add 'none' option to AlignGroup ([#18](https://www.github.com/zakodium/react-d3-utils/issues/18)) ([0d7abad](https://www.github.com/zakodium/react-d3-utils/commit/0d7abade6780837feaf290519aa84229cb54a249)) | ||
* add useTimeTicks hook ([#19](https://www.github.com/zakodium/react-d3-utils/issues/19)) ([c71733c](https://www.github.com/zakodium/react-d3-utils/commit/c71733c1051fd407b42bc8ba205eaefd5e24133a)) | ||
## [0.3.0](https://www.github.com/zakodium/react-d3-utils/compare/v0.2.0...v0.3.0) (2021-03-26) | ||
@@ -4,0 +12,0 @@ |
import { ReactNode } from 'react'; | ||
export declare type Align = 'start' | 'middle' | 'end'; | ||
export declare type Align = 'start' | 'middle' | 'end' | 'none'; | ||
export interface AlignGroupProps { | ||
@@ -4,0 +4,0 @@ x?: number; |
import { jsx as _jsx } from "react/jsx-runtime"; | ||
import { useMemo } from 'react'; | ||
import { useBBoxObserver } from '../hooks/useBBoxObserver'; | ||
function calculatePosition(start, align, space) { | ||
function calculatePosition(start, align, space, value) { | ||
switch (align) { | ||
@@ -15,2 +15,5 @@ case 'start': { | ||
} | ||
case 'none': { | ||
return value; | ||
} | ||
default: { | ||
@@ -24,6 +27,6 @@ throw new Error(`Unkwnown alignment ${JSON.stringify(align)}`); | ||
const observed = useBBoxObserver(); | ||
const xPosition = useMemo(() => calculatePosition(x - observed.x, horizontalAlign, observed.width || 0), [x, horizontalAlign, observed.x, observed.width]); | ||
const yPosition = useMemo(() => calculatePosition(y - observed.y, verticalAlign, observed.height || 0), [y, verticalAlign, observed.y, observed.height]); | ||
return (_jsx("g", Object.assign({ ref: observed.ref, transform: `translate(${xPosition}, ${yPosition})` }, { children: children }), void 0)); | ||
const xPosition = useMemo(() => calculatePosition(x - observed.x, horizontalAlign, observed.width || 0, x), [x, observed.x, observed.width, horizontalAlign]); | ||
const yPosition = useMemo(() => calculatePosition(y - observed.y, verticalAlign, observed.height || 0, y), [y, observed.y, observed.height, verticalAlign]); | ||
return (_jsx("g", { ref: observed.ref, transform: `translate(${xPosition}, ${yPosition})`, children: children }, void 0)); | ||
} | ||
//# sourceMappingURL=AlignGroup.js.map |
@@ -6,3 +6,3 @@ import { jsx as _jsx } from "react/jsx-runtime"; | ||
const observed = useResizeObserver(); | ||
return (_jsx("div", Object.assign({ ref: observed.ref, style: { | ||
return (_jsx("div", { ref: observed.ref, style: { | ||
flex: 1, | ||
@@ -15,6 +15,6 @@ width: width || '100%', | ||
maxHeight: maxHeight, | ||
} }, { children: observed.width && observed.height | ||
}, children: observed.width && observed.height | ||
? children({ width: observed.width, height: observed.height }) | ||
: null }), void 0)); | ||
: null }, void 0)); | ||
} | ||
//# sourceMappingURL=ResponsiveChart.js.map |
@@ -1,60 +0,7 @@ | ||
import { useCallback, useEffect, useState } from 'react'; | ||
import { textDimensions } from '../utils'; | ||
const TEST_HEIGHT = '+1234567890'; | ||
import { useState } from 'react'; | ||
import { useTicks } from './useTick'; | ||
export function useLinearPrimaryTicks(scale, direction, ref, options = {}) { | ||
const [ticks, setTicks] = useState([]); | ||
const range = scale.range(); | ||
if (!range) | ||
throw new Error('Range needs to be specified'); | ||
const domain = scale.domain(); | ||
if (!domain) | ||
throw new Error('Domain needs to be specified'); | ||
const { minSpace = 8 } = options; | ||
const format = options === null || options === void 0 ? void 0 : options.tickFormat; | ||
const tickFormat = useCallback((x) => (format ? format(x) : String(x)), [format]); | ||
const axisLength = Math.abs(range[0] - range[1]); | ||
// Calculates the tick number that fits in the given space | ||
useEffect(() => { | ||
if (ref.current) { | ||
let tickNumber; | ||
let ticks = []; | ||
if (direction === 'horizontal') { | ||
while (true) { | ||
// get next ticks | ||
ticks = scale.ticks(tickNumber); | ||
const formatedTicks = ticks.map(tickFormat); | ||
tickNumber = Math.min(ticks.length, tickNumber || Infinity); | ||
// get the current tick space | ||
const { width } = textDimensions(formatedTicks.join(''), ref); | ||
const size = width + (ticks.length - 1) * minSpace; | ||
// repeats if the size is bigger than current space | ||
if (size > axisLength && tickNumber > 1) { | ||
tickNumber = tickNumber - 1; | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
setTicks(ticks); | ||
} | ||
else { | ||
const { height } = textDimensions(TEST_HEIGHT, ref); | ||
while (true) { | ||
// get next ticks | ||
ticks = scale.ticks(tickNumber); | ||
tickNumber = Math.min(ticks.length, tickNumber || Infinity); | ||
// get the current tick space | ||
const size = ticks.length * (height + minSpace) - minSpace; | ||
// repeats if the size is bigger than current space | ||
if (size > axisLength && tickNumber > 1) { | ||
tickNumber = tickNumber - 1; | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
setTicks(ticks); | ||
} | ||
} | ||
}, [axisLength, direction, minSpace, ref, scale, tickFormat]); | ||
const { tickFormat = String } = options; | ||
useTicks(scale, direction, ref, { ...options, tickFormat, setTicks }); | ||
return ticks.map((value) => ({ | ||
@@ -61,0 +8,0 @@ label: tickFormat(value), |
@@ -6,1 +6,2 @@ export * from './components/AlignGroup'; | ||
export * from './hooks/useLogTicks'; | ||
export * from './hooks/useTimeTicks'; |
@@ -6,2 +6,3 @@ export * from './components/AlignGroup'; | ||
export * from './hooks/useLogTicks'; | ||
export * from './hooks/useTimeTicks'; | ||
//# sourceMappingURL=index.js.map |
@@ -7,3 +7,3 @@ "use strict"; | ||
const useBBoxObserver_1 = require("../hooks/useBBoxObserver"); | ||
function calculatePosition(start, align, space) { | ||
function calculatePosition(start, align, space, value) { | ||
switch (align) { | ||
@@ -19,2 +19,5 @@ case 'start': { | ||
} | ||
case 'none': { | ||
return value; | ||
} | ||
default: { | ||
@@ -27,7 +30,7 @@ throw new Error(`Unkwnown alignment ${JSON.stringify(align)}`); | ||
const { x = 0, y = 0, verticalAlign = 'start', horizontalAlign = 'start', children, } = props; | ||
const observed = useBBoxObserver_1.useBBoxObserver(); | ||
const xPosition = react_1.useMemo(() => calculatePosition(x - observed.x, horizontalAlign, observed.width || 0), [x, horizontalAlign, observed.x, observed.width]); | ||
const yPosition = react_1.useMemo(() => calculatePosition(y - observed.y, verticalAlign, observed.height || 0), [y, verticalAlign, observed.y, observed.height]); | ||
return (jsx_runtime_1.jsx("g", Object.assign({ ref: observed.ref, transform: `translate(${xPosition}, ${yPosition})` }, { children: children }), void 0)); | ||
const observed = (0, useBBoxObserver_1.useBBoxObserver)(); | ||
const xPosition = (0, react_1.useMemo)(() => calculatePosition(x - observed.x, horizontalAlign, observed.width || 0, x), [x, observed.x, observed.width, horizontalAlign]); | ||
const yPosition = (0, react_1.useMemo)(() => calculatePosition(y - observed.y, verticalAlign, observed.height || 0, y), [y, observed.y, observed.height, verticalAlign]); | ||
return ((0, jsx_runtime_1.jsx)("g", { ref: observed.ref, transform: `translate(${xPosition}, ${yPosition})`, children: children }, void 0)); | ||
} | ||
exports.AlignGroup = AlignGroup; |
@@ -11,4 +11,4 @@ "use strict"; | ||
const { width, height, minWidth, minHeight, maxWidth, maxHeight, children, } = props; | ||
const observed = use_resize_observer_1.default(); | ||
return (jsx_runtime_1.jsx("div", Object.assign({ ref: observed.ref, style: { | ||
const observed = (0, use_resize_observer_1.default)(); | ||
return ((0, jsx_runtime_1.jsx)("div", { ref: observed.ref, style: { | ||
flex: 1, | ||
@@ -21,6 +21,6 @@ width: width || '100%', | ||
maxHeight: maxHeight, | ||
} }, { children: observed.width && observed.height | ||
}, children: observed.width && observed.height | ||
? children({ width: observed.width, height: observed.height }) | ||
: null }), void 0)); | ||
: null }, void 0)); | ||
} | ||
exports.ResponsiveChart = ResponsiveChart; |
@@ -8,9 +8,9 @@ "use strict"; | ||
// Actual current size of the observed element | ||
const [size, setSize] = react_1.useState(initialSize); | ||
const [size, setSize] = (0, react_1.useState)(initialSize); | ||
// Previous size to compare in the observer and avoid unnecessary rerenders. | ||
const previousSize = react_1.useRef(initialSize); | ||
const previousSize = (0, react_1.useRef)(initialSize); | ||
// Contains a function to cleanup the previous observer when the observed element changes. | ||
const cleanupPrevious = react_1.useRef(); | ||
const cleanupPrevious = (0, react_1.useRef)(); | ||
// Ref callback to do the observation. | ||
const ref = react_1.useCallback((element) => { | ||
const ref = (0, react_1.useCallback)((element) => { | ||
if (cleanupPrevious.current) { | ||
@@ -17,0 +17,0 @@ cleanupPrevious.current(); |
@@ -5,60 +5,7 @@ "use strict"; | ||
const react_1 = require("react"); | ||
const utils_1 = require("../utils"); | ||
const TEST_HEIGHT = '+1234567890'; | ||
const useTick_1 = require("./useTick"); | ||
function useLinearPrimaryTicks(scale, direction, ref, options = {}) { | ||
const [ticks, setTicks] = react_1.useState([]); | ||
const range = scale.range(); | ||
if (!range) | ||
throw new Error('Range needs to be specified'); | ||
const domain = scale.domain(); | ||
if (!domain) | ||
throw new Error('Domain needs to be specified'); | ||
const { minSpace = 8 } = options; | ||
const format = options === null || options === void 0 ? void 0 : options.tickFormat; | ||
const tickFormat = react_1.useCallback((x) => (format ? format(x) : String(x)), [format]); | ||
const axisLength = Math.abs(range[0] - range[1]); | ||
// Calculates the tick number that fits in the given space | ||
react_1.useEffect(() => { | ||
if (ref.current) { | ||
let tickNumber; | ||
let ticks = []; | ||
if (direction === 'horizontal') { | ||
while (true) { | ||
// get next ticks | ||
ticks = scale.ticks(tickNumber); | ||
const formatedTicks = ticks.map(tickFormat); | ||
tickNumber = Math.min(ticks.length, tickNumber || Infinity); | ||
// get the current tick space | ||
const { width } = utils_1.textDimensions(formatedTicks.join(''), ref); | ||
const size = width + (ticks.length - 1) * minSpace; | ||
// repeats if the size is bigger than current space | ||
if (size > axisLength && tickNumber > 1) { | ||
tickNumber = tickNumber - 1; | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
setTicks(ticks); | ||
} | ||
else { | ||
const { height } = utils_1.textDimensions(TEST_HEIGHT, ref); | ||
while (true) { | ||
// get next ticks | ||
ticks = scale.ticks(tickNumber); | ||
tickNumber = Math.min(ticks.length, tickNumber || Infinity); | ||
// get the current tick space | ||
const size = ticks.length * (height + minSpace) - minSpace; | ||
// repeats if the size is bigger than current space | ||
if (size > axisLength && tickNumber > 1) { | ||
tickNumber = tickNumber - 1; | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
setTicks(ticks); | ||
} | ||
} | ||
}, [axisLength, direction, minSpace, ref, scale, tickFormat]); | ||
const [ticks, setTicks] = (0, react_1.useState)([]); | ||
const { tickFormat = String } = options; | ||
(0, useTick_1.useTicks)(scale, direction, ref, { ...options, tickFormat, setTicks }); | ||
return ticks.map((value) => ({ | ||
@@ -65,0 +12,0 @@ label: tickFormat(value), |
@@ -28,3 +28,3 @@ "use strict"; | ||
function useLogTicks(scale, direction, ref, options = {}) { | ||
const [maxStrSize, setMaxStrSize] = react_1.useState(40); | ||
const [maxStrSize, setMaxStrSize] = (0, react_1.useState)(40); | ||
const range = scale.range(); | ||
@@ -38,6 +38,6 @@ if (!range) | ||
const format = options === null || options === void 0 ? void 0 : options.tickFormat; | ||
const tickFormat = react_1.useCallback((x) => (format ? format(x) : String(x)), [format]); | ||
const ticks = react_1.useMemo(() => scale.ticks(), [scale]); | ||
const tickFormat = (0, react_1.useCallback)((x) => (format ? format(x) : String(x)), [format]); | ||
const ticks = (0, react_1.useMemo)(() => scale.ticks(), [scale]); | ||
// Calculates the word density | ||
react_1.useEffect(() => { | ||
(0, react_1.useEffect)(() => { | ||
if (ref.current) { | ||
@@ -49,7 +49,7 @@ if (direction === 'horizontal') { | ||
.reduce((acc, curr) => (acc.length < curr.length ? curr : acc), ''); | ||
const { width } = utils_1.textDimensions(maxLenWord, ref); | ||
const { width } = (0, utils_1.textDimensions)(maxLenWord, ref); | ||
setMaxStrSize(Math.ceil(width)); | ||
} | ||
else { | ||
const { height } = utils_1.textDimensions(TEST_HEIGHT, ref); | ||
const { height } = (0, utils_1.textDimensions)(TEST_HEIGHT, ref); | ||
setMaxStrSize(Math.ceil(height)); | ||
@@ -56,0 +56,0 @@ } |
@@ -18,1 +18,2 @@ "use strict"; | ||
__exportStar(require("./hooks/useLogTicks"), exports); | ||
__exportStar(require("./hooks/useTimeTicks"), exports); |
{ | ||
"name": "react-d3-utils", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "Low-level utilities to build charts with React and D3", | ||
@@ -37,23 +37,23 @@ "main": "lib/index.js", | ||
"devDependencies": { | ||
"@babel/core": "^7.12.13", | ||
"@simbathesailor/use-what-changed": "^1.0.0", | ||
"@storybook/addon-actions": "^6.1.17", | ||
"@storybook/addon-essentials": "^6.1.17", | ||
"@storybook/addon-links": "^6.1.17", | ||
"@storybook/addon-storysource": "^6.1.17", | ||
"@storybook/react": "^6.1.17", | ||
"@types/react": "^17.0.1", | ||
"@zakodium/eslint-config": "^3.0.0", | ||
"babel-loader": "^8.2.2", | ||
"eslint": "^7.19.0", | ||
"prettier": "^2.2.1", | ||
"react": "^17.0.1", | ||
"react-dom": "^17.0.1", | ||
"typescript": "^4.1.3" | ||
"@babel/core": "^7.16.10", | ||
"@simbathesailor/use-what-changed": "^2.0.0", | ||
"@storybook/addon-actions": "^6.4.14", | ||
"@storybook/addon-essentials": "^6.4.14", | ||
"@storybook/addon-links": "^6.4.14", | ||
"@storybook/addon-storysource": "^6.4.14", | ||
"@storybook/react": "^6.4.14", | ||
"@types/react": "^17.0.38", | ||
"@zakodium/eslint-config": "^5.1.0", | ||
"babel-loader": "^8.2.3", | ||
"eslint": "^8.7.0", | ||
"prettier": "^2.5.1", | ||
"react": "^17.0.2", | ||
"react-dom": "^17.0.2", | ||
"typescript": "^4.5.5" | ||
}, | ||
"dependencies": { | ||
"@types/d3-scale": "^3.2.2", | ||
"d3-scale": "^3.2.3", | ||
"use-resize-observer": "7.0.0" | ||
"@types/d3-scale": "^4.0.2", | ||
"d3-scale": "^4.0.2", | ||
"use-resize-observer": "8.0.0" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
42286
40
629
+ Added@juggle/resize-observer@3.4.0(transitive)
+ Added@types/d3-scale@4.0.9(transitive)
+ Added@types/d3-time@3.0.4(transitive)
+ Addedd3-array@3.2.4(transitive)
+ Addedd3-color@3.1.0(transitive)
+ Addedd3-format@3.1.0(transitive)
+ Addedd3-interpolate@3.0.1(transitive)
+ Addedd3-scale@4.0.2(transitive)
+ Addedd3-time@3.1.0(transitive)
+ Addedd3-time-format@4.1.0(transitive)
+ Addedinternmap@2.0.3(transitive)
+ Addeduse-resize-observer@8.0.0(transitive)
- Removed@types/d3-scale@3.3.5(transitive)
- Removed@types/d3-time@2.1.4(transitive)
- Removedd3-array@2.12.1(transitive)
- Removedd3-color@2.0.0(transitive)
- Removedd3-format@2.0.0(transitive)
- Removedd3-interpolate@2.0.1(transitive)
- Removedd3-scale@3.3.0(transitive)
- Removedd3-time@2.1.1(transitive)
- Removedd3-time-format@3.0.0(transitive)
- Removedinternmap@1.0.1(transitive)
- Removedresize-observer-polyfill@1.5.1(transitive)
- Removeduse-resize-observer@7.0.0(transitive)
Updated@types/d3-scale@^4.0.2
Updatedd3-scale@^4.0.2
Updateduse-resize-observer@8.0.0