• Recent
    • Tags
    • Popular
    • Register
    • Login

    Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

    Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website Mango 5 Documentation Website

    A global way to define colors for AMCharts

    Mango Automation general Discussion
    4
    13
    2.8k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      Jonas
      last edited by

      What is the best way to define colors for AMCharts? We have many different charts and I would like to define the colors globally in a CSS file for example.

      <ma-point-values point="EZR_T" values="EZR_T_Values" rendered="true" from="dateBar.from" to="dateBar.to" rollup="AVERAGE" rollup-interval="{{dateBar.rollupIntervals}} {{dateBar.rollupIntervalPeriod}}"></ma-point-values>
      <ma-serial-chart flex style="width: auto; height: 450px;" 
        series-1-point="EZR_T" 
        series-1-values="EZR_T_Values" 
        series-1-color="green" 
        series-1-type="line" 
        series-1-title="Raumtemperatur"
      
      legend="true" balloon="true" default-balloon-text="[[title]]: [[value]]" export="true" stack-type="none" options="{valueAxes:[{title:'°C'}, {title:'kW'}]}">
      </ma-serial-chart>
      

      I would like to have series-1-color="green" be something like series-1-color="{{green}}" or insert a name of a class from a stylesheet.

      Is there a good way? Thanks for your help!

      1 Reply Last reply Reply Quote 0
      • CraigWebC
        CraigWeb
        last edited by

        you can do soemthing like this on your main div:
        <div ng-init="color ={green:'green}">
        Then on your chart, you can do series-1-color="color.green"

        J 1 Reply Last reply Reply Quote 0
        • Jared WiltshireJ
          Jared Wiltshire
          last edited by Jared Wiltshire

          Hi @Jonas the series colors are by default the color set to the chart color on the data point, you can edit the data points using the bulk editor to set their colors.

          You can also use CSS to style other parts of the chart. You can define a global CSS file on the UI settings page. Use the chrome element inspector to discover the CSS class on the SVG element inside the chart.

          edit. See this thread - https://forum.infiniteautomation.com/topic/4150/styling-amcharts
          Also, amcharts CSS reference - https://www.amcharts.com/docs/v3/tutorials/css-class-names/

          Developer at Radix IoT

          1 Reply Last reply Reply Quote 0
          • J
            Jonas @CraigWeb
            last edited by Jonas

            @craigweb I created a colors-page with this code:

            <div ng-init="colorRed='#F44336'"></div>
            <div ng-init="colorRed2='#E57373'"></div>
            <div ng-init="colorOrange='#EF6C00'"></div>
            <div ng-init="colorOrange2='#FF9800'"></div>
            

            And on the page with the AmCharts I used the ma-ui-page-view with the XID of the colors-page but it doesn't work. It only works if the ng-init definitions are on the same page where the chart is defined.

            But I would like to have one place where I can define 20+ colors to use it on different pages / charts and SVG. I learned that CSS would be the place to do it but I cannot get it to work with amcharts CSS reference.

            CraigWebC 1 Reply Last reply Reply Quote 0
            • MattFoxM
              MattFox
              last edited by MattFox

              @jonas said in A global way to define colors for AMCharts:

              But I would like to have one place where I can define 20+ colors to use it on different pages / charts and SVG. I learned that CSS would be the place to do it but I cannot get it to work with amcharts CSS reference.

              Just a quick thought, but have you added all of your css styles into a file that can be accessed by the user css styles under administration->ui settings->Miscellaneous settings->User stylesheet url?
              That will always be loaded and will enable you to have your global css styles.

              Secondly, assuming you're using google chrome, using developer tools you can inspect the chart and select the html elements corresponding to the chart series in the amchart instance and 'create' styles for it. This can be done with the css styles window on the right hand side of the element window. This will allow you to ensure your naming conventions are correct for applying the styles you want - even copying and pasting them into your new global styles file so no concerns for misstypes etc...

              Do not follow where the path may lead; go instead where there is no path.
              And leave a trail - Muriel Strode

              J 1 Reply Last reply Reply Quote 0
              • CraigWebC
                CraigWeb @Jonas
                last edited by

                @jonas
                If you don't go the styles route which is probably better. You can store the colours in a JSON store. Then use the JSON component to retrieve them in each page.

                1 Reply Last reply Reply Quote 0
                • J
                  Jonas @MattFox
                  last edited by Jonas

                  @mattfox Thanks for your input.
                  I use a global css stylesheet via the ui-settings.
                  But the css class of an AMChart line is always the same. amcharts-graph-stroke or amcharts-graph-series-1 and we have 50+ charts and series-1 isn't always "blue" for example.

                  And if I add series-1-class="colorRed" or series-1-className="colorRed" to the chart settings isn't working. But that's what I basically need. Add my own class to every series because I already defined all my colors in my stylesheet.

                  1 Reply Last reply Reply Quote 0
                  • CraigWebC
                    CraigWeb
                    last edited by

                    Have you considered using the point default chart colour?

                    J 1 Reply Last reply Reply Quote 0
                    • J
                      Jonas @CraigWeb
                      last edited by Jonas

                      @craigweb There are often two different variants of one color. And predefined colors in the client industry. Room temperature, for example, is green. And outside temperature light green.

                      I have a look at your recommended JSON component way now.

                      1 Reply Last reply Reply Quote 0
                      • MattFoxM
                        MattFox
                        last edited by MattFox

                        Sounds like you need a chart profile configured in the graph options to set line colours. I've done something similar for highcharts that I've embedded into my dashboard. But am storing in a separate database.
                        I can look into coding something for you because I believe it will be beneficial for the mango community. I'll prob bastardise what jared has done from the watchlist page (it's good code!) and incorporate that into saving it as a profile in a json data file.
                        Let me know your thoughts

                        Fox

                        Do not follow where the path may lead; go instead where there is no path.
                        And leave a trail - Muriel Strode

                        J 1 Reply Last reply Reply Quote 0
                        • J
                          Jonas @MattFox
                          last edited by

                          @mattfox Hi!
                          We use a json component now and its working. But if you can build a better solution, we would definitely use it.

                          For everyone who is looking for a solution:
                          Insert this in your page with the AMChart

                          <ma-json-store xid="colours" item="myItem"></ma-json-store>
                          

                          And our json with the xid "colours" is something like:

                          {
                              "Red": "#FF4040",
                              "Orange": "#CD661D",
                              "Grey": "#68838B"
                          }
                          

                          And in the AMChart we use

                          series-1-color="{{myItem.jsonData.Orange}}" 
                          
                          1 Reply Last reply Reply Quote 0
                          • MattFoxM
                            MattFox
                            last edited by MattFox

                            Nicely done Jonas, I'll throw together a UI directive to do this, shouldn't take tooo long.
                            However, what I'll do is make it so that the graphs save with the names series1, series2 etc
                            You can separate chart profiles with a non white space name.

                            Do not follow where the path may lead; go instead where there is no path.
                            And leave a trail - Muriel Strode

                            1 Reply Last reply Reply Quote 0
                            • MattFoxM
                              MattFox
                              last edited by MattFox

                              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:

                              /modules/mangoUI/web/dev/userModule.js
                              

                              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;
                              });//define
                              

                              serialChartProfile.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;
                              });//define
                              

                              chartProfile.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

                              Do not follow where the path may lead; go instead where there is no path.
                              And leave a trail - Muriel Strode

                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post