mirror of
https://codeberg.org/artfulrobot/contactcats.git
synced 2025-06-25 23:18:05 +02:00
Sankey looks good now
This commit is contained in:
parent
8591d6c060
commit
216d9a46ee
3 changed files with 41 additions and 16 deletions
|
@ -72,3 +72,10 @@ crm-contact-category-settings .hint {
|
||||||
crm-contact-category-settings .name-input-wrapper:focus-within .hint {
|
crm-contact-category-settings .name-input-wrapper:focus-within .hint {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Category Flows page */
|
||||||
|
.contact-cats-sankey {
|
||||||
|
background:white;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
<svg viewBox="0 0 {{ $ctrl.sankey.width }} {{ $ctrl.sankey.height }}"
|
<svg viewBox="0 0 {{ $ctrl.sankey.width }} {{ $ctrl.sankey.height }}"
|
||||||
width="{{$ctrl.sankey.width}}"
|
width="{{$ctrl.sankey.width}}"
|
||||||
height="{{$ctrl.sankey.height}}"
|
height="{{$ctrl.sankey.height}}"
|
||||||
style="width: 100%; height: auto;"
|
|
||||||
version="1.1" xmlns="http://www.w3.org/2000/svg"
|
version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
<defs>
|
<defs>
|
||||||
|
@ -51,7 +50,7 @@
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<g transform="translate({{$ctrl.sankey.labelWidth}})">
|
<g transform="translate({{$ctrl.sankey.iconWidth}})">
|
||||||
<path ng-repeat="p in $ctrl.sankey.snakes"
|
<path ng-repeat="p in $ctrl.sankey.snakes"
|
||||||
d="{{p.d}}"
|
d="{{p.d}}"
|
||||||
fill="{{p.fill}}"
|
fill="{{p.fill}}"
|
||||||
|
@ -61,7 +60,7 @@
|
||||||
</path>
|
</path>
|
||||||
</g>
|
</g>
|
||||||
<!-- to-side labels -->
|
<!-- to-side labels -->
|
||||||
<g transform="translate({{$ctrl.sankey.labelWidth + $ctrl.sankey.snakeWidth}})">
|
<g transform="translate({{$ctrl.sankey.iconWidth + $ctrl.sankey.snakeWidth}})">
|
||||||
<rect ng-repeat="toAna in $ctrl.sankey.analysisArray"
|
<rect ng-repeat="toAna in $ctrl.sankey.analysisArray"
|
||||||
x=0
|
x=0
|
||||||
y="{{toAna.y}}"
|
y="{{toAna.y}}"
|
||||||
|
@ -71,11 +70,14 @@
|
||||||
></rect>
|
></rect>
|
||||||
<foreignobject ng-repeat="toAna in $ctrl.sankey.analysisArray"
|
<foreignobject ng-repeat="toAna in $ctrl.sankey.analysisArray"
|
||||||
x="20" y="{{toAna.y}}" width="{{$ctrl.sankey.labelWidth}}" height="{{toAna.thisCatHeight}}">
|
x="20" y="{{toAna.y}}" width="{{$ctrl.sankey.labelWidth}}" height="{{toAna.thisCatHeight}}">
|
||||||
<span class=sankey-label style="display:block;color:{{toAna.cat.color}}"><i class="crm-i {{toAna.cat.icon}}" title="{{toAna.cat.label}}"></i></span>
|
<span class=sankey-label style="display:block;color:{{toAna.cat.color}}">
|
||||||
|
<i class="crm-i {{toAna.cat.icon}}" title="{{toAna.cat.label}}"></i>
|
||||||
|
{{toAna.cat.label}} {{toAna.now.toLocaleString()}}
|
||||||
|
</span>
|
||||||
</foreignobject>
|
</foreignobject>
|
||||||
</g>
|
</g>
|
||||||
<!-- from-side labels -->
|
<!-- from-side labels -->
|
||||||
<g transform="translate({{$ctrl.sankey.labelWidth - 16}})">
|
<g transform="translate({{$ctrl.sankey.iconWidth}})">
|
||||||
<rect ng-repeat="toAna in $ctrl.sankey.analysisArray"
|
<rect ng-repeat="toAna in $ctrl.sankey.analysisArray"
|
||||||
x=0
|
x=0
|
||||||
y="{{toAna.y}}"
|
y="{{toAna.y}}"
|
||||||
|
@ -83,9 +85,16 @@
|
||||||
height="{{toAna.fromCatHeight}}"
|
height="{{toAna.fromCatHeight}}"
|
||||||
fill="{{toAna.cat.color}}"
|
fill="{{toAna.cat.color}}"
|
||||||
></rect>
|
></rect>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
<foreignobject ng-repeat="toAna in $ctrl.sankey.analysisArray"
|
<foreignobject ng-repeat="toAna in $ctrl.sankey.analysisArray"
|
||||||
x="-32" y="{{toAna.y}}" width="32" height="{{toAna.thisCatHeight}}">
|
x=0 y="{{toAna.y}}" width="{{$ctrl.sankey.iconWidth}}"
|
||||||
<span class=sankey-label style="display:block;color:{{toAna.cat.color}}"><i class="crm-i {{toAna.cat.icon}}" title="{{toAna.cat.label}}"></i></span>
|
height="{{toAna.thisCatHeight}}">
|
||||||
|
<span class=sankey-label
|
||||||
|
title="{{toAna.previous}}"
|
||||||
|
style="display:block;text-align:center;color:{{toAna.cat.color}}"
|
||||||
|
><i class="crm-i {{toAna.cat.icon}}" title="{{toAna.cat.label}}"></i>
|
||||||
|
</span>
|
||||||
</foreignobject>
|
</foreignobject>
|
||||||
</g>
|
</g>
|
||||||
<!--
|
<!--
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
angular.module("crmContactcats").component("crmContactCategoryFlows", {
|
angular.module("crmContactcats").component("crmContactCategoryFlows", {
|
||||||
templateUrl: "~/crmContactcats/crmContactCategoryFlows.html",
|
templateUrl: "~/crmContactcats/crmContactCategoryFlows.html",
|
||||||
controller: function($scope, $timeout, crmApi4, crmStatus, $document) {
|
controller: function($scope, $timeout, crmApi4, crmStatus, $document) {
|
||||||
const catHeightMin = 50, catHeightGap = 8;
|
|
||||||
var ts = ($scope.ts = CRM.ts(null)),
|
var ts = ($scope.ts = CRM.ts(null)),
|
||||||
ctrl = this;
|
ctrl = this;
|
||||||
|
|
||||||
|
@ -19,9 +18,8 @@
|
||||||
: allFlowsData;
|
: allFlowsData;
|
||||||
|
|
||||||
ctrl.loading = false;
|
ctrl.loading = false;
|
||||||
const labelWidth = ctrl.sankey.labelWidth,
|
const width = Math.max(600, document.querySelector('.contact-cats-sankey').clientWidth),
|
||||||
width = Math.max(600, document.querySelector('.contact-cats-sankey').clientWidth),
|
snakeWidth = width - ctrl.sankey.labelWidth - ctrl.sankey.iconWidth;
|
||||||
snakeWidth = width - 2*labelWidth;
|
|
||||||
ctrl.sankey.width = width;
|
ctrl.sankey.width = width;
|
||||||
ctrl.sankey.snakeWidth = snakeWidth;
|
ctrl.sankey.snakeWidth = snakeWidth;
|
||||||
|
|
||||||
|
@ -79,7 +77,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow a cat height to grow from its min to 3x min.
|
// Allow a cat height to grow from its min to 3x min.
|
||||||
let maxCatHeight = 3 * catHeightMin;
|
let maxCatHeight = 3 * ctrl.sankey.catHeightMin;
|
||||||
let maxContactsAtOneCat = Math.max(... analysisArray.map(cat => Math.max(cat.now, cat.previous)));
|
let maxContactsAtOneCat = Math.max(... analysisArray.map(cat => Math.max(cat.now, cat.previous)));
|
||||||
let scale = maxCatHeight / maxContactsAtOneCat;
|
let scale = maxCatHeight / maxContactsAtOneCat;
|
||||||
console.log({maxCatHeight, maxContactsAtOneCat,scale});
|
console.log({maxCatHeight, maxContactsAtOneCat,scale});
|
||||||
|
@ -92,8 +90,8 @@
|
||||||
toAna.y = accumulatedY;
|
toAna.y = accumulatedY;
|
||||||
toAna.toCatHeight = Math.max(1, Math.round(scale * toAna.now));
|
toAna.toCatHeight = Math.max(1, Math.round(scale * toAna.now));
|
||||||
toAna.fromCatHeight = Math.max(1,Math.round(scale * toAna.previous));
|
toAna.fromCatHeight = Math.max(1,Math.round(scale * toAna.previous));
|
||||||
toAna.thisCatHeight = Math.ceil(Math.max(catHeightMin, scale * Math.max(toAna.now, toAna.previous)));
|
toAna.thisCatHeight = Math.ceil(Math.max(ctrl.sankey.catHeightMin, scale * Math.max(toAna.now, toAna.previous)));
|
||||||
accumulatedY += toAna.thisCatHeight + catHeightGap;
|
accumulatedY += toAna.thisCatHeight + ctrl.sankey.catHeightGap;
|
||||||
// console.log({toCat: toAna.cat.label, toCatY: toAna.y, accumulatedY, thisCatHeight});
|
// console.log({toCat: toAna.cat.label, toCatY: toAna.y, accumulatedY, thisCatHeight});
|
||||||
// Intialise source offsets for this category.
|
// Intialise source offsets for this category.
|
||||||
offsetWithinSourcesByCat[toAna.cat.id] = 0;
|
offsetWithinSourcesByCat[toAna.cat.id] = 0;
|
||||||
|
@ -103,7 +101,7 @@
|
||||||
return a.cat.presentation_order - b.cat.presentation_order;
|
return a.cat.presentation_order - b.cat.presentation_order;
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
ctrl.sankey.height = Math.ceil(accumulatedY);
|
ctrl.sankey.height = analysisArray[analysisArray.length -1].y + analysisArray[analysisArray.length -1].thisCatHeight;
|
||||||
|
|
||||||
// Make a list of snakes we need to draw.
|
// Make a list of snakes we need to draw.
|
||||||
const snakes = [];
|
const snakes = [];
|
||||||
|
@ -167,7 +165,18 @@
|
||||||
ctrl.startDate = new Date('2025-03-25');
|
ctrl.startDate = new Date('2025-03-25');
|
||||||
ctrl.endDate = null;
|
ctrl.endDate = null;
|
||||||
ctrl.stats = null;
|
ctrl.stats = null;
|
||||||
ctrl.sankey = { height: 500, width: 900, labelWidth: 150, snakeWidth: 600, snakes: [], analysisArray: [] };
|
ctrl.sankey = {
|
||||||
|
catHeightMin : 50,
|
||||||
|
labelWidth: 220,
|
||||||
|
iconWidth: 32,
|
||||||
|
catHeightGap: 8,
|
||||||
|
// the following values get overwritten.
|
||||||
|
height: 500,
|
||||||
|
width: 900,
|
||||||
|
snakeWidth: 600,
|
||||||
|
snakes: [],
|
||||||
|
analysisArray: []
|
||||||
|
};
|
||||||
|
|
||||||
if (useTestFixtures) {
|
if (useTestFixtures) {
|
||||||
ctrl.catDefs = [
|
ctrl.catDefs = [
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue