Skip to content

Commit

Permalink
feat(marimekko): add support for patterns and gradients
Browse files Browse the repository at this point in the history
  • Loading branch information
plouc committed Nov 16, 2020
1 parent 604b523 commit d75a395
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 66 deletions.
2 changes: 1 addition & 1 deletion packages/marimekko/src/Bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const Bar = <RawDatum,>({
y={animatedProps.y}
width={to(animatedProps.width, value => Math.max(value, 0))}
height={to(animatedProps.height, value => Math.max(value, 0))}
fill={animatedProps.color}
fill={bar.fill ?? animatedProps.color}
stroke={animatedProps.borderColor}
strokeWidth={bar.borderWidth}
onClick={isInteractive ? handleClick : undefined}
Expand Down
18 changes: 16 additions & 2 deletions packages/marimekko/src/Marimekko.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import React, { createElement, Fragment, ReactNode } from 'react'
import { Container, SvgWrapper, useDimensions } from '@nivo/core'
import {
// @ts-ignore
bindDefs,
Container,
SvgWrapper,
useDimensions,
} from '@nivo/core'
import { Grid, Axes } from '@nivo/axes'
import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors'
import { SvgProps, LayerId, DimensionDatum } from './types'
Expand All @@ -18,6 +24,8 @@ const InnerMarimekko = <RawDatum,>({
margin: partialMargin,
layout = defaultProps.layout,
offset = defaultProps.offset,
outerPadding = defaultProps.outerPadding,
innerPadding = defaultProps.innerPadding,
layers = defaultProps.layers,
axisTop,
axisRight,
Expand All @@ -30,6 +38,8 @@ const InnerMarimekko = <RawDatum,>({
colors = defaultProps.colors as OrdinalColorScaleConfig<
Omit<DimensionDatum<RawDatum>, 'color'>
>,
defs = [],
fill = [],
borderWidth = defaultProps.borderWidth,
borderColor = defaultProps.borderColor as InheritedColorConfig<DimensionDatum<RawDatum>>,
isInteractive = defaultProps.isInteractive,
Expand All @@ -53,6 +63,8 @@ const InnerMarimekko = <RawDatum,>({
dimensions,
layout,
offset,
outerPadding,
innerPadding,
colors,
borderColor,
borderWidth,
Expand All @@ -67,6 +79,8 @@ const InnerMarimekko = <RawDatum,>({
legends: null,
}

const boundDefs = bindDefs(defs, bars, fill)

if (layers.includes('bars')) {
layerById.bars = (
<Bars<RawDatum>
Expand Down Expand Up @@ -127,7 +141,7 @@ const InnerMarimekko = <RawDatum,>({
width={outerWidth}
height={outerHeight}
margin={margin}
// defs={boundDefs}
defs={boundDefs}
role={role}
>
{layers.map((layer, i) => {
Expand Down
49 changes: 39 additions & 10 deletions packages/marimekko/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,20 +119,32 @@ export const useNormalizedData = <RawDatum>(
}, [data, getId, getValue])
}

export const useThicknessScale = <RawDatum>(
data: NormalizedDatum<RawDatum>[],
width: number,
height: number,
export const useThicknessScale = <RawDatum>({
data,
width,
height,
layout,
outerPadding,
innerPadding,
}: {
data: NormalizedDatum<RawDatum>[]
width: number
height: number
layout: Layout
) =>
outerPadding: number
innerPadding: number
}) =>
useMemo(() => {
const totalValue = data.reduce((acc, datum) => acc + datum.value, 0)

const thicknessScale = scaleLinear().domain([0, totalValue])

const totalPadding = 2 * outerPadding + (data.length - 1) * innerPadding

if (layout === 'vertical') {
thicknessScale.range([0, width])
thicknessScale.range([0, width - totalPadding])
} else {
thicknessScale.range([0, height])
thicknessScale.range([0, height - totalPadding])
}

return thicknessScale
Expand All @@ -146,6 +158,8 @@ export const useComputedData = <RawDatum>({
dimensionsScale,
colors,
layout,
outerPadding,
innerPadding,
}: {
data: NormalizedDatum<RawDatum>[]
stacked: Series<RawDatum, string>[]
Expand All @@ -154,12 +168,14 @@ export const useComputedData = <RawDatum>({
dimensionsScale: ScaleLinear<number, number>
colors: CommonProps<RawDatum>['colors']
layout: Layout
outerPadding: number
innerPadding: number
}) => {
const getColor = useOrdinalColorScale<Omit<DimensionDatum<RawDatum>, 'color'>>(colors, 'id')

const computedData: ComputedDatum<RawDatum>[] = []

let position = 0
let position = outerPadding

data.forEach(datum => {
const thickness = thicknessScale(datum.value)
Expand All @@ -172,7 +188,7 @@ export const useComputedData = <RawDatum>({
dimensions: [],
}

position += thickness
position += thickness + innerPadding

dimensionIds.forEach(dimensionId => {
const dimension = stacked.find(stack => stack.key === dimensionId)
Expand Down Expand Up @@ -248,6 +264,8 @@ export const useMarimekko = <RawDatum>({
dimensions: rawDimensions,
layout,
offset,
outerPadding,
innerPadding,
colors,
borderColor,
borderWidth,
Expand All @@ -260,6 +278,8 @@ export const useMarimekko = <RawDatum>({
dimensions: DataProps<RawDatum>['dimensions']
layout: Layout
offset: OffsetId
outerPadding: number
innerPadding: number
colors: CommonProps<RawDatum>['colors']
borderColor: InheritedColorConfig<DimensionDatum<RawDatum>>
borderWidth: number
Expand All @@ -270,7 +290,14 @@ export const useMarimekko = <RawDatum>({
const stack = useStack<RawDatum>(dimensionIds, dimensions, offset)
const { stacked, min, max } = useStackedData<RawDatum>(stack, data)
const normalizedData = useNormalizedData<RawDatum>(data, id, value)
const thicknessScale = useThicknessScale(normalizedData, width, height, layout)
const thicknessScale = useThicknessScale({
data: normalizedData,
width,
height,
layout,
outerPadding,
innerPadding,
})
const dimensionsScale = useDimensionsScale(min, max, width, height, layout)
const computedData = useComputedData<RawDatum>({
data: normalizedData,
Expand All @@ -280,6 +307,8 @@ export const useMarimekko = <RawDatum>({
dimensionsScale,
colors,
layout,
outerPadding,
innerPadding,
})
const bars = useBars<RawDatum>(computedData, borderColor, borderWidth)

Expand Down
6 changes: 2 additions & 4 deletions packages/marimekko/src/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ import { LayerId, Layout, OffsetId } from './types'
export const defaultProps = {
layout: 'vertical' as Layout,
offset: 'none' as OffsetId,
outerPadding: 0,
innerPadding: 3,

layers: ['grid', 'axes', 'bars', 'legends'] as LayerId[],

//axisTop: any,
//axisRight: any,
//axisBottom: any,
//axisLeft: any,
enableGridX: false,
enableGridY: true,

Expand Down
14 changes: 4 additions & 10 deletions packages/marimekko/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export interface ComputedDatum<RawDatum> extends NormalizedDatum<RawDatum> {

export interface BarDatum<RawDatum> extends DimensionDatum<RawDatum> {
key: string
fill?: string
borderColor: string
borderWidth: number
}
Expand Down Expand Up @@ -106,6 +107,8 @@ export type CommonProps<RawDatum> = {
margin: Box
layout: Layout
offset: OffsetId
outerPadding: number
innerPadding: number

// axes and grid
axisTop?: AxisProps
Expand Down Expand Up @@ -155,16 +158,7 @@ export type SvgProps<RawDatum> = DataProps<RawDatum> &
Dimensions &
Partial<CommonProps<RawDatum>> &
ModernMotionProps &
SvgDefsAndFill<ComputedDatum<RawDatum>> &
SvgDefsAndFill<BarDatum<RawDatum>> &
MouseEventHandlers<RawDatum, SVGRectElement> & {
layers?: Layer<RawDatum>[]
}

export type CompleteSvgProps<RawDatum> = DataProps<RawDatum> &
Dimensions &
CommonProps<RawDatum> &
ModernMotionProps &
SvgDefsAndFill<ComputedDatum<RawDatum>> &
MouseEventHandlers<RawDatum, SVGRectElement> & {
layers: Layer<RawDatum>[]
}
1 change: 0 additions & 1 deletion packages/pie/src/Pie.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ const Pie = <RawDatum, >({
height={outerHeight}
margin={margin}
defs={boundDefs}
theme={theme}
role={role}
>
{layers.map((layer, i) => {
Expand Down
37 changes: 8 additions & 29 deletions website/src/data/components/marimekko/mapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,44 +47,23 @@ export default settingsMapper(
defs: (value, values) => {
if (!values['showcase pattern usage']) return

/*
[
patternDotsDef('dots', {
background: 'inherit',
color: 'rgba(255, 255, 255, 0.3)',
size: 4,
padding: 1,
stagger: true,
}),
return [
patternLinesDef('lines', {
background: 'inherit',
color: 'rgba(255, 255, 255, 0.3)',
background: 'rgba(0, 0, 0, 0)',
color: 'inherit',
rotation: -45,
lineWidth: 6,
spacing: 10,
lineWidth: 4,
spacing: 8,
}),
]
*/

return
},
fill: (value, values) => {
if (!values['showcase pattern usage']) return

/*
[
{ match: { id: 'ruby' }, id: 'dots' },
{ match: { id: 'c' }, id: 'dots' },
{ match: { id: 'go' }, id: 'dots' },
{ match: { id: 'python' }, id: 'dots' },
{ match: { id: 'scala' }, id: 'lines' },
{ match: { id: 'lisp' }, id: 'lines' },
{ match: { id: 'elixir' }, id: 'lines' },
{ match: { id: 'javascript' }, id: 'lines' },
return [
{ match: { id: 'agree strongly' }, id: 'lines' },
{ match: { id: 'disagree strongly' }, id: 'lines' },
]
*/

return
},
},
{
Expand Down
28 changes: 28 additions & 0 deletions website/src/data/components/marimekko/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,34 @@ const props = [
})),
},
},
{
key: 'outerPadding',
help: 'Space before the first bar and after the last one.',
type: 'number',
required: false,
defaultValue: defaults.outerPadding,
controlType: 'range',
group: 'Base',
controlOptions: {
min: 0,
max: 20,
unit: 'px',
},
},
{
key: 'innerPadding',
help: 'Space between bars.',
type: 'number',
required: false,
defaultValue: defaults.innerPadding,
controlType: 'range',
group: 'Base',
controlOptions: {
min: 0,
max: 20,
unit: 'px',
},
},
{
key: 'width',
enableControlForFlavors: ['api'],
Expand Down
20 changes: 11 additions & 9 deletions website/src/pages/marimekko/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,26 @@ const initialProperties = {
value: 'participation',
dimensions: [
{
id: 'agree strongly',
value: 'stronglyAgree',
},
{
id: 'agree',
value: 'agree',
id: 'disagree strongly',
value: 'stronglyDisagree',
},
{
id: 'disagree',
value: 'disagree',
},
{
id: 'disagree strongly',
value: 'stronglyDisagree',
id: 'agree',
value: 'agree',
},
{
id: 'agree strongly',
value: 'stronglyAgree',
},
],
layout: defaultProps.layout,
offset: defaultProps.offset,
outerPadding: defaultProps.outerPadding,
innerPadding: 9,

axisTop: {
enable: false,
Expand Down Expand Up @@ -92,7 +94,7 @@ const initialProperties = {

valueFormat: { format: '', enabled: false },

colors: { scheme: 'nivo' },
colors: ['#ac402f', '#F47560', '#97E3D5', '#58b0a0'],

borderWidth: 1,
borderColor: {
Expand Down

0 comments on commit d75a395

Please sign in to comment.