OK! As promised, here we are. I'm using 3.5.6 so I'm not entirely certain how well this will work. I've stuck to mango components to the best of my ability to allow the best compatibility sans the colour picker. If it doesn't work you may need to alter the HTML to use <ma-color-picker instead.
You'll need to set up a userModule file to incorporate this.
I've saved my files in /opt/mango/overrides/web/modules/mangoUI/web/dev/directives/chartProfile
the userModule.js is in /opt/mango/overrides/web/modules/mangoUI/web/dev
For the mangoUI settings, the url for the userModule.js file is:
The user module file contains this:
define(['angular', 'require','./directives/chartProfile/serialChartProfile.js'],function(angular, require,serialChartProfile) { 'use strict'; var userModule = angular.module('userModule', ['maUiApp']); try { userModule.directive('serialChartProfile', serialChartProfile); }catch(e){console.log(e);} return userModule; });//defineserialChartProfile.js
/* Date: 13/8/19 File:serialChartProfile.js Author: Matt 'Fox' Fox Desc: Directive that allows mangoUI users to create chart profiles for their dashboard pages. Name of the JSON store can be set as well as the names of each of the chart profiles. Credit goes to Will Geller and Jared Wiltshire for original codebase */ define(['angular', 'require'],function(angular, require) { 'use strict'; serialChartProfile.$inject = ['maJsonStore','$mdDialog','$mdColorPicker','$mdToast']; function serialChartProfile( JsonStore, $mdDialog, $mdColorPicker,$mdToast ) { console.log($mdColorPicker); var scope = { jsonStore: '<?',//has default option }; return { restrict: 'E', templateUrl:'/modules/mangoUI/web/dev/directives/chartProfile/chartProfile.html', designerInfo: { translation: 'ui.components.serialChartProfile', icon: 'show_chart', category: 'pointValuesAndCharts', attributes: { jsonStore: {type: 'text'} }, }, scope: scope, compile: function() { return linkFn; } }; function linkFn(scope, $element, attrs) { scope.profileStore={}; /* Default for ensuring we have a json store name */ var hasStoreName = !!attrs.jsonStore; if(!hasStoreName) { scope.jsonStore = "chartProfile1"; getChartProfiles(); } else { if( scope.jsonStore.length < 3 ) { scope.jsonStore = "chartProfile1"; getChartProfiles(); } else { getChartProfiles();} } scope.axisOptions = [ {name: 'left', translation: 'ui.app.left'}, {name: 'right', translation: 'ui.app.right'}, {name: 'left-2', translation: 'ui.app.farLeft'}, {name: 'right-2', translation: 'ui.app.farRight'} ]; function getChartProfiles() { JsonStore.get({ xid: scope.jsonStore }).$promise.then(function (item) { scope.profileStore = item.jsonData; scope.chartProfile = Object.keys(scope.profileStore)[0]; }, function () { //create prompt - no data scope.createProfile(); }).then(function() { }); } scope.saveToStore=function() { var item = new JsonStore(); item.jsonData = scope.profileStore; item.xid = scope.jsonStore; item.name = scope.jsonStore; item.readPermission = "user"; item.editPermission = "user"; var r = item.$save(); r.then(function(){$mdToast.show( $mdToast.simple() .textContent("Chart Profiles Saved") .position("top") .hideDelay(3000)); }, function myError(response) { console.log( response.statusText ); $mdToast.show( $mdToast.simple() .textContent(response.data) .position("top") .hideDelay(3000)); }); if (r.status) {} else {} }; scope.showColorPicker = function($event, object, propertyName, rebuild) { if (!object) return; this.$mdColorPicker.show({ value: object[propertyName] || tinycolor.random().toHexString(), defaultValue: '', random: false, clickOutsideToClose: true, hasBackdrop: true, skipHide: false, preserveScope: false, mdColorAlphaChannel: true, mdColorSpectrum: true, mdColorSliders: false, mdColorGenericPalette: true, mdColorMaterialPalette: false, mdColorHistory: false, mdColorDefaultTab: 0, $event: $event }).then(color => { object[propertyName] = color; }); }; scope.createProfile = function(ev) { // Appending dialog to document.body to cover sidenav in docs app var confirm = $mdDialog.prompt() .title('Create New Chart Profile') .textContent('Enter new profile name:') .placeholder('PowerUsage') .ariaLabel('PowerUsage') .initialValue('chartProfile1') .targetEvent(ev) .required(true) .ok('CREATE') .cancel('CANCEL'); $mdDialog.show(confirm).then(function(result) { scope.profileStore[ result ] = {}; scope.chartProfile = result; }, function() { //Do nothing and hide. }); }; scope.deleteProfile = function(ev) { // Appending dialog to document.body to cover sidenav in docs app var confirm = $mdDialog.confirm() .title('Delete Profile') .textContent('Are you sure you want to delete this profile?') .ariaLabel('Delete Chart Profile') .targetEvent(ev) .ok('Confirm Delete') .cancel('Cancel'); $mdDialog.show(confirm).then(function() { delete(scope.profileStore[scope.chartProfile]); scope.status = 'Profile Deleted, save settings to confirm'; }, function() { $scope.status = 'Operation cancelled'; }); }; } } return serialChartProfile; });//definechartProfile.html
<main> <!-- <ma-json-store xid="jsonStore" name="jsonStore"></ma-json-store> --> <ma-button ng-click="createProfile()" label="Create Profile"></ma-button> <ma-button ng-click="saveToStore()" label="Save All Profiles"></ma-button> <ma-button ng-click="deleteProfile()" label="Delete Selected Profile"></ma-button> <md-select ng-model="chartProfile"> <md-option ng-repeat="(profile,vals) in profileStore" value="{{profile}}">{{profile}}</md-option> </md-select> <div class="md-padding"> <div ng-if="chartProfile.length>3"> <md-checkbox ng-model="profileStore[chartProfile].enabled.series1"><span>Configure Series 1:</span></md-checkbox> <md-checkbox ng-model="profileStore[chartProfile].enabled.series2"><span>Configure Series 2:</span></md-checkbox> <md-checkbox ng-model="profileStore[chartProfile].enabled.series3"><span>Configure Series 3:</span></md-checkbox> <md-checkbox ng-model="profileStore[chartProfile].enabled.series4"><span>Configure Series 4:</span></md-checkbox> <md-checkbox ng-model="profileStore[chartProfile].enabled.series5"><span>Configure Series 5:</span></md-checkbox> <md-checkbox ng-model="profileStore[chartProfile].enabled.series6"><span>Configure Series 6:</span></md-checkbox> <md-checkbox ng-model="profileStore[chartProfile].enabled.series7"><span>Configure Series 7:</span></md-checkbox> <md-checkbox ng-model="profileStore[chartProfile].enabled.series8"><span>Configure Series 8:</span></md-checkbox> <md-checkbox ng-model="profileStore[chartProfile].enabled.series9"><span>Configure Series 9:</span></md-checkbox> <md-checkbox ng-model="profileStore[chartProfile].enabled.series10"><span>Configure Series 10:</span></md-checkbox> {{chartProfile.enabled}} <div layout layout-align="start center" layout-wrap ng-repeat="(key,val) in profileStore[chartProfile].enabled" ng-if="val"> <strong flex="100" flex-gt-xs="30" flex-gt-md="15">Configure {{key}}</strong> <md-input-container flex> <label ma-tr="ui.app.lineColor"></label> <md-color-picker ng-model="profileStore[chartProfile][key].pointColor"></md-color-picker> </md-input-container> <!-- <md-input-container flex> <label ma-tr="ui.app.lineColor"></label> <input ng-model="profileStore[chartProfile][key].pointColor" ng-model-options="{debounce: 1000}"> </md-input-container> --> <md-input-container flex> <label ma-tr="ui.app.chartType"></label> <md-select ng-model="profileStore[chartProfile][key].type"> <md-option value=""><em ma-tr="ui.app.clear"></em></md-option> <md-option value="smoothedLine" ma-tr="ui.app.smooth"></md-option> <md-option value="line" ma-tr="ui.app.line"></md-option> <md-option value="step" ma-tr="ui.app.step"></md-option> <md-option value="column" ma-tr="ui.app.bar"></md-option> </md-select> </md-input-container> <md-input-container flex> <label ma-tr="ui.app.pointAxis"></label> <md-select ng-model="profileStore[chartProfile][key].axis"> <md-option value=""><em ma-tr="ui.app.clear"></em></md-option> <md-option ng-repeat="axis in axisOptions track by axis.name" ng-value="axis.name"> <span ma-tr="{{axis.translation}}"></span> </md-option> </md-select> </md-input-container> </div> <div> <md-checkbox ng-model="profileStore[chartProfile].configAxes"><span ma-tr="ui.app.configureAxes"></span></md-checkbox> </div> <div ng-if="profileStore[chartProfile].configAxes" ng-repeat="axis in axisOptions track by axis.name" layout="row" layout-align="start center" layout-wrap> <strong flex="100" flex-gt-xs="15" flex-gt-md="10" ma-tr="{{axis.translation}}"></strong> <div flex="100" flex-gt-xs="85" flex-gt-md="90" layout layout-align="start center" layout-wrap> <md-input-container flex="50" flex-gt-xs="33"> <label ma-tr="ui.app.axisTitle"></label> <input ma-empty-input="undefined" ng-model="profileStore[chartProfile].valueAxes[axis.name].title" ng-model-options="{debounce: 1000}" > </md-input-container> <div flex="50" flex-gt-xs="33" layout layout-align="start center"> <label ma-tr="ui.app.axisColor"></label> <md-color-picker ng-model="profileStore[chartProfile].valueAxes[axis.name].color" ></md-color-picker> <!-- <ma-color-picker ng-model="profileStore[chartProfile].valueAxes[axis.name].color" ></ma-color-picker> --> <!-- <md-input-container flex> <label ma-tr="ui.app.axisColor"></label> <input ma-empty-input="undefined" ng-model="profileStore[chartProfile].valueAxes[axis.name].color" ng-model-options="{debounce: 1000}" > </md-input-container> --> </div> <md-input-container flex="50" flex-gt-xs="33"> <label ma-tr="ui.app.stackType"></label> <md-select ma-empty-input="undefined" ng-model="profileStore[chartProfile].valueAxes[axis.name].stackType" > <md-option value=""><em ma-tr="ui.app.clear"></em></md-option> <md-option value="none" ma-tr="ui.app.none"></md-option> <md-option value="regular" ma-tr="ui.app.stacked"></md-option> <md-option value="100%">100% <span ma-tr="ui.app.stacked"></span></md-option> </md-select> </md-input-container> <md-input-container flex="50" flex-gt-xs="33"> <label ma-tr="ui.app.axisMinimum"></label> <input ma-empty-input="undefined" type="number" ng-model="profileStore[chartProfile].valueAxes[axis.name].minimum" ng-model-options="{debounce: 1000}" > </md-input-container> <md-input-container flex="50" flex-gt-xs="33"> <label ma-tr="ui.app.axisMaximum"></label> <input ma-empty-input="undefined" type="number" ng-model="profileStore[chartProfile].valueAxes[axis.name].maximum" ng-model-options="{debounce: 1000}" > </md-input-container> <md-input-container flex="50" flex-gt-xs="33"> <label ma-tr="ui.app.axisGridCount"></label> <input ma-empty-input="undefined" type="number" min="0" ng-model="profileStore[chartProfile].valueAxes[axis.name].gridCount" ng-model-options="{debounce: 1000}" > </md-input-container> </div> </div> </div> <style> .md-color-picker-input{color:black!important;}</style> </main> <!-- json-store is optional; --> <serial-chart-profile [json-store='jsonStoreName'] ></serial-chart-profile>Keep me informed, hopefully others can use this to make their chart templates for different statuses more dynamically!!
I won't lie, this may require further testing... and more comments!
Fox