0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-24 23:48:13 -05:00

Updated open rate chart

- changed to bar chart
- added handling of empty dataset
This commit is contained in:
Peter Zimon 2021-02-23 12:50:54 +01:00
parent c7bc501d23
commit 92dbc288ec
5 changed files with 55 additions and 17 deletions

View file

@ -3,7 +3,7 @@
<GhLoadingSpinner /> <GhLoadingSpinner />
{{else}} {{else}}
<EmberChart <EmberChart
@type="LineWithLine" @type={{this.type}}
@options={{this.chartOptions}} @options={{this.chartOptions}}
@data={{this.chartData}} @data={{this.chartData}}
@height={{300}} /> @height={{300}} />

View file

@ -126,6 +126,18 @@ export default Component.extend({
// Internal ---------------------------------------------------------------- // Internal ----------------------------------------------------------------
setChartData({dateLabels, dateValues, label = 'Total Members'}) { setChartData({dateLabels, dateValues, label = 'Total Members'}) {
let backgroundColors = this.lineColor;
if (this.chartType === 'open-rate') {
backgroundColors = dateValues.map((dateValue) => {
if (dateValue) {
return this.lineColor;
} else {
return (this.nightShift ? '#7C8B9A' : '#CED4D9');
}
});
}
this.set('chartData', { this.set('chartData', {
labels: dateLabels, labels: dateLabels,
datasets: [{ datasets: [{
@ -133,11 +145,13 @@ export default Component.extend({
cubicInterpolationMode: 'monotone', cubicInterpolationMode: 'monotone',
data: dateValues, data: dateValues,
fill: false, fill: false,
backgroundColor: this.lineColor, backgroundColor: backgroundColors,
pointRadius: 0, pointRadius: 0,
pointHitRadius: 10, pointHitRadius: 10,
borderColor: this.lineColor, borderColor: this.lineColor,
borderJoinStyle: 'miter' borderJoinStyle: 'miter',
maxBarThickness: 20,
minBarLength: 2
}] }]
}); });
}, },
@ -145,6 +159,10 @@ export default Component.extend({
setChartOptions({rangeInDays}) { setChartOptions({rangeInDays}) {
let maxTicksAllowed = this.isSmall ? 3 : this.getTicksForRange(rangeInDays); let maxTicksAllowed = this.isSmall ? 3 : this.getTicksForRange(rangeInDays);
if (this.chartType === 'open-rate') {
maxTicksAllowed = 0;
}
this.setChartJSDefaults(); this.setChartJSDefaults();
let options = { let options = {
responsive: true, responsive: true,
@ -176,6 +194,15 @@ export default Component.extend({
titleFontStyle: 'normal', titleFontStyle: 'normal',
titleFontColor: 'rgba(255, 255, 255, 0.7)', titleFontColor: 'rgba(255, 255, 255, 0.7)',
titleMarginBottom: 3, titleMarginBottom: 3,
filter: (tooltipItems, data) => {
if (this.chartType === 'open-rate') {
let label = data.labels[tooltipItems.index];
if (label === '') {
return false;
}
}
return true;
},
callbacks: { callbacks: {
label: (tooltipItems, data) => { label: (tooltipItems, data) => {
const labelText = data.datasets[tooltipItems.datasetIndex].label; const labelText = data.datasets[tooltipItems.datasetIndex].label;
@ -184,9 +211,19 @@ export default Component.extend({
const currency = getSymbol(this.stats.currency); const currency = getSymbol(this.stats.currency);
valueText = `${currency}${valueText}`; valueText = `${currency}${valueText}`;
} }
if (this.chartType === 'open-rate') {
valueText = `${valueText}%`;
}
return `${labelText}: ${valueText}`; return `${labelText}: ${valueText}`;
}, },
title: function (tooltipItems) { title: (tooltipItems) => {
if (this.chartType === 'open-rate') {
if (tooltipItems.length) {
return tooltipItems[0].xLabel;
} else {
return '';
}
}
return moment(tooltipItems[0].xLabel).format(DATE_FORMAT); return moment(tooltipItems[0].xLabel).format(DATE_FORMAT);
} }
} }
@ -215,7 +252,7 @@ export default Component.extend({
autoSkip: false, autoSkip: false,
fontColor: '#626D79', fontColor: '#626D79',
maxTicksLimit: 10, maxTicksLimit: 10,
callback: function (value, index, values) { callback: (value, index, values) => {
let step = (values.length - 1) / (maxTicksAllowed); let step = (values.length - 1) / (maxTicksAllowed);
let steps = []; let steps = [];
for (let i = 0; i < maxTicksAllowed; i++) { for (let i = 0; i < maxTicksAllowed; i++) {
@ -225,7 +262,7 @@ export default Component.extend({
if (index === 0) { if (index === 0) {
return value; return value;
} }
if (index === (values.length - 1)) { if (index === (values.length - 1) && this.chartType !== 'open-rate') {
return 'Today'; return 'Today';
} }

View file

@ -167,11 +167,11 @@ export default class DashboardController extends Controller {
rangeInDays: 30 rangeInDays: 30
}, },
data: { data: {
label: 'Open Rate', label: 'Open rate',
dateLabels: results.map(d => d.submittedAt), dateLabels: results.map(d => d.subject),
dateValues: results.map(d => d.openRate) dateValues: results.map(d => d.openRate)
}, },
title: 'Open Rate', title: 'Open rate',
stats: results stats: results
}; };
this.newsletterOpenRatesLoading = false; this.newsletterOpenRatesLoading = false;

View file

@ -144,10 +144,11 @@ export default class MembersStatsService extends Service {
@task @task
*_fetchNewsletterStatsTask() { *_fetchNewsletterStatsTask() {
const limit = 5;
let query = { let query = {
filter: 'email_count:-0', filter: 'email_count:-0',
order: 'submitted_at desc', order: 'submitted_at desc',
limit: 10 limit: limit
}; };
const results = yield this.store.query('email', query); const results = yield this.store.query('email', query);
const data = results.toArray(); const data = results.toArray();
@ -160,8 +161,8 @@ export default class MembersStatsService extends Service {
}); });
const paddedResults = []; const paddedResults = [];
if (data.length < 10) { if (data.length < limit) {
const pad = 10 - data.length; const pad = limit - data.length;
const lastSubmittedAt = data.length > 0 ? data[results.length - 1].submittedAtUTC : moment(); const lastSubmittedAt = data.length > 0 ? data[results.length - 1].submittedAtUTC : moment();
for (let i = 0; i < pad; i++) { for (let i = 0; i < pad; i++) {
paddedResults.push({ paddedResults.push({
@ -171,7 +172,7 @@ export default class MembersStatsService extends Service {
}); });
} }
} }
stats = stats.concat(paddedResults); stats = stats .concat(paddedResults);
stats.reverse(); stats.reverse();
this.newsletterStats = stats; this.newsletterStats = stats;
return stats; return stats;

View file

@ -24,7 +24,7 @@
</div> </div>
{{#if this.mrrStatsData}} {{#if this.mrrStatsData}}
<div class="gh-dashboard-chart"> <div class="gh-dashboard-chart">
<GhMembersChart @nightShift={{feature "nightShift"}} @showSummary={{false}} @showRange={{false}} @chartType="mrr" @chartStats={{this.mrrStatsData}} /> <GhMembersChart @type="LineWithLine" @nightShift={{feature "nightShift"}} @showSummary={{false}} @showRange={{false}} @chartType="mrr" @chartStats={{this.mrrStatsData}} />
</div> </div>
{{else}} {{else}}
<div class="gh-dashboard-chart nodata"> <div class="gh-dashboard-chart nodata">
@ -43,7 +43,7 @@
</div> </div>
</div> </div>
<div class="gh-dashboard-chart small"> <div class="gh-dashboard-chart small">
<GhMembersChart @nightShift={{feature "nightShift"}} @chartSize="small" @showSummary={{false}} @chartType="all-members" @showRange={{false}} @chartStats={{this.memberCountStatsData.all}} /> <GhMembersChart @type="LineWithLine" @nightShift={{feature "nightShift"}} @chartSize="small" @showSummary={{false}} @chartType="all-members" @showRange={{false}} @chartStats={{this.memberCountStatsData.all}} />
</div> </div>
</div> </div>
</div> </div>
@ -57,7 +57,7 @@
</div> </div>
</div> </div>
<div class="gh-dashboard-chart small"> <div class="gh-dashboard-chart small">
<GhMembersChart @nightShift={{feature "nightShift"}} @chartSize="small" @showSummary={{false}} @chartType="paid-members" @showRange={{false}} @chartStats={{this.memberCountStatsData.paid}} /> <GhMembersChart @type="LineWithLine" @nightShift={{feature "nightShift"}} @chartSize="small" @showSummary={{false}} @chartType="paid-members" @showRange={{false}} @chartStats={{this.memberCountStatsData.paid}} />
</div> </div>
</div> </div>
</div> </div>
@ -71,7 +71,7 @@
</div> </div>
</div> </div>
<div class="gh-dashboard-chart small"> <div class="gh-dashboard-chart small">
<GhMembersChart @nightShift={{feature "nightShift"}} @chartSize="small" @showSummary={{false}} @chartType="paid-members" @showRange={{false}} @chartStats={{this.newsletterOpenRatesData}} /> <GhMembersChart @type="bar" @nightShift={{feature "nightShift"}} @chartSize="small" @showSummary={{false}} @chartType="open-rate" @showRange={{false}} @chartStats={{this.newsletterOpenRatesData}} />
</div> </div>
</div> </div>
</div> </div>