Tons of tweaks based on feedback for new Dashboard

refs: https://github.com/TryGhost/Team/issues/1531
This commit is contained in:
James Morris 2022-04-28 16:40:19 +01:00
parent f81801549b
commit 059ad77939
6 changed files with 120 additions and 47 deletions

View File

@ -35,7 +35,7 @@
</div>
{{else}}
<EmberChart
@type="line"
@type={{this.chartType}}
@data={{this.chartData}}
@options={{this.chartOptions}}
@height={{200}} />

View File

@ -1,3 +1,5 @@
/* global Chart */
import Component from '@glimmer/component';
import moment from 'moment';
import {action} from '@ember/object';
@ -32,6 +34,33 @@ const DISPLAY_OPTIONS = [{
value: 'free'
}];
// custom ChartJS draw function
Chart.defaults.hoverLine = Chart.defaults.line;
Chart.controllers.hoverLine = Chart.controllers.line.extend({
draw: function (ease) {
Chart.controllers.line.prototype.draw.call(this, ease);
if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
let activePoint = this.chart.tooltip._active[0],
ctx = this.chart.ctx,
x = activePoint.tooltipPosition().x,
topY = this.chart.legend.bottom,
bottomY = this.chart.chartArea.bottom;
// draw line
ctx.save();
ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.setLineDash([3, 4]);
ctx.lineWidth = 1;
ctx.strokeStyle = '#7C8B9A';
ctx.stroke();
ctx.restore();
}
}
});
export default class Anchor extends Component {
@service dashboardStats;
@service feature;
@ -113,7 +142,7 @@ export default class Anchor extends Component {
}
get chartType() {
return 'line';
return 'hoverLine'; // uses custom ChartJS draw function
}
get chartTitle() {
@ -212,8 +241,8 @@ export default class Anchor extends Component {
padding: {
top: 2,
bottom: 2,
left: 0,
right: 0
left: 1,
right: 1
}
},
hover: {
@ -276,13 +305,13 @@ export default class Anchor extends Component {
},
gridLines: {
color: barColor,
borderDash: [4,4],
borderDash: [3,4],
display: true,
drawBorder: true,
drawTicks: false,
zeroLineWidth: 1,
zeroLineColor: barColor,
zeroLineBorderDash: [4,4]
zeroLineBorderDash: [3,4]
},
ticks: {
display: false,

View File

@ -1,3 +1,5 @@
/* global Chart */
import Component from '@glimmer/component';
import moment from 'moment';
import {getSymbol} from 'ghost-admin/utils/currency';
@ -6,6 +8,33 @@ import {inject as service} from '@ember/service';
const DATE_FORMAT = 'D MMM';
// custom ChartJS draw function
Chart.defaults.hoverLine = Chart.defaults.line;
Chart.controllers.hoverLine = Chart.controllers.line.extend({
draw: function (ease) {
Chart.controllers.line.prototype.draw.call(this, ease);
if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
let activePoint = this.chart.tooltip._active[0],
ctx = this.chart.ctx,
x = activePoint.tooltipPosition().x,
topY = this.chart.legend.bottom,
bottomY = this.chart.chartArea.bottom;
// draw line
ctx.save();
ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.setLineDash([3, 4]);
ctx.lineWidth = 1;
ctx.strokeStyle = '#7C8B9A';
ctx.stroke();
ctx.restore();
}
}
});
export default class Mrr extends Component {
@service dashboardStats;
@service feature;
@ -32,7 +61,7 @@ export default class Mrr extends Component {
}
get chartType() {
return 'line';
return 'hoverLine'; // uses custom ChartJS draw function
}
get mrrCurrencySymbol() {

View File

@ -1,3 +1,5 @@
/* globals Chart */
import Component from '@glimmer/component';
import moment from 'moment';
import {action} from '@ember/object';
@ -5,6 +7,33 @@ import {inject as service} from '@ember/service';
const DATE_FORMAT = 'D MMM';
// custom ChartJS draw function
Chart.defaults.hoverBar = Chart.defaults.bar;
Chart.controllers.hoverBar = Chart.controllers.bar.extend({
draw: function (ease) {
Chart.controllers.line.prototype.draw.call(this, ease);
if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
let activePoint = this.chart.tooltip._active[0],
ctx = this.chart.ctx,
x = activePoint.tooltipPosition().x,
topY = this.chart.legend.bottom,
bottomY = this.chart.chartArea.bottom;
// draw line
ctx.save();
ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.setLineDash([3, 4]);
ctx.lineWidth = 1;
ctx.strokeStyle = '#7C8B9A';
ctx.stroke();
ctx.restore();
}
}
});
export default class PaidBreakdown extends Component {
@service dashboardStats;
@service feature;
@ -23,7 +52,7 @@ export default class PaidBreakdown extends Component {
}
get chartType() {
return 'bar';
return 'hoverBar';
}
get chartData() {
@ -31,38 +60,19 @@ export default class PaidBreakdown extends Component {
const labels = stats.map(stat => stat.date);
const newData = stats.map(stat => stat.positiveDelta);
const canceledData = stats.map(stat => -stat.negativeDelta);
const netData = stats.map(stat => stat.positiveDelta - stat.negativeDelta);
const barThickness = 5;
return {
labels: labels,
datasets: [
{
type: 'line',
data: netData,
tension: 0,
cubicInterpolationMode: 'monotone',
fill: false,
pointRadius: 0,
pointHitRadius: 10,
pointBorderColor: '#14B8FF',
pointBackgroundColor: '#14B8FF',
pointHoverBackgroundColor: '#14B8FF',
pointHoverBorderColor: '#14B8FF',
pointHoverRadius: 0,
borderColor: 'rgba(189, 197, 204, 0.5)',
borderJoinStyle: 'miter',
borderWidth: 3
}, {
data: newData,
fill: false,
backgroundColor: '#8E42FF',
cubicInterpolationMode: 'monotone',
barThickness: barThickness,
minBarLength: 3
}, {
data: canceledData,
fill: false,
backgroundColor: '#FB76B4',
cubicInterpolationMode: 'monotone',
barThickness: barThickness,
@ -120,15 +130,17 @@ export default class PaidBreakdown extends Component {
tooltipEl.style.opacity = 1;
tooltipEl.style.position = 'absolute';
tooltipEl.style.left = tooltip.x + 'px';
tooltipEl.style.top = tooltip.y + 'px';
tooltipEl.style.top = '70px';
},
callbacks: {
label: (tooltipItems, data) => {
let newValue = data.datasets[1].data[tooltipItems.index].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
document.querySelector('#gh-dashboard5-breakdown-tooltip .gh-dashboard5-tooltip-value-2').innerHTML = `New ${newValue}`;
// new data
let newValue = parseInt(data.datasets[0].data[tooltipItems.index].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','));
document.querySelector('#gh-dashboard5-breakdown-tooltip .gh-dashboard5-tooltip-value-1').innerHTML = `New ${newValue}`;
let canceldValue = data.datasets[2].data[tooltipItems.index].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
document.querySelector('#gh-dashboard5-breakdown-tooltip .gh-dashboard5-tooltip-value-3').innerHTML = `Canceled ${canceldValue}`;
// canceld data
let canceledValue = Math.abs(parseInt(data.datasets[1].data[tooltipItems.index].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')));
document.querySelector('#gh-dashboard5-breakdown-tooltip .gh-dashboard5-tooltip-value-2').innerHTML = `Canceled ${canceledValue}`;
},
title: (tooltipItems) => {
const value = moment(tooltipItems[0].xLabel).format(DATE_FORMAT);

View File

@ -117,10 +117,10 @@ export default class PaidMix extends Component {
},
layout: {
padding: {
top: 30,
top: 45,
bottom: 0,
left: 0,
right: 0
right: 4
}
},
animation: {

View File

@ -219,7 +219,6 @@ Dashboard v5 Layout */
border-left: 1px solid var(--whitegrey);
padding: 4px 24px;
position: relative;
height: 110px;
}
.gh-dashboard5-minichart .gh-dashboard5-data {
@ -256,6 +255,10 @@ Dashboard v5 Layout */
padding: 0;
}
.gh-dashboard5-minichart .gh-dashboard5-chart-box {
height: 110px;
}
.gh-dashboard5-legend {
flex: 1;
display: flex;
@ -324,16 +327,20 @@ Dashboard v5 Layout */
.gh-dashboard5-select {
position: absolute;
top: 16px;
top: 14px;
right: 4px;
}
.gh-dashboard5-select .gh-dashboard5-select {
height: 36px;
}
.gh-dashboard5-select .ember-power-select-selected-item {
font-size: 1.25rem;
font-weight: 600;
letter-spacing: -.1px;
line-height: 1em;
padding: 0;
padding: 0 0 10px;
color: var(--middarkgrey);
white-space: nowrap;
}
@ -465,10 +472,6 @@ Dashboard v5 Chart */
padding: 0 0 0 30%;
}
.gh-dashboard5-minicharts .gh-dashboard5-chart-box {
height: 110px;
}
/* ---------------------------------
Dashboard v5 Percentage */
@ -816,11 +819,11 @@ Dashboard v5 Anchor */
}
.gh-dashboard5-anchor .gh-dashboard5-minicharts {
margin-top: 48px;
margin-top: 32px;
}
.gh-dashboard5-mix .gh-dashboard5-select {
top: -8px;
top: -11px;
right: -18px;
}
@ -833,10 +836,11 @@ Dashboard v5 Engagement */
}
.gh-dashboard5-engagement .gh-dashboard5-columns {
padding-top: 24px;
padding-top: 16px;
}
.gh-dashboard5-engagement .gh-dashboard5-select {
top: 16px;
right: 6px;
}
@ -1015,7 +1019,7 @@ Dashboard v5 Recents */
}
.gh-dashboard5-recents .gh-dashboard5-list-header {
margin-top: 32px;
margin-top: 24px;
}
.gh-dashboard5-recents .gh-dashboard5-list-loading {
@ -1602,10 +1606,9 @@ Dashboard v5 Tooltips */
border: 1px solid var(--whitegrey);
border-radius: 8px;
padding: 12px;
box-shadow: 0 2px 12px rgba(0,0,0,0.05);
box-shadow: 0 3px 12px rgba(0,0,0,0.12);
z-index: 9999;
pointer-events: none;
transition: top 50ms ease-out, left 50ms ease-out;
}
.gh-dashboard5-tooltip .gh-dashboard5-metric-value {