Skip to content

Commit

Permalink
Merge pull request #89 from hashicorp/f-keyed-axis-grids
Browse files Browse the repository at this point in the history
Keyed axis ticks and gridlines
  • Loading branch information
DingoEatingFuzz authored Jun 14, 2023
2 parents d7d540c + 4d6884e commit 42ace85
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/rude-masks-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@lineal-viz/lineal': patch
---

Add keys to Axis and Gridline loops to preserve elements
4 changes: 2 additions & 2 deletions lineal-viz/src/components/lineal/axis/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<path class='domain' stroke='currentColor' d={{this.domainPath}}></path>
{{/if}}
{{#if (eq this.direction 'horizontal')}}
{{#each this.ticks as |tick index|}}
{{#each this.ticks key='@index' as |tick index|}}
<g transform={{tick.transform}}>
{{#if (has-block)}}
{{yield tick index}}
Expand All @@ -26,7 +26,7 @@
</g>
{{/each}}
{{else}}
{{#each this.ticks as |tick index|}}
{{#each this.ticks key='@index' as |tick index|}}
<g transform={{tick.transform}}>
{{#if (has-block)}}
{{yield tick index}}
Expand Down
2 changes: 1 addition & 1 deletion lineal-viz/src/components/lineal/gridlines/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
}}

<g class='gridlines'>
{{#each this.lines as |l|}}
{{#each this.lines key='@index' as |l|}}
<line
stroke='currentColor'
x1={{l.x1}}
Expand Down
32 changes: 32 additions & 0 deletions test-app/app/controllers/lines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,41 @@
import Controller from '@ember/controller';
import { tracked, cached } from '@glimmer/tracking';
import { action } from '@ember/object';
import { ScaleLinear } from '@lineal-viz/lineal/scale';
import { extent } from 'd3-array';

const wiggle = (x: number) => x + Math.random() * x * 0.15 - x * 0.075;

export default class LinesController extends Controller {
@tracked activeDatum = null;
@tracked populationX = this.population;

constructor(...args: any[]) {
super(...args);

setInterval(() => {
console.log('beep');
console.log(this.population);
this.populationX = this.population.map((d) => ({
...d,
people: wiggle(d.people as number),
}));
}, 100);
}

get pXScale() {
return new ScaleLinear({
domain: extent(this.populationX, (d) => +d.year).map((d) => d ?? 0),
});
}

get pYScale() {
return new ScaleLinear({
domain: extent(this.populationX, (d) => d.people as number).map(
(d) => d ?? 0
),
});
}

get population() {
const data = this.model as any[];
Expand Down
52 changes: 52 additions & 0 deletions test-app/app/templates/lines.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,58 @@
SPDX-License-Identifier: MPL-2.0
}}

<h2>Can we break it?</h2>
<div class="fluid-chart">
<Lineal::Fluid class="fluid-chart__plot" as |width height|>
<svg class="fluid-chart__svg">
{{#let
(this.pXScale.derive range=(array 0 width))
(this.pYScale.derive range=(array height 0))
as |xScale yScale|
}}
{{#if (and xScale.isValid yScale.isValid)}}
<Lineal::Axis @scale={{yScale}} @orientation="left" />
<Lineal::Axis
@scale={{xScale}}
@orientation="bottom"
transform="translate(0,{{height}})"
/>
<Lineal::Gridlines
@scale={{yScale}}
@direction="horizontal"
@length={{width}}
opacity="0.7"
/>
<Lineal::Gridlines
@scale={{xScale}}
@direction="vertical"
@length={{height}}
opacity="0.3"
/>
{{#each this.populationX as |d|}}
<circle
cx={{xScale.compute d.year}}
cy={{yScale.compute d.people}}
r="3"
></circle>
{{/each}}
{{/if}}
<Lineal::Line
@data={{this.populationX}}
@xScale={{xScale}}
@yScale={{yScale}}
@x="year"
@y="people"
@curve="natural"
fill="transparent"
stroke="black"
stroke-width="2"
/>
{{/let}}
</svg>
</Lineal::Fluid>
</div>

<h2>Line</h2>
<div class="fluid-chart">
<Lineal::Fluid class="fluid-chart__plot" as |width height|>
Expand Down
28 changes: 28 additions & 0 deletions test-app/tests/integration/components/lineal/axis-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,4 +389,32 @@ module('Integration | Component | Lineal::Axis', function (hooks) {
]);
}
});

test('When tick values change, <g> elements are updated instead of recreated', async function (assert) {
const scale = new ScaleLinear({ range: '0..100', domain: '0..10' });
const tickValues = [0, 0.5, 1.5, 3, 5, 7.5];
this.setProperties({ scale, tickValues });

assert.expect(tickValues.length);

await render(hbs`
<svg>
<Lineal::Axis
@scale={{this.scale}}
@orientation="bottom"
@tickValues={{this.tickValues}}
@offset={{0}} />
</svg>
`);

const firstTicks = findAll('.axis g');

this.set('tickValues', [1, 1.5, 2.5, 4, 6, 8.5]);

const secondTicks = findAll('.axis g');

firstTicks.forEach((tick, idx) => {
assert.strictEqual(tick, secondTicks[idx]);
});
});
});
29 changes: 29 additions & 0 deletions test-app/tests/integration/components/lineal/gridlines-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,33 @@ module('Integration | Component | Lineal::Gridlines', function (hooks) {
}))
);
});

test('When line values change, <line> elements are updated instead of recreated', async function (assert) {
const scale = new ScaleLinear({ range: '0..100', domain: '0..10' });
const lineValues = [0, 10, 20, 30, 50, 80];
this.setProperties({ scale, lineValues });

assert.expect(lineValues.length);

await render(hbs`
<svg>
<Lineal::Gridlines
@scale={{this.scale}}
@lineValues={{this.lineValues}}
@direction="vertical"
@length={{100}}
@offset={{0}} />
</svg>
`);

const firstLines = findAll('line');

this.set('lineValues', [5, 15, 25, 35, 55, 85]);

const secondLines = findAll('line');

firstLines.forEach((line, idx) => {
assert.strictEqual(line, secondLines[idx]);
});
});
});

1 comment on commit 42ace85

@vercel
Copy link

@vercel vercel bot commented on 42ace85 Jun 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

lineal-docs – ./

lineal-docs-hashicorp.vercel.app
lineal-docs.vercel.app
lineal-docs-git-main-hashicorp.vercel.app

Please sign in to comment.