Theme.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. define("dojox/charting/Theme", ["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare","dojo/_base/Color",
  2. "dojox/color/_base", "dojox/color/Palette", "dojox/lang/utils", "dojox/gfx/gradutils"],
  3. function(lang, arr, declare, Color, colorX, Palette, dlu, dgg){
  4. var Theme = declare("dojox.charting.Theme", null, {
  5. // summary:
  6. // A Theme is a pre-defined object, primarily JSON-based, that makes up the definitions to
  7. // style a chart.
  8. //
  9. // description:
  10. // While you can set up style definitions on a chart directly (usually through the various add methods
  11. // on a dojox.charting.Chart object), a Theme simplifies this manual setup by allowing you to
  12. // pre-define all of the various visual parameters of each element in a chart.
  13. //
  14. // Most of the properties of a Theme are straight-forward; if something is line-based (such as
  15. // an axis or the ticks on an axis), they will be defined using basic stroke parameters. Likewise,
  16. // if an element is primarily block-based (such as the background of a chart), it will be primarily
  17. // fill-based.
  18. //
  19. // In addition (for convenience), a Theme definition does not have to contain the entire JSON-based
  20. // structure. Each theme is built on top of a default theme (which serves as the basis for the theme
  21. // "GreySkies"), and is mixed into the default theme object. This allows you to create a theme based,
  22. // say, solely on colors for data series.
  23. //
  24. // Defining a new theme is relatively easy; see any of the themes in dojox.charting.themes for examples
  25. // on how to define your own.
  26. //
  27. // When you set a theme on a chart, the theme itself is deep-cloned. This means that you cannot alter
  28. // the theme itself after setting the theme value on a chart, and expect it to change your chart. If you
  29. // are looking to make alterations to a theme for a chart, the suggestion would be to create your own
  30. // theme, based on the one you want to use, that makes those alterations before it is applied to a chart.
  31. //
  32. // Finally, a Theme contains a number of functions to facilitate rendering operations on a chart--the main
  33. // helper of which is the ~next~ method, in which a chart asks for the information for the next data series
  34. // to be rendered.
  35. //
  36. // A note on colors:
  37. // The Theme constructor was on the use of dojox.color.Palette (in general) for creating a visually distinct
  38. // set of colors for usage in a chart. A palette is usually comprised of 5 different color definitions, and
  39. // no more. If you have a need to render a chart with more than 5 data elements, you can simply "push"
  40. // new color definitions into the theme's .color array. Make sure that you do that with the actual
  41. // theme object from a Chart, and not in the theme itself (i.e. either do that before using .setTheme
  42. // on a chart).
  43. //
  44. // example:
  45. // The default theme (and structure) looks like so:
  46. // | // all objects are structs used directly in dojox.gfx
  47. // | chart:{
  48. // | stroke: null,
  49. // | fill: "white",
  50. // | pageStyle: null // suggested page style as an object suitable for dojo.style()
  51. // | },
  52. // | plotarea:{
  53. // | stroke: null,
  54. // | fill: "white"
  55. // | },
  56. // | axis:{
  57. // | stroke: { // the axis itself
  58. // | color: "#333",
  59. // | width: 1
  60. // | },
  61. // | tick: { // used as a foundation for all ticks
  62. // | color: "#666",
  63. // | position: "center",
  64. // | font: "normal normal normal 7pt Tahoma", // labels on axis
  65. // | fontColor: "#333" // color of labels
  66. // | },
  67. // | majorTick: { // major ticks on axis, and used for major gridlines
  68. // | width: 1,
  69. // | length: 6
  70. // | },
  71. // | minorTick: { // minor ticks on axis, and used for minor gridlines
  72. // | width: 0.8,
  73. // | length: 3
  74. // | },
  75. // | microTick: { // minor ticks on axis, and used for minor gridlines
  76. // | width: 0.5,
  77. // | length: 1
  78. // | }
  79. // | },
  80. // | series: {
  81. // | stroke: {width: 1.5, color: "#333"}, // line
  82. // | outline: {width: 0.1, color: "#ccc"}, // outline
  83. // | //shadow: {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]},
  84. // | shadow: null, // no shadow
  85. // | fill: "#ccc", // fill, if appropriate
  86. // | font: "normal normal normal 8pt Tahoma", // if there's a label
  87. // | fontColor: "#000" // color of labels
  88. // | labelWiring: {width: 1, color: "#ccc"}, // connect marker and target data item(slice, column, bar...)
  89. // | },
  90. // | marker: { // any markers on a series
  91. // | symbol: "m-3,3 l3,-6 3,6 z", // symbol
  92. // | stroke: {width: 1.5, color: "#333"}, // stroke
  93. // | outline: {width: 0.1, color: "#ccc"}, // outline
  94. // | shadow: null, // no shadow
  95. // | fill: "#ccc", // fill if needed
  96. // | font: "normal normal normal 8pt Tahoma", // label
  97. // | fontColor: "#000"
  98. // | },
  99. // | indicator: {
  100. // | lineStroke: {width: 1.5, color: "#333"}, // line
  101. // | lineOutline: {width: 0.1, color: "#ccc"}, // line outline
  102. // | lineShadow: null, // no line shadow
  103. // | stroke: {width: 1.5, color: "#333"}, // label background stroke
  104. // | outline: {width: 0.1, color: "#ccc"}, // label background outline
  105. // | shadow: null, // no label background shadow
  106. // | fill: "#ccc", // label background fill
  107. // | radius: 3, // radius of the label background
  108. // | font: "normal normal normal 10pt Tahoma", // label font
  109. // | fontColor: "#000" // label color
  110. // | markerFill: "#ccc", // marker fill
  111. // | markerSymbol: "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0", // marker symbol
  112. // | markerStroke: {width: 1.5, color: "#333"}, // marker stroke
  113. // | markerOutline: {width: 0.1, color: "#ccc"}, // marker outline
  114. // | markerShadow: null, // no marker shadow
  115. // | }
  116. //
  117. // example:
  118. // Defining a new theme is pretty simple:
  119. // | dojox.charting.themes.Grasslands = new dojox.charting.Theme({
  120. // | colors: [ "#70803a", "#dde574", "#788062", "#b1cc5d", "#eff2c2" ]
  121. // | });
  122. // |
  123. // | myChart.setTheme(dojox.charting.themes.Grasslands);
  124. shapeSpaces: {shape: 1, shapeX: 1, shapeY: 1},
  125. constructor: function(kwArgs){
  126. // summary:
  127. // Initialize a theme using the keyword arguments. Note that the arguments
  128. // look like the example (above), and may include a few more parameters.
  129. kwArgs = kwArgs || {};
  130. // populate theme with defaults updating them if needed
  131. var def = Theme.defaultTheme;
  132. arr.forEach(["chart", "plotarea", "axis", "series", "marker", "indicator"], function(name){
  133. this[name] = lang.delegate(def[name], kwArgs[name]);
  134. }, this);
  135. // personalize theme
  136. if(kwArgs.seriesThemes && kwArgs.seriesThemes.length){
  137. this.colors = null;
  138. this.seriesThemes = kwArgs.seriesThemes.slice(0);
  139. }else{
  140. this.seriesThemes = null;
  141. this.colors = (kwArgs.colors || Theme.defaultColors).slice(0);
  142. }
  143. this.markerThemes = null;
  144. if(kwArgs.markerThemes && kwArgs.markerThemes.length){
  145. this.markerThemes = kwArgs.markerThemes.slice(0);
  146. }
  147. this.markers = kwArgs.markers ? lang.clone(kwArgs.markers) : lang.delegate(Theme.defaultMarkers);
  148. // set flags
  149. this.noGradConv = kwArgs.noGradConv;
  150. this.noRadialConv = kwArgs.noRadialConv;
  151. if(kwArgs.reverseFills){
  152. this.reverseFills();
  153. }
  154. // private housekeeping
  155. this._current = 0;
  156. this._buildMarkerArray();
  157. },
  158. clone: function(){
  159. // summary:
  160. // Clone the current theme.
  161. // returns: dojox.charting.Theme
  162. // The cloned theme; any alterations made will not affect the original.
  163. var theme = new Theme({
  164. // theme components
  165. chart: this.chart,
  166. plotarea: this.plotarea,
  167. axis: this.axis,
  168. series: this.series,
  169. marker: this.marker,
  170. // individual arrays
  171. colors: this.colors,
  172. markers: this.markers,
  173. indicator: this.indicator,
  174. seriesThemes: this.seriesThemes,
  175. markerThemes: this.markerThemes,
  176. // flags
  177. noGradConv: this.noGradConv,
  178. noRadialConv: this.noRadialConv
  179. });
  180. // copy custom methods
  181. arr.forEach(
  182. ["clone", "clear", "next", "skip", "addMixin", "post", "getTick"],
  183. function(name){
  184. if(this.hasOwnProperty(name)){
  185. theme[name] = this[name];
  186. }
  187. },
  188. this
  189. );
  190. return theme; // dojox.charting.Theme
  191. },
  192. clear: function(){
  193. // summary:
  194. // Clear and reset the internal pointer to start fresh.
  195. this._current = 0;
  196. },
  197. next: function(elementType, mixin, doPost){
  198. // summary:
  199. // Get the next color or series theme.
  200. // elementType: String?
  201. // An optional element type (for use with series themes)
  202. // mixin: Object?
  203. // An optional object to mix into the theme.
  204. // doPost: Boolean?
  205. // A flag to post-process the results.
  206. // returns: Object
  207. // An object of the structure { series, marker, symbol }
  208. var merge = dlu.merge, series, marker;
  209. if(this.colors){
  210. series = lang.delegate(this.series);
  211. marker = lang.delegate(this.marker);
  212. var color = new Color(this.colors[this._current % this.colors.length]), old;
  213. // modify the stroke
  214. if(series.stroke && series.stroke.color){
  215. series.stroke = lang.delegate(series.stroke);
  216. old = new Color(series.stroke.color);
  217. series.stroke.color = new Color(color);
  218. series.stroke.color.a = old.a;
  219. }else{
  220. series.stroke = {color: color};
  221. }
  222. if(marker.stroke && marker.stroke.color){
  223. marker.stroke = lang.delegate(marker.stroke);
  224. old = new Color(marker.stroke.color);
  225. marker.stroke.color = new Color(color);
  226. marker.stroke.color.a = old.a;
  227. }else{
  228. marker.stroke = {color: color};
  229. }
  230. // modify the fill
  231. if(!series.fill || series.fill.type){
  232. series.fill = color;
  233. }else{
  234. old = new Color(series.fill);
  235. series.fill = new Color(color);
  236. series.fill.a = old.a;
  237. }
  238. if(!marker.fill || marker.fill.type){
  239. marker.fill = color;
  240. }else{
  241. old = new Color(marker.fill);
  242. marker.fill = new Color(color);
  243. marker.fill.a = old.a;
  244. }
  245. }else{
  246. series = this.seriesThemes ?
  247. merge(this.series, this.seriesThemes[this._current % this.seriesThemes.length]) :
  248. this.series;
  249. marker = this.markerThemes ?
  250. merge(this.marker, this.markerThemes[this._current % this.markerThemes.length]) :
  251. series;
  252. }
  253. var symbol = marker && marker.symbol || this._markers[this._current % this._markers.length];
  254. var theme = {series: series, marker: marker, symbol: symbol};
  255. // advance the counter
  256. ++this._current;
  257. if(mixin){
  258. theme = this.addMixin(theme, elementType, mixin);
  259. }
  260. if(doPost){
  261. theme = this.post(theme, elementType);
  262. }
  263. return theme; // Object
  264. },
  265. skip: function(){
  266. // summary:
  267. // Skip the next internal color.
  268. ++this._current;
  269. },
  270. addMixin: function(theme, elementType, mixin, doPost){
  271. // summary:
  272. // Add a mixin object to the passed theme and process.
  273. // theme: dojox.charting.Theme
  274. // The theme to mixin to.
  275. // elementType: String
  276. // The type of element in question. Can be "line", "bar" or "circle"
  277. // mixin: Object|Array
  278. // The object or objects to mix into the theme.
  279. // doPost: Boolean
  280. // If true, run the new theme through the post-processor.
  281. // returns: dojox.charting.Theme
  282. // The new theme.
  283. if(lang.isArray(mixin)){
  284. arr.forEach(mixin, function(m){
  285. theme = this.addMixin(theme, elementType, m);
  286. }, this);
  287. }else{
  288. var t = {};
  289. if("color" in mixin){
  290. if(elementType == "line" || elementType == "area"){
  291. lang.setObject("series.stroke.color", mixin.color, t);
  292. lang.setObject("marker.stroke.color", mixin.color, t);
  293. }else{
  294. lang.setObject("series.fill", mixin.color, t);
  295. }
  296. }
  297. arr.forEach(["stroke", "outline", "shadow", "fill", "font", "fontColor", "labelWiring"], function(name){
  298. var markerName = "marker" + name.charAt(0).toUpperCase() + name.substr(1),
  299. b = markerName in mixin;
  300. if(name in mixin){
  301. lang.setObject("series." + name, mixin[name], t);
  302. if(!b){
  303. lang.setObject("marker." + name, mixin[name], t);
  304. }
  305. }
  306. if(b){
  307. lang.setObject("marker." + name, mixin[markerName], t);
  308. }
  309. });
  310. if("marker" in mixin){
  311. t.symbol = mixin.marker;
  312. }
  313. theme = dlu.merge(theme, t);
  314. }
  315. if(doPost){
  316. theme = this.post(theme, elementType);
  317. }
  318. return theme; // dojox.charting.Theme
  319. },
  320. post: function(theme, elementType){
  321. // summary:
  322. // Process any post-shape fills.
  323. // theme: dojox.charting.Theme
  324. // The theme to post process with.
  325. // elementType: String
  326. // The type of element being filled. Can be "bar" or "circle".
  327. // returns: dojox.charting.Theme
  328. // The post-processed theme.
  329. var fill = theme.series.fill, t;
  330. if(!this.noGradConv && this.shapeSpaces[fill.space] && fill.type == "linear"){
  331. if(elementType == "bar"){
  332. // transpose start and end points
  333. t = {
  334. x1: fill.y1,
  335. y1: fill.x1,
  336. x2: fill.y2,
  337. y2: fill.x2
  338. };
  339. }else if(!this.noRadialConv && fill.space == "shape" && (elementType == "slice" || elementType == "circle")){
  340. // switch to radial
  341. t = {
  342. type: "radial",
  343. cx: 0,
  344. cy: 0,
  345. r: 100
  346. };
  347. }
  348. if(t){
  349. return dlu.merge(theme, {series: {fill: t}});
  350. }
  351. }
  352. return theme; // dojox.charting.Theme
  353. },
  354. getTick: function(name, mixin){
  355. // summary:
  356. // Calculates and merges tick parameters.
  357. // name: String
  358. // Tick name, can be "major", "minor", or "micro".
  359. // mixin: Object?
  360. // Optional object to mix in to the tick.
  361. var tick = this.axis.tick, tickName = name + "Tick",
  362. merge = dlu.merge;
  363. if(tick){
  364. if(this.axis[tickName]){
  365. tick = merge(tick, this.axis[tickName]);
  366. }
  367. }else{
  368. tick = this.axis[tickName];
  369. }
  370. if(mixin){
  371. if(tick){
  372. if(mixin[tickName]){
  373. tick = merge(tick, mixin[tickName]);
  374. }
  375. }else{
  376. tick = mixin[tickName];
  377. }
  378. }
  379. return tick; // Object
  380. },
  381. inspectObjects: function(f){
  382. arr.forEach(["chart", "plotarea", "axis", "series", "marker", "indicator"], function(name){
  383. f(this[name]);
  384. }, this);
  385. if(this.seriesThemes){
  386. arr.forEach(this.seriesThemes, f);
  387. }
  388. if(this.markerThemes){
  389. arr.forEach(this.markerThemes, f);
  390. }
  391. },
  392. reverseFills: function(){
  393. this.inspectObjects(function(o){
  394. if(o && o.fill){
  395. o.fill = dgg.reverse(o.fill);
  396. }
  397. });
  398. },
  399. addMarker:function(/*String*/ name, /*String*/ segment){
  400. // summary:
  401. // Add a custom marker to this theme.
  402. // example:
  403. // | myTheme.addMarker("Ellipse", foo);
  404. this.markers[name] = segment;
  405. this._buildMarkerArray();
  406. },
  407. setMarkers:function(/*Object*/ obj){
  408. // summary:
  409. // Set all the markers of this theme at once. obj should be a
  410. // dictionary of keys and path segments.
  411. //
  412. // example:
  413. // | myTheme.setMarkers({ "CIRCLE": foo });
  414. this.markers = obj;
  415. this._buildMarkerArray();
  416. },
  417. _buildMarkerArray: function(){
  418. this._markers = [];
  419. for(var p in this.markers){
  420. this._markers.push(this.markers[p]);
  421. }
  422. }
  423. });
  424. /*=====
  425. dojox.charting.Theme.__DefineColorArgs = function(num, colors, hue, saturation, low, high, base, generator){
  426. // summary:
  427. // The arguments object that can be passed to define colors for a theme.
  428. // num: Number?
  429. // The number of colors to generate. Defaults to 5.
  430. // colors: String[]|dojo.Color[]?
  431. // A pre-defined set of colors; this is passed through to the Theme directly.
  432. // hue: Number?
  433. // A hue to base the generated colors from (a number from 0 - 359).
  434. // saturation: Number?
  435. // If a hue is passed, this is used for the saturation value (0 - 100).
  436. // low: Number?
  437. // An optional value to determine the lowest value used to generate a color (HSV model)
  438. // high: Number?
  439. // An optional value to determine the highest value used to generate a color (HSV model)
  440. // base: String|dojo.Color?
  441. // A base color to use if we are defining colors using dojox.color.Palette
  442. // generator: String?
  443. // The generator function name from dojox.color.Palette.
  444. this.num = num;
  445. this.colors = colors;
  446. this.hue = hue;
  447. this.saturation = saturation;
  448. this.low = low;
  449. this.high = high;
  450. this.base = base;
  451. this.generator = generator;
  452. }
  453. =====*/
  454. lang.mixin(Theme, {
  455. defaultMarkers: {
  456. CIRCLE: "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0",
  457. SQUARE: "m-3,-3 l0,6 6,0 0,-6 z",
  458. DIAMOND: "m0,-3 l3,3 -3,3 -3,-3 z",
  459. CROSS: "m0,-3 l0,6 m-3,-3 l6,0",
  460. X: "m-3,-3 l6,6 m0,-6 l-6,6",
  461. TRIANGLE: "m-3,3 l3,-6 3,6 z",
  462. TRIANGLE_INVERTED: "m-3,-3 l3,6 3,-6 z"
  463. },
  464. defaultColors:[
  465. // gray skies
  466. "#54544c", "#858e94", "#6e767a", "#948585", "#474747"
  467. ],
  468. defaultTheme: {
  469. // all objects are structs used directly in dojox.gfx
  470. chart:{
  471. stroke: null,
  472. fill: "white",
  473. pageStyle: null,
  474. titleGap: 20,
  475. titlePos: "top",
  476. titleFont: "normal normal bold 14pt Tahoma", // labels on axis
  477. titleFontColor: "#333"
  478. },
  479. plotarea:{
  480. stroke: null,
  481. fill: "white"
  482. },
  483. // TODO: label rotation on axis
  484. axis:{
  485. stroke: { // the axis itself
  486. color: "#333",
  487. width: 1
  488. },
  489. tick: { // used as a foundation for all ticks
  490. color: "#666",
  491. position: "center",
  492. font: "normal normal normal 7pt Tahoma", // labels on axis
  493. fontColor: "#333", // color of labels
  494. titleGap: 15,
  495. titleFont: "normal normal normal 11pt Tahoma", // labels on axis
  496. titleFontColor: "#333", // color of labels
  497. titleOrientation: "axis" // "axis": facing the axis, "away": facing away
  498. },
  499. majorTick: { // major ticks on axis, and used for major gridlines
  500. width: 1,
  501. length: 6
  502. },
  503. minorTick: { // minor ticks on axis, and used for minor gridlines
  504. width: 0.8,
  505. length: 3
  506. },
  507. microTick: { // minor ticks on axis, and used for minor gridlines
  508. width: 0.5,
  509. length: 1
  510. }
  511. },
  512. series: {
  513. // used as a "main" theme for series, sThemes augment it
  514. stroke: {width: 1.5, color: "#333"}, // line
  515. outline: {width: 0.1, color: "#ccc"}, // outline
  516. //shadow: {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]},
  517. shadow: null, // no shadow
  518. fill: "#ccc", // fill, if appropriate
  519. font: "normal normal normal 8pt Tahoma", // if there's a label
  520. fontColor: "#000", // color of labels
  521. labelWiring: {width: 1, color: "#ccc"} // connect marker and target data item(slice, column, bar...)
  522. },
  523. marker: { // any markers on a series
  524. stroke: {width: 1.5, color: "#333"}, // stroke
  525. outline: {width: 0.1, color: "#ccc"}, // outline
  526. //shadow: {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]},
  527. shadow: null, // no shadow
  528. fill: "#ccc", // fill if needed
  529. font: "normal normal normal 8pt Tahoma", // label
  530. fontColor: "#000"
  531. },
  532. indicator: {
  533. lineStroke: {width: 1.5, color: "#333"},
  534. lineOutline: {width: 0.1, color: "#ccc"},
  535. lineShadow: null,
  536. stroke: {width: 1.5, color: "#333"},
  537. outline: {width: 0.1, color: "#ccc"},
  538. shadow: null,
  539. fill : "#ccc",
  540. radius: 3,
  541. font: "normal normal normal 10pt Tahoma",
  542. fontColor: "#000",
  543. markerFill: "#ccc",
  544. markerSymbol: "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0",
  545. markerStroke: {width: 1.5, color: "#333"},
  546. markerOutline: {width: 0.1, color: "#ccc"},
  547. markerShadow: null
  548. }
  549. },
  550. defineColors: function(kwArgs){
  551. // summary:
  552. // Generate a set of colors for the theme based on keyword
  553. // arguments.
  554. // kwArgs: dojox.charting.Theme.__DefineColorArgs
  555. // The arguments object used to define colors.
  556. // returns: dojo.Color[]
  557. // An array of colors for use in a theme.
  558. //
  559. // example:
  560. // | var colors = dojox.charting.Theme.defineColors({
  561. // | base: "#369",
  562. // | generator: "compound"
  563. // | });
  564. //
  565. // example:
  566. // | var colors = dojox.charting.Theme.defineColors({
  567. // | hue: 60,
  568. // | saturation: 90,
  569. // | low: 30,
  570. // | high: 80
  571. // | });
  572. kwArgs = kwArgs || {};
  573. var l, c = [], n = kwArgs.num || 5; // the number of colors to generate
  574. if(kwArgs.colors){
  575. // we have an array of colors predefined, so fix for the number of series.
  576. l = kwArgs.colors.length;
  577. for(var i = 0; i < n; i++){
  578. c.push(kwArgs.colors[i % l]);
  579. }
  580. return c; // dojo.Color[]
  581. }
  582. if(kwArgs.hue){
  583. // single hue, generate a set based on brightness
  584. var s = kwArgs.saturation || 100, // saturation
  585. st = kwArgs.low || 30,
  586. end = kwArgs.high || 90;
  587. // we'd like it to be a little on the darker side.
  588. l = (end + st) / 2;
  589. // alternately, use "shades"
  590. return colorX.Palette.generate(
  591. colorX.fromHsv(kwArgs.hue, s, l), "monochromatic"
  592. ).colors;
  593. }
  594. if(kwArgs.generator){
  595. // pass a base color and the name of a generator
  596. return colorX.Palette.generate(kwArgs.base, kwArgs.generator).colors;
  597. }
  598. return c; // dojo.Color[]
  599. },
  600. generateGradient: function(fillPattern, colorFrom, colorTo){
  601. var fill = lang.delegate(fillPattern);
  602. fill.colors = [
  603. {offset: 0, color: colorFrom},
  604. {offset: 1, color: colorTo}
  605. ];
  606. return fill;
  607. },
  608. generateHslColor: function(color, luminance){
  609. color = new Color(color);
  610. var hsl = color.toHsl(),
  611. result = colorX.fromHsl(hsl.h, hsl.s, luminance);
  612. result.a = color.a; // add missing opacity
  613. return result;
  614. },
  615. generateHslGradient: function(color, fillPattern, lumFrom, lumTo){
  616. color = new Color(color);
  617. var hsl = color.toHsl(),
  618. colorFrom = colorX.fromHsl(hsl.h, hsl.s, lumFrom),
  619. colorTo = colorX.fromHsl(hsl.h, hsl.s, lumTo);
  620. colorFrom.a = colorTo.a = color.a; // add missing opacity
  621. return Theme.generateGradient(fillPattern, colorFrom, colorTo); // Object
  622. }
  623. });
  624. return Theme;
  625. });