@shopify/polaris-viz
Advanced tools
Comparing version 0.0.11 to 0.0.12
# Changelog | ||
## [0.0.11] - 2020-07-27 | ||
### Added | ||
- `<GroupedBarChart />` component | ||
## [0.0.11] - 2020-07-08 | ||
@@ -4,0 +10,0 @@ |
435
index.es.js
@@ -1505,2 +1505,435 @@ import React, { useRef, useState, useEffect, useMemo, useLayoutEffect } from 'react'; | ||
export { BarChart, LineChart, NormalizedStackedBar, Sparkline }; | ||
var MIN_BAR_HEIGHT$1 = 5; | ||
var MARGIN$1 = { | ||
Top: 5, | ||
Right: 20, | ||
Bottom: 25, | ||
Left: 0 | ||
}; | ||
var LINE_HEIGHT$1 = 12; | ||
var TICK_SIZE$2 = 6; | ||
var MIN_Y_LABEL_SPACE$2 = 80; | ||
var SPACING_EXTRA_TIGHT$1 = 4; | ||
var SPACING_TIGHT$2 = 8; | ||
var SPACING$2 = 16; | ||
var SPACING_LOOSE = 20; | ||
var SMALL_WIDTH = 500; | ||
var FONT_SIZE$1 = 12; | ||
var SMALL_FONT_SIZE$1 = 10; | ||
var FULL_OPACITY = '100%'; | ||
var SUBDUED_OPACITY = '75%'; | ||
var DEFAULT_HEIGHT = 250; | ||
var BAR_SPACING = 0.5; | ||
function XAxis$2(_a) { | ||
var labels = _a.labels, | ||
xScale = _a.xScale, | ||
fontSize = _a.fontSize, | ||
showAlternateLabels = _a.showAlternateLabels, | ||
needsDiagonalLabels = _a.needsDiagonalLabels; | ||
var _b = xScale.range(), | ||
xScaleMin = _b[0], | ||
xScaleMax = _b[1]; | ||
var transform = needsDiagonalLabels ? "translate(" + SPACING_EXTRA_TIGHT$1 + " " + SPACING_LOOSE + ") rotate(-40)" : "translate(0 " + (SPACING_TIGHT$2 + SPACING$2) + ")"; | ||
return React.createElement(React.Fragment, null, React.createElement("path", { | ||
d: "M " + xScaleMin + " " + TICK_SIZE$2 + " v " + -TICK_SIZE$2 + " H " + xScaleMax + " v " + TICK_SIZE$2, | ||
fill: "none", | ||
stroke: colorSky | ||
}), labels.map(function (_a, index) { | ||
var value = _a.value, | ||
xOffset = _a.xOffset; | ||
if (showAlternateLabels && index % 2 !== 0) { | ||
return null; | ||
} | ||
return React.createElement("g", { | ||
key: index, | ||
transform: "translate(" + xOffset + ", 0)" | ||
}, React.createElement("line", { | ||
y2: TICK_SIZE$2, | ||
stroke: colorSky | ||
}), React.createElement("text", { | ||
fill: colorInkLighter, | ||
textAnchor: needsDiagonalLabels ? 'end' : 'middle', | ||
transform: transform, | ||
style: { | ||
fontSize: fontSize | ||
} | ||
}, value)); | ||
})); | ||
} | ||
function BarGroup(_a) { | ||
var x = _a.x, | ||
data = _a.data, | ||
yScale = _a.yScale, | ||
width = _a.width, | ||
colors = _a.colors, | ||
isActive = _a.isActive, | ||
hasActiveGroup = _a.hasActiveGroup; | ||
var baseOpacity = hasActiveGroup ? SUBDUED_OPACITY : FULL_OPACITY; | ||
var opacity = isActive ? FULL_OPACITY : baseOpacity; | ||
var animation = useSpring({ | ||
config: { | ||
duration: tokens.durationFast | ||
}, | ||
opacity: opacity, | ||
from: { | ||
opacity: baseOpacity | ||
} | ||
}); | ||
var barWidth = width / data.length - BAR_SPACING; | ||
return React.createElement(React.Fragment, null, data.map(function (value, index) { | ||
var rawHeight = Math.abs(yScale(value) - yScale(0)); | ||
var needsMinHeight = rawHeight < MIN_BAR_HEIGHT$1 && rawHeight !== 0; | ||
var height = needsMinHeight ? MIN_BAR_HEIGHT$1 : rawHeight; | ||
var modifiedYPosition = value > 0 ? yScale(0) - MIN_BAR_HEIGHT$1 : yScale(0); | ||
var yPosition = needsMinHeight ? modifiedYPosition : yScale(Math.max(0, value)); | ||
var xPosition = x + (barWidth + BAR_SPACING) * index; | ||
return React.createElement(animated.rect, { | ||
key: index, | ||
x: xPosition, | ||
y: yPosition, | ||
fill: tokens[colors[index]], | ||
opacity: animation.opacity, | ||
width: barWidth, | ||
height: height | ||
}); | ||
})); | ||
} | ||
var styles$b = { | ||
"Container": "PolarisViz-GroupedBarChart-Tooltip__Container", | ||
"Value": "PolarisViz-GroupedBarChart-Tooltip__Value", | ||
"ColorPreview": "PolarisViz-GroupedBarChart-Tooltip__ColorPreview" | ||
}; | ||
function Tooltip$2(_a) { | ||
var colors = _a.colors, | ||
labels = _a.labels, | ||
values = _a.values, | ||
formatValue = _a.formatValue; | ||
return React.createElement("div", { | ||
className: styles$b.Container | ||
}, colors.map(function (color, index) { | ||
return React.createElement(React.Fragment, { | ||
key: color | ||
}, React.createElement("div", { | ||
className: styles$b.ColorPreview, | ||
style: { | ||
background: tokens[color] | ||
} | ||
}), React.createElement("strong", null, labels[index]), React.createElement("div", { | ||
className: styles$b.Value | ||
}, formatValue(values[index]))); | ||
})); | ||
} | ||
var styles$c = { | ||
"Container": "PolarisViz-GroupedBarChart-Legend__Container", | ||
"ColorPreview": "PolarisViz-GroupedBarChart-Legend__ColorPreview", | ||
"InnerContainer": "PolarisViz-GroupedBarChart-Legend__InnerContainer", | ||
"Label": "PolarisViz-GroupedBarChart-Legend__Label" | ||
}; | ||
function Legend$1(_a) { | ||
var series = _a.series; | ||
return React.createElement("div", { | ||
className: styles$c.Container | ||
}, series.map(function (_a) { | ||
var label = _a.label, | ||
color = _a.color; | ||
return React.createElement("div", { | ||
key: label, | ||
className: styles$c.InnerContainer | ||
}, React.createElement("div", { | ||
className: styles$c.ColorPreview, | ||
style: { | ||
background: tokens[color] | ||
} | ||
}), React.createElement("div", { | ||
className: styles$c.Label | ||
}, label)); | ||
})); | ||
} | ||
function useXScale$2(_a) { | ||
var drawableWidth = _a.drawableWidth, | ||
data = _a.data, | ||
labels = _a.labels; | ||
var xScale = scaleBand().rangeRound([0, drawableWidth]).paddingInner(0.3).domain(data.map(function (_, index) { | ||
return index.toString(); | ||
})); | ||
var barWidthOffset = xScale.bandwidth() / 2; | ||
var xAxisLabels = useMemo(function () { | ||
return labels.map(function (label, index) { | ||
var barXPosition = xScale(index.toString()); | ||
var xOffset = barXPosition == null ? barWidthOffset : barWidthOffset + barXPosition; | ||
return { | ||
value: label, | ||
xOffset: xOffset | ||
}; | ||
}); | ||
}, [labels, xScale, barWidthOffset]); | ||
return { | ||
xScale: xScale, | ||
xAxisLabels: xAxisLabels | ||
}; | ||
} | ||
function useYScale$2(_a) { | ||
var drawableHeight = _a.drawableHeight, | ||
data = _a.data, | ||
formatYValue = _a.formatYValue; | ||
var _b = useMemo(function () { | ||
var vals = data.map(function (_a) { | ||
var data = _a.data; | ||
return data; | ||
}).reduce(function (acc, currentValue) { | ||
return acc.concat(currentValue); | ||
}, []); | ||
var min = Math.min.apply(Math, __spreadArrays(vals, [0])); | ||
var max = Math.max.apply(Math, vals); | ||
var maxTicks = Math.max(1, Math.floor(drawableHeight / MIN_Y_LABEL_SPACE$2)); | ||
var yScale = scaleLinear().range([drawableHeight, 0]).domain([min, max]).nice(maxTicks); | ||
var ticks = yScale.ticks(maxTicks).map(function (value) { | ||
return { | ||
value: value, | ||
formattedValue: formatYValue(value), | ||
yOffset: yScale(value) | ||
}; | ||
}); | ||
return { | ||
yScale: yScale, | ||
ticks: ticks | ||
}; | ||
}, [drawableHeight, data, formatYValue]), | ||
yScale = _b.yScale, | ||
ticks = _b.ticks; | ||
return { | ||
yScale: yScale, | ||
ticks: ticks | ||
}; | ||
} | ||
var styles$d = { | ||
"ChartContainer": "PolarisViz-Chart__ChartContainer" | ||
}; | ||
function Chart$2(_a) { | ||
var series = _a.series, | ||
chartDimensions = _a.chartDimensions, | ||
formatYValue = _a.formatYValue, | ||
labels = _a.labels, | ||
timeSeries = _a.timeSeries; | ||
var _b = useState(null), | ||
activeBarGroup = _b[0], | ||
setActiveBarGroup = _b[1]; | ||
var _c = useState(null), | ||
tooltipPosition = _c[0], | ||
setTooltipPosition = _c[1]; | ||
var yAxisLabelWidth = series.map(function (_a) { | ||
var data = _a.data; | ||
return data.map(function (value) { | ||
return getTextWidth({ | ||
text: formatYValue(value), | ||
fontSize: FONT_SIZE$1 | ||
}); | ||
}); | ||
}).reduce(function (acc, currentValue) { | ||
return acc.concat(currentValue); | ||
}, []).reduce(function (acc, currentValue) { | ||
return Math.max(acc, currentValue); | ||
}); | ||
var axisStartBuffer = SPACING$2; | ||
var axisMargin = axisStartBuffer + yAxisLabelWidth; | ||
var drawableWidth = chartDimensions.width - MARGIN$1.Right - axisMargin; | ||
var sortedData = labels.map(function (_, index) { | ||
return series.map(function (type) { | ||
return type.data[index]; | ||
}); | ||
}); | ||
var _d = useXScale$2({ | ||
drawableWidth: drawableWidth, | ||
data: sortedData, | ||
labels: labels | ||
}), | ||
xScale = _d.xScale, | ||
xAxisLabels = _d.xAxisLabels; | ||
var fontSize = drawableWidth < SMALL_WIDTH ? SMALL_FONT_SIZE$1 : FONT_SIZE$1; | ||
var longestLabel = Math.max.apply(Math, xAxisLabels.map(function (_a) { | ||
var value = _a.value; | ||
return getTextWidth({ | ||
text: value, | ||
fontSize: fontSize | ||
}); | ||
})); | ||
var overflowingLabel = longestLabel > xScale.bandwidth(); | ||
var xAxisLabelSpace = overflowingLabel ? longestLabel : LINE_HEIGHT$1; | ||
var drawableHeight = chartDimensions.height - MARGIN$1.Top - MARGIN$1.Bottom - xAxisLabelSpace; | ||
var _e = useYScale$2({ | ||
drawableHeight: drawableHeight, | ||
data: series, | ||
formatYValue: formatYValue | ||
}), | ||
yScale = _e.yScale, | ||
ticks = _e.ticks; | ||
var barColors = series.map(function (_a) { | ||
var color = _a.color; | ||
return color; | ||
}); | ||
var barGroupLabels = series.map(function (_a) { | ||
var label = _a.label; | ||
return label; | ||
}); | ||
return React.createElement("div", { | ||
className: styles$d.ChartContainer, | ||
style: { | ||
height: chartDimensions.height, | ||
width: chartDimensions.width | ||
} | ||
}, React.createElement("svg", { | ||
width: "100%", | ||
height: "100%", | ||
onMouseMove: handleInteraction, | ||
onTouchMove: handleInteraction, | ||
onMouseLeave: function onMouseLeave() { | ||
return setActiveBarGroup(null); | ||
}, | ||
onTouchEnd: function onTouchEnd() { | ||
return setActiveBarGroup(null); | ||
} | ||
}, React.createElement("g", { | ||
transform: "translate(" + axisMargin + "," + (chartDimensions.height - MARGIN$1.Bottom - xAxisLabelSpace) + ")" | ||
}, React.createElement(XAxis$2, { | ||
labels: xAxisLabels, | ||
xScale: xScale, | ||
needsDiagonalLabels: overflowingLabel, | ||
showAlternateLabels: timeSeries && overflowingLabel, | ||
fontSize: fontSize | ||
})), React.createElement("g", { | ||
transform: "translate(" + axisMargin + "," + MARGIN$1.Top + ")" | ||
}, React.createElement(YAxis, { | ||
ticks: ticks, | ||
drawableWidth: drawableWidth | ||
})), React.createElement("g", { | ||
transform: "translate(" + axisMargin + "," + MARGIN$1.Top + ")" | ||
}, sortedData.map(function (item, index) { | ||
var xPosition = xScale(index.toString()); | ||
return React.createElement(BarGroup, { | ||
key: index, | ||
x: xPosition == null ? 0 : xPosition, | ||
isActive: activeBarGroup === index, | ||
hasActiveGroup: activeBarGroup != null, | ||
yScale: yScale, | ||
data: item, | ||
width: xScale.bandwidth(), | ||
colors: barColors | ||
}); | ||
}))), tooltipPosition != null && activeBarGroup != null ? React.createElement(TooltipContainer, { | ||
activePointIndex: activeBarGroup, | ||
currentX: tooltipPosition.x, | ||
currentY: tooltipPosition.y, | ||
chartDimensions: chartDimensions, | ||
margin: MARGIN$1, | ||
position: "center" | ||
}, React.createElement(Tooltip$2, { | ||
colors: barColors, | ||
labels: barGroupLabels, | ||
values: sortedData[activeBarGroup], | ||
formatValue: formatYValue | ||
})) : null); | ||
function handleInteraction(event) { | ||
var point = eventPoint(event); | ||
if (point == null) { | ||
return; | ||
} | ||
var svgX = point.svgX, | ||
svgY = point.svgY; | ||
var currentPoint = svgX - axisMargin; | ||
var currentIndex = Math.floor(currentPoint / xScale.step()); | ||
if (currentIndex < 0 || currentIndex > sortedData.length - 1 || svgY <= MARGIN$1.Top || svgY > drawableHeight + MARGIN$1.Bottom + xAxisLabelSpace) { | ||
setActiveBarGroup(null); | ||
return; | ||
} | ||
var xPosition = xScale(currentIndex.toString()); | ||
var highestValue = Math.max.apply(Math, sortedData[currentIndex]); | ||
var tooltipXPositon = xPosition == null ? 0 : xPosition + axisMargin + xScale.bandwidth() / 2; | ||
setActiveBarGroup(currentIndex); | ||
setTooltipPosition({ | ||
x: tooltipXPositon, | ||
y: yScale(highestValue) | ||
}); | ||
} | ||
} | ||
function GroupedBarChart(_a) { | ||
var labels = _a.labels, | ||
series = _a.series, | ||
accessibilityLabel = _a.accessibilityLabel, | ||
_b = _a.timeSeries, | ||
timeSeries = _b === void 0 ? false : _b, | ||
_c = _a.chartHeight, | ||
chartHeight = _c === void 0 ? DEFAULT_HEIGHT : _c, | ||
_d = _a.formatYValue, | ||
formatYValue = _d === void 0 ? function (value) { | ||
return value.toString(); | ||
} : _d; | ||
var _e = useState(null), | ||
chartDimensions = _e[0], | ||
setChartDimensions = _e[1]; | ||
var containerRef = useRef(null); | ||
var updateDimensions = useDebouncedCallback(function () { | ||
if (containerRef.current != null) { | ||
setChartDimensions(containerRef.current.getBoundingClientRect()); | ||
} | ||
}, 100)[0]; | ||
useEffect(function () { | ||
if (containerRef.current != null) { | ||
updateDimensions(); | ||
} | ||
window.addEventListener('resize', updateDimensions); | ||
return function () { | ||
window.removeEventListener('resize', updateDimensions); | ||
}; | ||
}, [containerRef, updateDimensions]); | ||
return React.createElement("div", { | ||
"aria-label": accessibilityLabel, | ||
role: "img" | ||
}, React.createElement("div", { | ||
style: { | ||
height: chartHeight | ||
}, | ||
ref: containerRef | ||
}, chartDimensions == null ? null : React.createElement(Chart$2, { | ||
series: series, | ||
labels: labels, | ||
chartDimensions: chartDimensions, | ||
formatYValue: formatYValue, | ||
timeSeries: timeSeries | ||
})), React.createElement(Legend$1, { | ||
series: series | ||
})); | ||
} | ||
export { BarChart, GroupedBarChart, LineChart, NormalizedStackedBar, Sparkline }; |
434
index.js
@@ -1513,5 +1513,439 @@ 'use strict'; | ||
var MIN_BAR_HEIGHT$1 = 5; | ||
var MARGIN$1 = { | ||
Top: 5, | ||
Right: 20, | ||
Bottom: 25, | ||
Left: 0 | ||
}; | ||
var LINE_HEIGHT$1 = 12; | ||
var TICK_SIZE$2 = 6; | ||
var MIN_Y_LABEL_SPACE$2 = 80; | ||
var SPACING_EXTRA_TIGHT$1 = 4; | ||
var SPACING_TIGHT$2 = 8; | ||
var SPACING$2 = 16; | ||
var SPACING_LOOSE = 20; | ||
var SMALL_WIDTH = 500; | ||
var FONT_SIZE$1 = 12; | ||
var SMALL_FONT_SIZE$1 = 10; | ||
var FULL_OPACITY = '100%'; | ||
var SUBDUED_OPACITY = '75%'; | ||
var DEFAULT_HEIGHT = 250; | ||
var BAR_SPACING = 0.5; | ||
function XAxis$2(_a) { | ||
var labels = _a.labels, | ||
xScale = _a.xScale, | ||
fontSize = _a.fontSize, | ||
showAlternateLabels = _a.showAlternateLabels, | ||
needsDiagonalLabels = _a.needsDiagonalLabels; | ||
var _b = xScale.range(), | ||
xScaleMin = _b[0], | ||
xScaleMax = _b[1]; | ||
var transform = needsDiagonalLabels ? "translate(" + SPACING_EXTRA_TIGHT$1 + " " + SPACING_LOOSE + ") rotate(-40)" : "translate(0 " + (SPACING_TIGHT$2 + SPACING$2) + ")"; | ||
return React__default.createElement(React__default.Fragment, null, React__default.createElement("path", { | ||
d: "M " + xScaleMin + " " + TICK_SIZE$2 + " v " + -TICK_SIZE$2 + " H " + xScaleMax + " v " + TICK_SIZE$2, | ||
fill: "none", | ||
stroke: tokens.colorSky | ||
}), labels.map(function (_a, index) { | ||
var value = _a.value, | ||
xOffset = _a.xOffset; | ||
if (showAlternateLabels && index % 2 !== 0) { | ||
return null; | ||
} | ||
return React__default.createElement("g", { | ||
key: index, | ||
transform: "translate(" + xOffset + ", 0)" | ||
}, React__default.createElement("line", { | ||
y2: TICK_SIZE$2, | ||
stroke: tokens.colorSky | ||
}), React__default.createElement("text", { | ||
fill: tokens.colorInkLighter, | ||
textAnchor: needsDiagonalLabels ? 'end' : 'middle', | ||
transform: transform, | ||
style: { | ||
fontSize: fontSize | ||
} | ||
}, value)); | ||
})); | ||
} | ||
function BarGroup(_a) { | ||
var x = _a.x, | ||
data = _a.data, | ||
yScale = _a.yScale, | ||
width = _a.width, | ||
colors = _a.colors, | ||
isActive = _a.isActive, | ||
hasActiveGroup = _a.hasActiveGroup; | ||
var baseOpacity = hasActiveGroup ? SUBDUED_OPACITY : FULL_OPACITY; | ||
var opacity = isActive ? FULL_OPACITY : baseOpacity; | ||
var animation = reactSpring.useSpring({ | ||
config: { | ||
duration: tokens__default.durationFast | ||
}, | ||
opacity: opacity, | ||
from: { | ||
opacity: baseOpacity | ||
} | ||
}); | ||
var barWidth = width / data.length - BAR_SPACING; | ||
return React__default.createElement(React__default.Fragment, null, data.map(function (value, index) { | ||
var rawHeight = Math.abs(yScale(value) - yScale(0)); | ||
var needsMinHeight = rawHeight < MIN_BAR_HEIGHT$1 && rawHeight !== 0; | ||
var height = needsMinHeight ? MIN_BAR_HEIGHT$1 : rawHeight; | ||
var modifiedYPosition = value > 0 ? yScale(0) - MIN_BAR_HEIGHT$1 : yScale(0); | ||
var yPosition = needsMinHeight ? modifiedYPosition : yScale(Math.max(0, value)); | ||
var xPosition = x + (barWidth + BAR_SPACING) * index; | ||
return React__default.createElement(reactSpring.animated.rect, { | ||
key: index, | ||
x: xPosition, | ||
y: yPosition, | ||
fill: tokens__default[colors[index]], | ||
opacity: animation.opacity, | ||
width: barWidth, | ||
height: height | ||
}); | ||
})); | ||
} | ||
var styles$b = { | ||
"Container": "PolarisViz-GroupedBarChart-Tooltip__Container", | ||
"Value": "PolarisViz-GroupedBarChart-Tooltip__Value", | ||
"ColorPreview": "PolarisViz-GroupedBarChart-Tooltip__ColorPreview" | ||
}; | ||
function Tooltip$2(_a) { | ||
var colors = _a.colors, | ||
labels = _a.labels, | ||
values = _a.values, | ||
formatValue = _a.formatValue; | ||
return React__default.createElement("div", { | ||
className: styles$b.Container | ||
}, colors.map(function (color, index) { | ||
return React__default.createElement(React__default.Fragment, { | ||
key: color | ||
}, React__default.createElement("div", { | ||
className: styles$b.ColorPreview, | ||
style: { | ||
background: tokens__default[color] | ||
} | ||
}), React__default.createElement("strong", null, labels[index]), React__default.createElement("div", { | ||
className: styles$b.Value | ||
}, formatValue(values[index]))); | ||
})); | ||
} | ||
var styles$c = { | ||
"Container": "PolarisViz-GroupedBarChart-Legend__Container", | ||
"ColorPreview": "PolarisViz-GroupedBarChart-Legend__ColorPreview", | ||
"InnerContainer": "PolarisViz-GroupedBarChart-Legend__InnerContainer", | ||
"Label": "PolarisViz-GroupedBarChart-Legend__Label" | ||
}; | ||
function Legend$1(_a) { | ||
var series = _a.series; | ||
return React__default.createElement("div", { | ||
className: styles$c.Container | ||
}, series.map(function (_a) { | ||
var label = _a.label, | ||
color = _a.color; | ||
return React__default.createElement("div", { | ||
key: label, | ||
className: styles$c.InnerContainer | ||
}, React__default.createElement("div", { | ||
className: styles$c.ColorPreview, | ||
style: { | ||
background: tokens__default[color] | ||
} | ||
}), React__default.createElement("div", { | ||
className: styles$c.Label | ||
}, label)); | ||
})); | ||
} | ||
function useXScale$2(_a) { | ||
var drawableWidth = _a.drawableWidth, | ||
data = _a.data, | ||
labels = _a.labels; | ||
var xScale = d3Scale.scaleBand().rangeRound([0, drawableWidth]).paddingInner(0.3).domain(data.map(function (_, index) { | ||
return index.toString(); | ||
})); | ||
var barWidthOffset = xScale.bandwidth() / 2; | ||
var xAxisLabels = React.useMemo(function () { | ||
return labels.map(function (label, index) { | ||
var barXPosition = xScale(index.toString()); | ||
var xOffset = barXPosition == null ? barWidthOffset : barWidthOffset + barXPosition; | ||
return { | ||
value: label, | ||
xOffset: xOffset | ||
}; | ||
}); | ||
}, [labels, xScale, barWidthOffset]); | ||
return { | ||
xScale: xScale, | ||
xAxisLabels: xAxisLabels | ||
}; | ||
} | ||
function useYScale$2(_a) { | ||
var drawableHeight = _a.drawableHeight, | ||
data = _a.data, | ||
formatYValue = _a.formatYValue; | ||
var _b = React.useMemo(function () { | ||
var vals = data.map(function (_a) { | ||
var data = _a.data; | ||
return data; | ||
}).reduce(function (acc, currentValue) { | ||
return acc.concat(currentValue); | ||
}, []); | ||
var min = Math.min.apply(Math, __spreadArrays(vals, [0])); | ||
var max = Math.max.apply(Math, vals); | ||
var maxTicks = Math.max(1, Math.floor(drawableHeight / MIN_Y_LABEL_SPACE$2)); | ||
var yScale = d3Scale.scaleLinear().range([drawableHeight, 0]).domain([min, max]).nice(maxTicks); | ||
var ticks = yScale.ticks(maxTicks).map(function (value) { | ||
return { | ||
value: value, | ||
formattedValue: formatYValue(value), | ||
yOffset: yScale(value) | ||
}; | ||
}); | ||
return { | ||
yScale: yScale, | ||
ticks: ticks | ||
}; | ||
}, [drawableHeight, data, formatYValue]), | ||
yScale = _b.yScale, | ||
ticks = _b.ticks; | ||
return { | ||
yScale: yScale, | ||
ticks: ticks | ||
}; | ||
} | ||
var styles$d = { | ||
"ChartContainer": "PolarisViz-Chart__ChartContainer" | ||
}; | ||
function Chart$2(_a) { | ||
var series = _a.series, | ||
chartDimensions = _a.chartDimensions, | ||
formatYValue = _a.formatYValue, | ||
labels = _a.labels, | ||
timeSeries = _a.timeSeries; | ||
var _b = React.useState(null), | ||
activeBarGroup = _b[0], | ||
setActiveBarGroup = _b[1]; | ||
var _c = React.useState(null), | ||
tooltipPosition = _c[0], | ||
setTooltipPosition = _c[1]; | ||
var yAxisLabelWidth = series.map(function (_a) { | ||
var data = _a.data; | ||
return data.map(function (value) { | ||
return getTextWidth({ | ||
text: formatYValue(value), | ||
fontSize: FONT_SIZE$1 | ||
}); | ||
}); | ||
}).reduce(function (acc, currentValue) { | ||
return acc.concat(currentValue); | ||
}, []).reduce(function (acc, currentValue) { | ||
return Math.max(acc, currentValue); | ||
}); | ||
var axisStartBuffer = SPACING$2; | ||
var axisMargin = axisStartBuffer + yAxisLabelWidth; | ||
var drawableWidth = chartDimensions.width - MARGIN$1.Right - axisMargin; | ||
var sortedData = labels.map(function (_, index) { | ||
return series.map(function (type) { | ||
return type.data[index]; | ||
}); | ||
}); | ||
var _d = useXScale$2({ | ||
drawableWidth: drawableWidth, | ||
data: sortedData, | ||
labels: labels | ||
}), | ||
xScale = _d.xScale, | ||
xAxisLabels = _d.xAxisLabels; | ||
var fontSize = drawableWidth < SMALL_WIDTH ? SMALL_FONT_SIZE$1 : FONT_SIZE$1; | ||
var longestLabel = Math.max.apply(Math, xAxisLabels.map(function (_a) { | ||
var value = _a.value; | ||
return getTextWidth({ | ||
text: value, | ||
fontSize: fontSize | ||
}); | ||
})); | ||
var overflowingLabel = longestLabel > xScale.bandwidth(); | ||
var xAxisLabelSpace = overflowingLabel ? longestLabel : LINE_HEIGHT$1; | ||
var drawableHeight = chartDimensions.height - MARGIN$1.Top - MARGIN$1.Bottom - xAxisLabelSpace; | ||
var _e = useYScale$2({ | ||
drawableHeight: drawableHeight, | ||
data: series, | ||
formatYValue: formatYValue | ||
}), | ||
yScale = _e.yScale, | ||
ticks = _e.ticks; | ||
var barColors = series.map(function (_a) { | ||
var color = _a.color; | ||
return color; | ||
}); | ||
var barGroupLabels = series.map(function (_a) { | ||
var label = _a.label; | ||
return label; | ||
}); | ||
return React__default.createElement("div", { | ||
className: styles$d.ChartContainer, | ||
style: { | ||
height: chartDimensions.height, | ||
width: chartDimensions.width | ||
} | ||
}, React__default.createElement("svg", { | ||
width: "100%", | ||
height: "100%", | ||
onMouseMove: handleInteraction, | ||
onTouchMove: handleInteraction, | ||
onMouseLeave: function onMouseLeave() { | ||
return setActiveBarGroup(null); | ||
}, | ||
onTouchEnd: function onTouchEnd() { | ||
return setActiveBarGroup(null); | ||
} | ||
}, React__default.createElement("g", { | ||
transform: "translate(" + axisMargin + "," + (chartDimensions.height - MARGIN$1.Bottom - xAxisLabelSpace) + ")" | ||
}, React__default.createElement(XAxis$2, { | ||
labels: xAxisLabels, | ||
xScale: xScale, | ||
needsDiagonalLabels: overflowingLabel, | ||
showAlternateLabels: timeSeries && overflowingLabel, | ||
fontSize: fontSize | ||
})), React__default.createElement("g", { | ||
transform: "translate(" + axisMargin + "," + MARGIN$1.Top + ")" | ||
}, React__default.createElement(YAxis, { | ||
ticks: ticks, | ||
drawableWidth: drawableWidth | ||
})), React__default.createElement("g", { | ||
transform: "translate(" + axisMargin + "," + MARGIN$1.Top + ")" | ||
}, sortedData.map(function (item, index) { | ||
var xPosition = xScale(index.toString()); | ||
return React__default.createElement(BarGroup, { | ||
key: index, | ||
x: xPosition == null ? 0 : xPosition, | ||
isActive: activeBarGroup === index, | ||
hasActiveGroup: activeBarGroup != null, | ||
yScale: yScale, | ||
data: item, | ||
width: xScale.bandwidth(), | ||
colors: barColors | ||
}); | ||
}))), tooltipPosition != null && activeBarGroup != null ? React__default.createElement(TooltipContainer, { | ||
activePointIndex: activeBarGroup, | ||
currentX: tooltipPosition.x, | ||
currentY: tooltipPosition.y, | ||
chartDimensions: chartDimensions, | ||
margin: MARGIN$1, | ||
position: "center" | ||
}, React__default.createElement(Tooltip$2, { | ||
colors: barColors, | ||
labels: barGroupLabels, | ||
values: sortedData[activeBarGroup], | ||
formatValue: formatYValue | ||
})) : null); | ||
function handleInteraction(event) { | ||
var point = eventPoint(event); | ||
if (point == null) { | ||
return; | ||
} | ||
var svgX = point.svgX, | ||
svgY = point.svgY; | ||
var currentPoint = svgX - axisMargin; | ||
var currentIndex = Math.floor(currentPoint / xScale.step()); | ||
if (currentIndex < 0 || currentIndex > sortedData.length - 1 || svgY <= MARGIN$1.Top || svgY > drawableHeight + MARGIN$1.Bottom + xAxisLabelSpace) { | ||
setActiveBarGroup(null); | ||
return; | ||
} | ||
var xPosition = xScale(currentIndex.toString()); | ||
var highestValue = Math.max.apply(Math, sortedData[currentIndex]); | ||
var tooltipXPositon = xPosition == null ? 0 : xPosition + axisMargin + xScale.bandwidth() / 2; | ||
setActiveBarGroup(currentIndex); | ||
setTooltipPosition({ | ||
x: tooltipXPositon, | ||
y: yScale(highestValue) | ||
}); | ||
} | ||
} | ||
function GroupedBarChart(_a) { | ||
var labels = _a.labels, | ||
series = _a.series, | ||
accessibilityLabel = _a.accessibilityLabel, | ||
_b = _a.timeSeries, | ||
timeSeries = _b === void 0 ? false : _b, | ||
_c = _a.chartHeight, | ||
chartHeight = _c === void 0 ? DEFAULT_HEIGHT : _c, | ||
_d = _a.formatYValue, | ||
formatYValue = _d === void 0 ? function (value) { | ||
return value.toString(); | ||
} : _d; | ||
var _e = React.useState(null), | ||
chartDimensions = _e[0], | ||
setChartDimensions = _e[1]; | ||
var containerRef = React.useRef(null); | ||
var updateDimensions = useDebounce.useDebouncedCallback(function () { | ||
if (containerRef.current != null) { | ||
setChartDimensions(containerRef.current.getBoundingClientRect()); | ||
} | ||
}, 100)[0]; | ||
React.useEffect(function () { | ||
if (containerRef.current != null) { | ||
updateDimensions(); | ||
} | ||
window.addEventListener('resize', updateDimensions); | ||
return function () { | ||
window.removeEventListener('resize', updateDimensions); | ||
}; | ||
}, [containerRef, updateDimensions]); | ||
return React__default.createElement("div", { | ||
"aria-label": accessibilityLabel, | ||
role: "img" | ||
}, React__default.createElement("div", { | ||
style: { | ||
height: chartHeight | ||
}, | ||
ref: containerRef | ||
}, chartDimensions == null ? null : React__default.createElement(Chart$2, { | ||
series: series, | ||
labels: labels, | ||
chartDimensions: chartDimensions, | ||
formatYValue: formatYValue, | ||
timeSeries: timeSeries | ||
})), React__default.createElement(Legend$1, { | ||
series: series | ||
})); | ||
} | ||
exports.BarChart = BarChart; | ||
exports.GroupedBarChart = GroupedBarChart; | ||
exports.LineChart = LineChart; | ||
exports.NormalizedStackedBar = NormalizedStackedBar; | ||
exports.Sparkline = Sparkline; |
{ | ||
"name": "@shopify/polaris-viz", | ||
"description": "Shopify’s viz component library", | ||
"version": "0.0.11", | ||
"version": "0.0.12", | ||
"private": false, | ||
@@ -6,0 +6,0 @@ "license": "SEE LICENSE IN LICENSE.md", |
@@ -156,2 +156,27 @@ # Polaris Viz | ||
</tr> | ||
<tr> | ||
<td> | ||
Grouped bar chart | ||
<br /> | ||
<br /> | ||
<img src="https://github.com/Shopify/polaris-viz/raw/master/documentation/images/groupedbarchart.png"/> | ||
</td> | ||
<td> | ||
Shows comparison of different types, across categories. | ||
</td> | ||
<td> | ||
<ul> | ||
<li> | ||
<strong>series (required):</strong> | ||
<code>{data: number[]; color:</code> <a href="https://github.com/Shopify/polaris-viz/blob/master/src/types.ts#L1"><code>Color</code></a><code>; label: string;}[]</code> | ||
</li> | ||
<li><strong>labels (required):</strong><code>string[]</code></li> | ||
<li><strong>timeSeries: </strong><code>boolean</code></li> | ||
<li><strong>accessibilityLabel:</strong> <code>string</code></li> | ||
<li><strong>formatYValue:</strong><code>(value: number): string;</code></li> | ||
<li><strong>chartHeight:</strong> <code>number</code></li> | ||
</ul> | ||
</td> | ||
</tr> | ||
</tbody> | ||
@@ -158,0 +183,0 @@ </table> |
@@ -7,1 +7,2 @@ export { BarChart } from './BarChart'; | ||
export { TooltipContainer } from './TooltipContainer'; | ||
export { GroupedBarChart } from './GroupedBarChart'; |
@@ -1,1 +0,1 @@ | ||
export { BarChart, LineChart, NormalizedStackedBar, Sparkline, } from './components'; | ||
export { BarChart, LineChart, NormalizedStackedBar, Sparkline, GroupedBarChart, } from './components'; |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
226502
16416
200
4261
191