-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #52 from redbearsam/feature/fix-horizontal-groups
Use a custom (fixed) version of the seriesSvgGrouped component
- Loading branch information
Showing
3 changed files
with
136 additions
and
1 deletion.
There are no files selected for viewing
77 changes: 77 additions & 0 deletions
77
packages/perspective-viewer-d3fc/src/js/d3fc/series/groupedBase.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import {scaleLinear, scaleBand} from "d3"; | ||
import {range} from "d3"; | ||
import {rebindAll, includeMap} from "@d3fc/d3fc-rebind"; | ||
|
||
const functor = d => (typeof d === "function" ? d : () => d); | ||
|
||
const alignOffset = (align, width) => { | ||
switch (align) { | ||
case "left": | ||
return width / 2; | ||
case "right": | ||
return -width / 2; | ||
default: | ||
return 0; | ||
} | ||
}; | ||
|
||
const createBase = initialValues => { | ||
const env = Object.assign({}, initialValues); | ||
const base = () => {}; | ||
|
||
Object.keys(env).forEach(key => { | ||
base[key] = (...args) => { | ||
if (!args.length) { | ||
return env[key]; | ||
} | ||
env[key] = args[0]; | ||
return base; | ||
}; | ||
}); | ||
|
||
return base; | ||
}; | ||
|
||
export default () => { | ||
let bandwidth = () => 50; | ||
let align = "center"; | ||
|
||
// the offset scale is used to offset each of the series within a group | ||
const offsetScale = scaleBand(); | ||
|
||
const grouped = createBase({ | ||
decorate: () => {}, | ||
xScale: scaleLinear(), | ||
yScale: scaleLinear() | ||
}); | ||
|
||
// the bandwidth for the grouped series can be a function of datum / index. As a result | ||
// the offset scale required to cluster the 'sub' series is also dependent on datum / index. | ||
// This function computes the offset scale for a specific datum / index of the grouped series | ||
grouped.offsetScaleForDatum = (data, d, i) => { | ||
const width = bandwidth(d, i); | ||
const offset = alignOffset(align, width); | ||
|
||
const halfWidth = width / 2; | ||
return offsetScale.domain(range(0, data.length)).range([-halfWidth + offset, halfWidth + offset]); | ||
}; | ||
|
||
grouped.bandwidth = (...args) => { | ||
if (!args.length) { | ||
return bandwidth; | ||
} | ||
bandwidth = functor(args[0]); | ||
return grouped; | ||
}; | ||
grouped.align = (...args) => { | ||
if (!args.length) { | ||
return align; | ||
} | ||
align = args[0]; | ||
return grouped; | ||
}; | ||
|
||
rebindAll(grouped, offsetScale, includeMap({paddingInner: "paddingOuter"})); | ||
|
||
return grouped; | ||
}; |
57 changes: 57 additions & 0 deletions
57
packages/perspective-viewer-d3fc/src/js/d3fc/series/svg/grouped.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import {dataJoin} from "@d3fc/d3fc-data-join"; | ||
import {select} from "d3"; | ||
import {rebindAll, exclude} from "@d3fc/d3fc-rebind"; | ||
import groupedBase from "../groupedBase"; | ||
|
||
export default series => { | ||
const base = groupedBase(series); | ||
|
||
const join = dataJoin("g", "grouped"); | ||
|
||
const grouped = selection => { | ||
if (selection.selection) { | ||
join.transition(selection); | ||
} | ||
|
||
selection.each((data, index, group) => { | ||
const g = join(select(group[index]), data); | ||
|
||
g.enter().append("g"); | ||
|
||
g.select("g").each((_, index, group) => { | ||
const container = select(group[index]); | ||
|
||
// create a composite scale that applies the required offset | ||
const isVertical = series.orient() !== "horizontal"; | ||
const compositeScale = (d, i) => { | ||
const offset = base.offsetScaleForDatum(data, d, i); | ||
const baseScale = isVertical ? base.xScale() : base.yScale(); | ||
return baseScale(d) + offset(index) + offset.bandwidth() / 2; | ||
}; | ||
|
||
if (isVertical) { | ||
series.xScale(compositeScale); | ||
series.yScale(base.yScale()); | ||
} else { | ||
series.yScale(compositeScale); | ||
series.xScale(base.xScale()); | ||
} | ||
|
||
// if the sub-series has a bandwidth, set this from the offset scale | ||
if (series.bandwidth) { | ||
series.bandwidth((d, i) => base.offsetScaleForDatum(data, d, i).bandwidth()); | ||
} | ||
|
||
// adapt the decorate function to give each series the correct index | ||
series.decorate((s, d) => base.decorate()(s, d, index)); | ||
|
||
container.call(series); | ||
}); | ||
}); | ||
}; | ||
|
||
rebindAll(grouped, series, exclude("decorate", "xScale", "yScale")); | ||
rebindAll(grouped, base, exclude("offsetScaleForDatum")); | ||
|
||
return grouped; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters