Commit d7154552 authored by Phil Hughes's avatar Phil Hughes

Rather than looping data ourselves, d3 loops it

parent 05dc1407
...@@ -4,12 +4,13 @@ export default class Deployments { ...@@ -4,12 +4,13 @@ export default class Deployments {
constructor(width, height) { constructor(width, height) {
this.width = width; this.width = width;
this.height = height; this.height = height;
this.data = [];
this.dateFormat = d3.time.format('%b %d, %Y'); this.dateFormat = d3.time.format('%b %d, %Y');
this.timeFormat = d3.time.format('%H:%M%p'); this.timeFormat = d3.time.format('%H:%M%p');
this.endpoint = document.getElementById('js-metrics').dataset.deploymentEndpoint; this.endpoint = document.getElementById('js-metrics').dataset.deploymentEndpoint;
Deployments.createGradientDef(); this.createGradientDef();
} }
init(chartData) { init(chartData) {
...@@ -29,15 +30,12 @@ export default class Deployments { ...@@ -29,15 +30,12 @@ export default class Deployments {
dataType: 'JSON', dataType: 'JSON',
}) })
.done((data) => { .done((data) => {
this.data = [];
data.deployments.forEach((deployment) => { data.deployments.forEach((deployment) => {
const minInSeconds = 1000 * 60; const time = new Date(deployment.created_at);
let time = new Date(deployment.created_at);
time = new Date(Math.round(time.getTime() / minInSeconds) * minInSeconds);
time.setSeconds(this.chartData[0].time.getSeconds());
const xPos = Math.floor(this.x(time)); const xPos = Math.floor(this.x(time));
time.setSeconds(this.chartData[0].time.getSeconds());
if (xPos >= 0) { if (xPos >= 0) {
this.data.push({ this.data.push({
id: deployment.id, id: deployment.id,
...@@ -65,7 +63,7 @@ export default class Deployments { ...@@ -65,7 +63,7 @@ export default class Deployments {
}); });
} }
static createGradientDef() { createGradientDef() {
const defs = d3.select('body') const defs = d3.select('body')
.append('svg') .append('svg')
.attr({ .attr({
...@@ -84,9 +82,7 @@ export default class Deployments { ...@@ -84,9 +82,7 @@ export default class Deployments {
'stop-color': '#000', 'stop-color': '#000',
'stop-opacity': 0.4, 'stop-opacity': 0.4,
}) })
.select(function selectParentNode() { .select(this.selectParentNode)
return this.parentNode;
})
.append('stop') .append('stop')
.attr({ .attr({
offset: '100%', offset: '100%',
...@@ -116,9 +112,7 @@ export default class Deployments { ...@@ -116,9 +112,7 @@ export default class Deployments {
width: 3, width: 3,
fill: 'url(#shadow-gradient)', fill: 'url(#shadow-gradient)',
}) })
.select(function selectParentNode() { .select(this.selectParentNode)
return this.parentNode;
})
.append('line') .append('line')
.attr({ .attr({
class: 'deployment-line', class: 'deployment-line',
...@@ -130,60 +124,52 @@ export default class Deployments { ...@@ -130,60 +124,52 @@ export default class Deployments {
} }
createDeployInfoBox(chart, key) { createDeployInfoBox(chart, key) {
this.data.forEach((d) => { chart.selectAll('.deploy-info')
const group = chart.select(`.deploy-info-${d.id}-${key}`) .selectAll('.js-deploy-info-box')
.data(this.data)
.enter()
.select(d => document.querySelector(`.deploy-info-${d.id}-${key}`))
.append('svg') .append('svg')
.attr({ .attr({
class: 'js-deploy-info-box hidden',
x: 3, x: 3,
y: 0, y: 0,
width: 92,
height: 60, height: 60,
}); })
.append('rect')
const rect = group.append('rect')
.attr({ .attr({
class: 'rect-text-metric deploy-info-rect rect-metric', class: 'rect-text-metric deploy-info-rect rect-metric',
x: 1, x: 1,
y: 1, y: 1,
rx: 2, rx: 2,
height: group.attr('height') - 2, width: 90,
}); height: 58,
})
const textGroup = group.append('g') .select(this.selectParentNode)
.append('g')
.attr({ .attr({
transform: 'translate(5, 2)', transform: 'translate(5, 2)',
}); })
.append('text')
textGroup.append('text')
.attr({ .attr({
class: 'deploy-info-text text-metric-bold', class: 'deploy-info-text text-metric-bold',
}) })
.text(() => { .text(Deployments.refText)
const isTag = d.tag; .select(this.selectParentNode)
const refText = isTag ? d.ref : d.sha.slice(0, 6); .append('text')
return refText;
});
textGroup.append('text')
.attr({ .attr({
class: 'deploy-info-text', class: 'deploy-info-text',
y: 18, y: 18,
}) })
.text(() => this.dateFormat(d.time)); .text(d => this.dateFormat(d.time))
.select(this.selectParentNode)
textGroup.append('text') .append('text')
.attr({ .attr({
class: 'deploy-info-text text-metric-bold', class: 'deploy-info-text text-metric-bold',
y: 38, y: 38,
}) })
.text(() => this.timeFormat(d.time)); .text(d => this.timeFormat(d.time));
group.attr('width', Math.floor(textGroup.node().getBoundingClientRect().width) + 14);
rect.attr('width', Math.floor(textGroup.node().getBoundingClientRect().width) + 10);
group.attr('class', 'js-deploy-info-box hidden');
});
} }
static toggleDeployTextbox(deploy, key, showInfoBox) { static toggleDeployTextbox(deploy, key, showInfoBox) {
...@@ -208,4 +194,16 @@ export default class Deployments { ...@@ -208,4 +194,16 @@ export default class Deployments {
return dataFound; return dataFound;
} }
/* `this` is bound to the D3 node */
selectParentNode() {
return this.parentNode;
}
static refText(d) {
const isTag = d.tag;
const refText = isTag ? d.ref : d.sha.slice(0, 6);
return refText;
}
} }
...@@ -110,4 +110,24 @@ describe('Metrics deployments', () => { ...@@ -110,4 +110,24 @@ describe('Metrics deployments', () => {
graphElement().querySelector('.deploy-info-1-cpu_values .js-deploy-info-box.hidden'), graphElement().querySelector('.deploy-info-1-cpu_values .js-deploy-info-box.hidden'),
).not.toBeNull(); ).not.toBeNull();
}); });
describe('refText', () => {
it('returns shortened SHA', () => {
expect(
Deployments.refText({
tag: false,
sha: '123456789',
}),
).toBe('123456');
});
it('returns tag name', () => {
expect(
Deployments.refText({
tag: true,
ref: 'v1.0',
}),
).toBe('v1.0');
});
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment