mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-03 23:00:14 -05:00
Refined source attribution dashboard chart
- updates chart to show percentage value for each source - adds Others bar back to the charts to show total percentage of other sources out of top 5
This commit is contained in:
parent
836010c0f2
commit
17f587ca0e
2 changed files with 73 additions and 38 deletions
|
@ -78,7 +78,7 @@ export default class SourceAttributionChart extends Component {
|
|||
value = -value;
|
||||
}
|
||||
|
||||
tooltipTextEl.innerHTML = `<span class="indicator solid" style="background-color: ${data.datasets[tooltipItems.datasetIndex].backgroundColor[tooltipItems.index]}"></span><span class="value">${value}</span><span class="metric">${label}</span>`;
|
||||
tooltipTextEl.innerHTML = `<span class="indicator solid" style="background-color: ${data.datasets[tooltipItems.datasetIndex].backgroundColor[tooltipItems.index]}"></span><span class="value">${value}%</span><span class="metric">${label}</span>`;
|
||||
},
|
||||
title: () => {
|
||||
return null;
|
||||
|
@ -92,40 +92,75 @@ export default class SourceAttributionChart extends Component {
|
|||
get chartData() {
|
||||
let borderColor = this.feature.nightShift ? '#101114' : '#fff';
|
||||
|
||||
if (this.args.sortColumn === 'signups') {
|
||||
const sortedByFree = [...this.sources];
|
||||
sortedByFree.sort((a, b) => {
|
||||
return b.signups - a.signups;
|
||||
});
|
||||
return {
|
||||
labels: sortedByFree.slice(0, 5).map(source => source.source),
|
||||
datasets: [{
|
||||
label: 'Signups',
|
||||
data: sortedByFree.slice(0, 5).map(source => source.signups),
|
||||
backgroundColor: CHART_COLORS.slice(0, 5),
|
||||
borderWidth: 2,
|
||||
borderColor: borderColor,
|
||||
hoverBorderWidth: 2,
|
||||
hoverBorderColor: borderColor
|
||||
}]
|
||||
};
|
||||
} else {
|
||||
const sortedByPaid = [...this.sources];
|
||||
sortedByPaid.sort((a, b) => {
|
||||
return b.paidConversions - a.paidConversions;
|
||||
});
|
||||
return {
|
||||
labels: sortedByPaid.slice(0, 5).map(source => source.source),
|
||||
datasets: [{
|
||||
label: 'Paid Conversions',
|
||||
data: sortedByPaid.slice(0, 5).map(source => source.paidConversions),
|
||||
backgroundColor: CHART_COLORS.slice(0, 5),
|
||||
borderWidth: 2,
|
||||
borderColor: borderColor,
|
||||
hoverBorderWidth: 2,
|
||||
hoverBorderColor: borderColor
|
||||
}]
|
||||
};
|
||||
return {
|
||||
labels: this.allSources.map(source => source.source),
|
||||
datasets: [{
|
||||
label: this.args.sortColumn === 'signups' ? 'Signups' : 'Paid conversions',
|
||||
data: this.allSources.map((source) => {
|
||||
return source.percentage;
|
||||
}),
|
||||
backgroundColor: CHART_COLORS.slice(0, 6),
|
||||
borderWidth: 2,
|
||||
borderColor: borderColor,
|
||||
hoverBorderWidth: 2,
|
||||
hoverBorderColor: borderColor
|
||||
}]
|
||||
};
|
||||
}
|
||||
|
||||
get allSources() {
|
||||
const mainSources = [...this.sortedSources.slice(0, 5)];
|
||||
if (this.others) {
|
||||
mainSources.push(this.others);
|
||||
}
|
||||
// get percentage of each source
|
||||
const total = mainSources.reduce((acc, source) => {
|
||||
if (this.args.sortColumn === 'signups') {
|
||||
return acc + source.signups;
|
||||
}
|
||||
return acc + source.paidConversions;
|
||||
}, 0);
|
||||
|
||||
return mainSources.map((source) => {
|
||||
let value = 0;
|
||||
if (this.args.sortColumn === 'signups') {
|
||||
value = source.signups;
|
||||
} else {
|
||||
value = source.paidConversions;
|
||||
}
|
||||
return {
|
||||
...source,
|
||||
percentage: Math.round((value / total) * 100)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// Others data includes all sources except the first 5
|
||||
get others() {
|
||||
if (this.sortedSources.length <= 5) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.sortedSources.slice(5).reduce((acc, source) => {
|
||||
return {
|
||||
...acc,
|
||||
signups: acc.signups + source.signups,
|
||||
paidConversions: acc.paidConversions + source.paidConversions
|
||||
};
|
||||
}, {
|
||||
source: 'Others',
|
||||
signups: 0,
|
||||
paidConversions: 0
|
||||
});
|
||||
}
|
||||
|
||||
get sortedSources() {
|
||||
return this.args.sources?.filter(source => source.source).sort((a, b) => {
|
||||
if (this.args.sortColumn === 'signups') {
|
||||
return b.signups - a.signups;
|
||||
} else {
|
||||
return b.paidConversions - a.paidConversions;
|
||||
}
|
||||
}) || [];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ export default class SourceAttributionTable extends Component {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (this.sortedSources === 5 && !this.unavailableSource.length) {
|
||||
if (this.sortedSources.length === 5 && !this.unavailableSource.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,8 @@ export default class SourceAttributionTable extends Component {
|
|||
paidConversions: acc.paidConversions + source.paidConversions
|
||||
};
|
||||
}, {
|
||||
signups: this.unavailableSource?.signups ?? 0,
|
||||
paidConversions: this.unavailableSource?.paidConversions ?? 0
|
||||
signups: 0,
|
||||
paidConversions: 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue