Skip to content

Commit

Permalink
fix(annotations): fix alignment at the edges
Browse files Browse the repository at this point in the history
This commit fixed the alignment of rect and line annotations near the edge of a data domain. It
aligns the x/y position specified by the dataValues of the annotation to the domain of the chart.

BREAKING CHANGE: In the rectangular annotation, the `y0` parameter of the coordinates now refers to
the minimum value and the `y1` value refers to the maximum value of the y domain. Previously, this
was the opposite.

fix #586
  • Loading branch information
markov00 committed Apr 24, 2020
1 parent cafcb9c commit 053f169
Show file tree
Hide file tree
Showing 15 changed files with 845 additions and 153 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ test/failure-screenshots/**/*.png

reports/
tmp/
.temp/
dist/
coverage/
.out/
Expand Down
3 changes: 3 additions & 0 deletions .playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
height: 300px;
margin: 20px;
}
label {
display: block;
}
</style>
</head>
<body>
Expand Down
258 changes: 225 additions & 33 deletions .playground/playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,235 @@
* under the License. */

import React from 'react';
import { Chart, Partition, Settings, PartitionLayout, XYChartElementEvent, PartitionElementEvent } from '../src';
import {
Chart,
ScaleType,
Settings,
RectAnnotation,
LineAnnotation,
TooltipType,
BarSeries,
LineSeries,
Axis,
Position,
} from '../src';

export class Playground extends React.Component {
onElementClick = (elements: (XYChartElementEvent | PartitionElementEvent)[]) => {
// eslint-disable-next-line no-console
console.log(elements);
// const data = [
// { x: 0, min: 0, max: 1 },
// { x: 10, min: 0, max: 2 },
// // { x: 2, min: 0, max: 3 },
// ];

const data = new Array(11).fill(0).map((d, i) => {
return {
x: i,
max: Math.random() * 10,
};
});
interface State {
showRectAnnotation: boolean;
showLineXAnnotation: boolean;
showLineYAnnotation: boolean;
totalBars: number;
useLinearBar: boolean;
useOrdinalBar: boolean;
useHistogramBar: boolean;
totalLines: number;
useLinearLine: boolean;
useOrdinalLine: boolean;
}
export class Playground extends React.Component<{}, State> {
state: State = {
showRectAnnotation: false,
showLineXAnnotation: false,
showLineYAnnotation: false,
totalBars: 1,
totalLines: 1,
useLinearBar: true,
useOrdinalBar: false,
useHistogramBar: false,
useLinearLine: false,
useOrdinalLine: false,
};
handleInputChange = (stateParam: keyof State) => (event: React.ChangeEvent<HTMLInputElement>) => {
const updatedValue = stateParam === 'totalBars' || stateParam === 'totalLines' ? Number(event.target.value) : 1;
this.setState((prevState: State) => {
return {
...prevState,
[stateParam]: stateParam === 'totalBars' || stateParam === 'totalLines' ? updatedValue : !prevState[stateParam],
};
});
};
render() {
const keys: Array<keyof State> = [
'showRectAnnotation',
'showLineXAnnotation',
'showLineYAnnotation',
'useLinearBar',
'useOrdinalBar',
'useHistogramBar',
'useLinearLine',
'useOrdinalLine',
'totalBars',
'totalLines',
];
return (
<div className="chart">
<Chart>
<Settings onElementClick={this.onElementClick} />
<Partition
id="111"
config={{
partitionLayout: PartitionLayout.treemap,
}}
valueAccessor={(d: { v: number }) => {
return d.v;
}}
data={[
{ g1: 'a', g2: 'a', v: 1 },
{ g1: 'a', g2: 'b', v: 1 },
{ g1: 'b', g2: 'a', v: 1 },
{ g1: 'b', g2: 'b', v: 1 },
]}
layers={[
{
groupByRollup: (datum: { g1: string }) => datum.g1,
},
{
groupByRollup: (datum: { g2: string }) => datum.g2,
},
]}
/>
</Chart>
</div>
<>
<div>
<form>
{keys.map((key) => {
return (
<label key={key}>
{key}
{key === 'totalBars' || key === 'totalLines' ? (
<input type="number" value={this.state[key]} onChange={this.handleInputChange(key)} />
) : (
<input type="checkbox" checked={this.state[key]} onChange={this.handleInputChange(key)} />
)}
</label>
);
})}
</form>
</div>
<div className="chart">
<Chart>
<Settings
tooltip={TooltipType.None}
theme={{
lineSeriesStyle: {
point: {
visible: true,
fill: 'transparent',
},
},
barSeriesStyle: {
rect: {
opacity: 0.5,
},
},
scales: { barsPadding: 0, histogramPadding: 0 },
chartPaddings: { bottom: 0, left: 0, top: 0, right: 0 },
chartMargins: { bottom: 0, left: 0, top: 0, right: 0 },
}}
/>
<Axis id="y" position={Position.Left} />
<Axis id="x" position={Position.Bottom} />
{this.state.showRectAnnotation && (
<RectAnnotation
id="annotation"
dataValues={[{ coordinates: { x0: 0 } }]}
style={{
fill: 'red',
opacity: 0.25,
}}
/>
)}
{this.state.showLineYAnnotation && (
<LineAnnotation
id="lineany"
dataValues={[
{
dataValue: 6,
details: 'aaa',
header: 'aaa',
},
]}
domainType="yDomain"
marker={<div style={{ width: 10, height: 10, background: 'red' }}></div>}
/>
)}
{this.state.showLineXAnnotation && (
<LineAnnotation
id="lineanx"
dataValues={[
{
dataValue: 10,
details: 'aaa',
header: 'aaa',
},
]}
domainType="xDomain"
marker={<div style={{ width: 10, height: 10, background: 'red' }}></div>}
/>
)}
{this.state.useLinearBar &&
new Array(this.state.totalBars)
.fill(0)
.map((d, i) => (
<BarSeries
key={`linearBar${i}`}
id={`linearBar${i}`}
xScaleType={ScaleType.Linear}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['max']}
data={data}
/>
))}

{this.state.useOrdinalBar &&
new Array(this.state.totalBars)
.fill(0)
.map((d, i) => (
<BarSeries
key={`ordinalBar${i}`}
id={`ordinalBar${i}`}
xScaleType={ScaleType.Ordinal}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['max']}
data={data}
/>
))}

{this.state.useHistogramBar &&
new Array(this.state.totalBars)
.fill(0)
.map((d, i) => (
<BarSeries
key={`histoBar${i}`}
id={`histoBar${i}`}
enableHistogramMode
xScaleType={ScaleType.Ordinal}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['max']}
data={data}
/>
))}

{this.state.useOrdinalLine &&
new Array(this.state.totalLines)
.fill(0)
.map((d, i) => (
<LineSeries
key={`ordinalLines${i}`}
id={`ordinalLines${i}`}
xScaleType={ScaleType.Ordinal}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['max']}
data={data}
/>
))}

{this.state.useLinearLine &&
new Array(this.state.totalLines)
.fill(0)
.map((d, i) => (
<LineSeries
key={`linearLines${i}`}
id={`linearLines${i}`}
xScaleType={ScaleType.Linear}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['max']}
data={data}
/>
))}
</Chart>
</div>
</>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('annotation marker', () => {
xScale,
Position.Left,
0,
false,
0,
);
const expectedDimensions: AnnotationLineProps[] = [
{
Expand Down Expand Up @@ -131,7 +131,7 @@ describe('annotation marker', () => {
xScale,
Position.Left,
0,
false,
0,
);
const expectedDimensions: AnnotationLineProps[] = [
{
Expand Down Expand Up @@ -185,7 +185,7 @@ describe('annotation marker', () => {
xScale,
Position.Bottom,
0,
false,
0,
);
const expectedDimensions: AnnotationLineProps[] = [
{
Expand Down
Loading

0 comments on commit 053f169

Please sign in to comment.