• Edit
  • Download
    1. <!DOCTYPE html>
    2. <html>
    3.  
    4. <head>
    5. <meta charset="utf-8">
    6. <title>ZingSoft Demo</title>
    7. <script nonce="undefined" src="https://cdn.zingchart.com/zingchart.min.js"></script>
    8. <style>
    9. .chart--container {
    10. min-height: 530px;
    11. width: 100%;
    12. height: 100%;
    13. }
    14.  
    15. .zc-ref {
    16. display: none;
    17. }
    18. </style>
    19. </head>
    20.  
    21. <body>
    22. <div id="myChart" class="chart--container">
    23. <a class="zc-ref" href="https://www.zingchart.com/">Powered by ZingChart</a>
    24. </div>
    25. <script>
    26. ZC.LICENSE = ["569d52cefae586f634c54f86dc99e6a9", "b55b025e438fa8a98e32482b5f768ff5"];
    27. let aColorRange = ['#D36A67', '#E5896C', '#F9BC7F', '#F9DEA7', '#9CD8B1', '#91BAA0', '#389B96', '#425B5E'];
    28. let aDomain = [100000, 40000000]; // [mix,max]
    29.  
    30. let chartItems = {
    31. CA: {
    32. value: 38332521
    33. },
    34. OR: {
    35. value: 3930065
    36. },
    37. WA: {
    38. value: 6971406
    39. },
    40. NV: {
    41. value: 2790136
    42. },
    43. ID: {
    44. value: 1612136
    45. },
    46. UT: {
    47. value: 2900872
    48. },
    49. AZ: {
    50. value: 6626624
    51. },
    52. MT: {
    53. value: 1015165
    54. },
    55. WY: {
    56. value: 582658
    57. },
    58. CO: {
    59. value: 5268367
    60. },
    61. NM: {
    62. value: 2085287
    63. },
    64. AK: {
    65. value: 735132
    66. },
    67. HI: {
    68. value: 1404054
    69. },
    70. TX: {
    71. value: 26448193
    72. },
    73. OK: {
    74. value: 3850568
    75. },
    76. KS: {
    77. value: 2893957
    78. },
    79. NE: {
    80. value: 1868516
    81. },
    82. SD: {
    83. value: 844877
    84. },
    85. ND: {
    86. value: 723393
    87. },
    88. MN: {
    89. value: 5420380
    90. },
    91. IA: {
    92. value: 3090416
    93. },
    94. MO: {
    95. value: 6044171
    96. },
    97. AR: {
    98. value: 2959373
    99. },
    100. LA: {
    101. value: 4625470
    102. },
    103. MS: {
    104. value: 2991207
    105. },
    106. TN: {
    107. value: 6495978
    108. },
    109. KY: {
    110. value: 4395295
    111. },
    112. IL: {
    113. value: 12882135
    114. },
    115. WI: {
    116. value: 5742713
    117. },
    118. MI: {
    119. value: 9895622
    120. },
    121. IN: {
    122. value: 6570902
    123. },
    124. AL: {
    125. value: 4833722
    126. },
    127. GA: {
    128. value: 9992167
    129. },
    130. FL: {
    131. value: 19552860
    132. },
    133. SC: {
    134. value: 4774839
    135. },
    136. NC: {
    137. value: 9848060
    138. },
    139. VA: {
    140. value: 8260405
    141. },
    142. WV: {
    143. value: 1854304
    144. },
    145. OH: {
    146. value: 11570808
    147. },
    148. PA: {
    149. value: 12773801
    150. },
    151. DC: {
    152. value: 681170
    153. },
    154. MD: {
    155. value: 5928814
    156. },
    157. DE: {
    158. value: 925749
    159. },
    160. NJ: {
    161. value: 8899339
    162. },
    163. NY: {
    164. value: 19651127
    165. },
    166. CT: {
    167. value: 3596080
    168. },
    169. RI: {
    170. value: 1051511
    171. },
    172. MA: {
    173. value: 6692824
    174. },
    175. VT: {
    176. value: 626630
    177. },
    178. NH: {
    179. value: 1323459
    180. },
    181. ME: {
    182. value: 1328302
    183. }
    184. };
    185.  
    186. let chartConfig = {
    187. title: {
    188. text: 'Population By Province',
    189. align: 'left',
    190. fontSize: '14px'
    191. },
    192. shapes: [{
    193. type: 'zingchart.maps',
    194. options: {
    195. name: 'usa',
    196. scale: {
    197. type: 'quantize', // if you define threshold here your domain length must match your range length
    198. domain: aDomain, // [min,max]
    199. range: aColorRange
    200. },
    201. style: {
    202. tooltip: {
    203. backgroundColor: 'inherit',
    204. borderColor: '#FFF',
    205. borderWidth: '2px',
    206. fontColor: '#000',
    207. fontSize: '15px'
    208. },
    209. controls: {
    210. placement: 'br'
    211. },
    212. hoverState: {
    213. backgroundColor: 'transparent',
    214. borderColor: '#000',
    215. borderWidth: '2px'
    216. },
    217. items: chartItems,
    218. label: { // text displaying. Like valueBox
    219. fontSize: '8px',
    220. visible: true
    221. }
    222. },
    223. zoom: 1.1
    224. }
    225. }],
    226. choropleth: {
    227. legend: {
    228. align: 'left',
    229. verticalAlign: 'bottom',
    230. header: {
    231. text: 'Population Range'
    232. },
    233. item: {
    234. cursor: 'pointer',
    235. },
    236. items: [{
    237. text: ' > 100,000'
    238. }],
    239. marker: {
    240. cursor: 'pointer'
    241. }
    242. }
    243. }
    244. };
    245.  
    246. zingchart.loadModules('maps,maps-usa');
    247. zingchart.render({
    248. id: 'myChart',
    249. modules: 'choropleth',
    250. data: chartConfig,
    251. height: '100%',
    252. width: '100%',
    253. });
    254.  
    255. // Used to only bind events once. When the window re-sizes we don't need to overwrite the events
    256. let firstTimeLoad = true;
    257.  
    258. let leftOrRight = (value, left, right) => {
    259. let leftDiff = Math.abs(value - left);
    260. let rightDiff = Math.abs(value - right);
    261. return leftDiff < rightDiff ? true : false
    262. };
    263.  
    264. let isBetween = (value, left, right) => {
    265. return value > left && value < right;
    266. };
    267.  
    268. let thresholdIndex = (value, scale) => {
    269. for (let i = 0; i < scale.length; i++) {
    270. if (value < scale[i]) {
    271. return i;
    272. }
    273. }
    274. return scale.length;
    275. };
    276.  
    277. let quantizeIndex = (value, scale) => {
    278. let first = scale[0];
    279. let last = scale[scale.length - 1];
    280. for (let i = 0; i < scale.length; i++) {
    281. if (value <= first) {
    282. return 0;
    283. } else if (value >= last) {
    284. return scale.length - 1;
    285. } else if (i < scale.length - 1) {
    286. if (value == scale[i]) {
    287. return i;
    288. } else {
    289. let current = scale[i];
    290. let next = scale[i + 1];
    291. if (isBetween(value, current, next)) {
    292. return leftOrRight(value, current, next) ? i : i + 1;
    293. }
    294. }
    295. }
    296. }
    297. };
    298.  
    299. // define mix max for domain
    300. let quantize = (value, domain, range) => {
    301. let index = quantizeIndex(value, domain);
    302. return {
    303. range: range[index],
    304. domain: domain[index],
    305. group: index
    306. };
    307. };
    308.  
    309. let quantizeDomain = (aDomain, aRange) => {
    310. let iMin = aDomain[0];
    311. let iMax = aDomain[1];
    312. let iSlope = (iMax - iMin) / (aRange.length - 1);
    313. let aScale = [];
    314. for (let i = 0; i < aRange.length; i++) {
    315. aScale[i] = (iSlope * i + iMin);
    316. }
    317. return aScale;
    318. };
    319.  
    320. let generateDomain = (sType, aDomain, aRange) => {
    321. let aScale = aDomain;
    322. if (sType == 'quantize') {
    323. aScale = quantizeDomain(aDomain, aRange)
    324. }
    325. return aScale;
    326. };
    327.  
    328. let drawLegend = (domain, range, json) => {
    329. if (!json.series)
    330. json.series = [];
    331.  
    332. json.legend = json.choropleth.legend || {};
    333. for (let i = 0; i < domain.length; i++) {
    334. json.series[i] = {
    335. /*
    336. * merge text if user wants to define new text.
    337. * else format thousands separator
    338. */
    339. text: (json.legend.items && json.legend.items[i] && json.legend.items[i].text) ? json.legend.items[i].text : Math.round(domain[i]).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','),
    340. lineColor: range[i],
    341. backgroundColor: range,
    342. dataDomain: domain[i],
    343. dataVisible: true
    344. };
    345. }
    346. };
    347.  
    348. let legendClickForMaps = (e) => {
    349. let clickedDomain = e.xdata.domain;
    350. let plotIsVisible = e.xdata.visible;
    351. let plotIndex = e.plotindex;
    352. let json = zingchart.exec(e.id, 'getdata');
    353. json = json.graphset ? json.graphset[0] : json;
    354. let items = json.shapes;
    355. let toggleOffColor = '#c3c3c3';
    356. e.xdata.visible = !e.xdata.visible;
    357.  
    358. for (let i = 0; i < items.length; i++) {
    359. if (clickedDomain == items[i].domain) {
    360. if (plotIsVisible) {
    361. items[i]['background-color'] = toggleOffColor;
    362. } else {
    363. items[i]['background-color'] = items[i]['original-background-color'];
    364. }
    365. zingchart.exec(e.id, 'updateobject', {
    366. type: 'shape',
    367. data: items[i]
    368. });
    369. }
    370. }
    371. };
    372.  
    373. // define a range of thresholds for domain
    374. let threshold = (value, domain, range) => {
    375. let index = thresholdIndex(value, domain);
    376. return {
    377. range: range[index],
    378. domain: domain[index],
    379. group: index
    380. };
    381. };
    382.  
    383. /* custom module for choropleth charts */
    384. zingchart.defineModule('choropleth', 'plugin', (originalJson) => {
    385. if (originalJson.shapes[0].options) {
    386. let options = originalJson.shapes[0].options;
    387. let mapType = options.name;
    388. let scaleType = options.scale.type;
    389. let range = options.scale.range;
    390. let domain = generateDomain(scaleType, options.scale.domain, range);
    391. let scaleFunction = (scaleType == 'quantize' ? quantize : threshold);
    392.  
    393. // Initialize items object
    394. let items = {};
    395. // Iterate over options items
    396. for (let key in options.style.items) {
    397. let item = options.style.items[key];
    398. let name = item.name;
    399. let value = item.value;
    400. let rangeIndex = scaleFunction(value, domain, range);
    401. let keyInfo = zingchart.maps.getItemInfo(options.name, key)
    402. item['background-color'] = rangeIndex.range;
    403. item['original-background-color'] = rangeIndex.range;
    404. item['domain'] = rangeIndex.domain;
    405. item['tooltip'] = options.style.tooltip ? JSON.parse(JSON.stringify(options.style.tooltip)) : {};
    406. item['tooltip']['text'] = keyInfo.tooltip.text + ' <br>' + item.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    407. item['group'] = rangeIndex.group + 1;
    408.  
    409. // border color, font-color and background color can inherit
    410. if (item['tooltip']['border-color'] == 'inherit')
    411. item['tooltip']['border-color'] = rangeIndex.range;
    412. if (item['tooltip']['backgroundColor'] == 'inherit')
    413. item['tooltip']['backgroundColor'] = rangeIndex.range;
    414. if (item['tooltip']['background-color'] == 'inherit')
    415. item['tooltip']['background-color'] = rangeIndex.range;
    416. if (item['tooltip']['font-color'] == 'inherit')
    417. item['tooltip']['font-color'] = rangeIndex.range;
    418. }
    419.  
    420. // Draw the legend
    421. if (originalJson.choropleth.legend) {
    422. drawLegend(domain, range, originalJson);
    423.  
    424. // only bind events on first load
    425. if (firstTimeLoad) {
    426. zingchart.bind(null, 'legend_item_click', legendClickForMaps);
    427. zingchart.bind(null, 'legend_marker_click', legendClickForMaps);
    428. firstTimeLoad = false;
    429. }
    430. }
    431.  
    432. return originalJson;
    433. } else {
    434. console.error('Whoa there... You need an `options` object to set the styles.');
    435. }
    436. });
    437. </script>
    438. </body>
    439.  
    440. </html>
    1. <!DOCTYPE html>
    2. <html>
    3.  
    4. <head>
    5. <meta charset="utf-8">
    6. <title>ZingSoft Demo</title>
    7. <script src="https://cdn.zingchart.com/zingchart.min.js"></script>
    8. </head>
    9.  
    10. <body>
    11. <div id="myChart" class="chart--container">
    12. <a class="zc-ref" href="https://www.zingchart.com/">Powered by ZingChart</a>
    13. </div>
    14. </body>
    15.  
    16. </html>
    1. .chart--container {
    2. min-height: 530px;
    3. width: 100%;
    4. height: 100%;
    5. }
    6.  
    7. .zc-ref {
    8. display: none;
    9. }
    1. let aColorRange = ['#D36A67', '#E5896C', '#F9BC7F', '#F9DEA7', '#9CD8B1', '#91BAA0', '#389B96', '#425B5E'];
    2. let aDomain = [100000, 40000000]; // [mix,max]
    3.  
    4. let chartItems = {
    5. CA: {
    6. value: 38332521
    7. },
    8. OR: {
    9. value: 3930065
    10. },
    11. WA: {
    12. value: 6971406
    13. },
    14. NV: {
    15. value: 2790136
    16. },
    17. ID: {
    18. value: 1612136
    19. },
    20. UT: {
    21. value: 2900872
    22. },
    23. AZ: {
    24. value: 6626624
    25. },
    26. MT: {
    27. value: 1015165
    28. },
    29. WY: {
    30. value: 582658
    31. },
    32. CO: {
    33. value: 5268367
    34. },
    35. NM: {
    36. value: 2085287
    37. },
    38. AK: {
    39. value: 735132
    40. },
    41. HI: {
    42. value: 1404054
    43. },
    44. TX: {
    45. value: 26448193
    46. },
    47. OK: {
    48. value: 3850568
    49. },
    50. KS: {
    51. value: 2893957
    52. },
    53. NE: {
    54. value: 1868516
    55. },
    56. SD: {
    57. value: 844877
    58. },
    59. ND: {
    60. value: 723393
    61. },
    62. MN: {
    63. value: 5420380
    64. },
    65. IA: {
    66. value: 3090416
    67. },
    68. MO: {
    69. value: 6044171
    70. },
    71. AR: {
    72. value: 2959373
    73. },
    74. LA: {
    75. value: 4625470
    76. },
    77. MS: {
    78. value: 2991207
    79. },
    80. TN: {
    81. value: 6495978
    82. },
    83. KY: {
    84. value: 4395295
    85. },
    86. IL: {
    87. value: 12882135
    88. },
    89. WI: {
    90. value: 5742713
    91. },
    92. MI: {
    93. value: 9895622
    94. },
    95. IN: {
    96. value: 6570902
    97. },
    98. AL: {
    99. value: 4833722
    100. },
    101. GA: {
    102. value: 9992167
    103. },
    104. FL: {
    105. value: 19552860
    106. },
    107. SC: {
    108. value: 4774839
    109. },
    110. NC: {
    111. value: 9848060
    112. },
    113. VA: {
    114. value: 8260405
    115. },
    116. WV: {
    117. value: 1854304
    118. },
    119. OH: {
    120. value: 11570808
    121. },
    122. PA: {
    123. value: 12773801
    124. },
    125. DC: {
    126. value: 681170
    127. },
    128. MD: {
    129. value: 5928814
    130. },
    131. DE: {
    132. value: 925749
    133. },
    134. NJ: {
    135. value: 8899339
    136. },
    137. NY: {
    138. value: 19651127
    139. },
    140. CT: {
    141. value: 3596080
    142. },
    143. RI: {
    144. value: 1051511
    145. },
    146. MA: {
    147. value: 6692824
    148. },
    149. VT: {
    150. value: 626630
    151. },
    152. NH: {
    153. value: 1323459
    154. },
    155. ME: {
    156. value: 1328302
    157. }
    158. };
    159.  
    160. let chartConfig = {
    161. title: {
    162. text: 'Population By Province',
    163. align: 'left',
    164. fontSize: '14px'
    165. },
    166. shapes: [{
    167. type: 'zingchart.maps',
    168. options: {
    169. name: 'usa',
    170. scale: {
    171. type: 'quantize', // if you define threshold here your domain length must match your range length
    172. domain: aDomain, // [min,max]
    173. range: aColorRange
    174. },
    175. style: {
    176. tooltip: {
    177. backgroundColor: 'inherit',
    178. borderColor: '#FFF',
    179. borderWidth: '2px',
    180. fontColor: '#000',
    181. fontSize: '15px'
    182. },
    183. controls: {
    184. placement: 'br'
    185. },
    186. hoverState: {
    187. backgroundColor: 'transparent',
    188. borderColor: '#000',
    189. borderWidth: '2px'
    190. },
    191. items: chartItems,
    192. label: { // text displaying. Like valueBox
    193. fontSize: '8px',
    194. visible: true
    195. }
    196. },
    197. zoom: 1.1
    198. }
    199. }],
    200. choropleth: {
    201. legend: {
    202. align: 'left',
    203. verticalAlign: 'bottom',
    204. header: {
    205. text: 'Population Range'
    206. },
    207. item: {
    208. cursor: 'pointer',
    209. },
    210. items: [{
    211. text: ' > 100,000'
    212. }],
    213. marker: {
    214. cursor: 'pointer'
    215. }
    216. }
    217. }
    218. };
    219.  
    220. zingchart.loadModules('maps,maps-usa');
    221. zingchart.render({
    222. id: 'myChart',
    223. modules: 'choropleth',
    224. data: chartConfig,
    225. height: '100%',
    226. width: '100%',
    227. });
    228.  
    229. // Used to only bind events once. When the window re-sizes we don't need to overwrite the events
    230. let firstTimeLoad = true;
    231.  
    232. let leftOrRight = (value, left, right) => {
    233. let leftDiff = Math.abs(value - left);
    234. let rightDiff = Math.abs(value - right);
    235. return leftDiff < rightDiff ? true : false
    236. };
    237.  
    238. let isBetween = (value, left, right) => {
    239. return value > left && value < right;
    240. };
    241.  
    242. let thresholdIndex = (value, scale) => {
    243. for (let i = 0; i < scale.length; i++) {
    244. if (value < scale[i]) {
    245. return i;
    246. }
    247. }
    248. return scale.length;
    249. };
    250.  
    251. let quantizeIndex = (value, scale) => {
    252. let first = scale[0];
    253. let last = scale[scale.length - 1];
    254. for (let i = 0; i < scale.length; i++) {
    255. if (value <= first) {
    256. return 0;
    257. } else if (value >= last) {
    258. return scale.length - 1;
    259. } else if (i < scale.length - 1) {
    260. if (value == scale[i]) {
    261. return i;
    262. } else {
    263. let current = scale[i];
    264. let next = scale[i + 1];
    265. if (isBetween(value, current, next)) {
    266. return leftOrRight(value, current, next) ? i : i + 1;
    267. }
    268. }
    269. }
    270. }
    271. };
    272.  
    273. // define mix max for domain
    274. let quantize = (value, domain, range) => {
    275. let index = quantizeIndex(value, domain);
    276. return {
    277. range: range[index],
    278. domain: domain[index],
    279. group: index
    280. };
    281. };
    282.  
    283. let quantizeDomain = (aDomain, aRange) => {
    284. let iMin = aDomain[0];
    285. let iMax = aDomain[1];
    286. let iSlope = (iMax - iMin) / (aRange.length - 1);
    287. let aScale = [];
    288. for (let i = 0; i < aRange.length; i++) {
    289. aScale[i] = (iSlope * i + iMin);
    290. }
    291. return aScale;
    292. };
    293.  
    294. let generateDomain = (sType, aDomain, aRange) => {
    295. let aScale = aDomain;
    296. if (sType == 'quantize') {
    297. aScale = quantizeDomain(aDomain, aRange)
    298. }
    299. return aScale;
    300. };
    301.  
    302. let drawLegend = (domain, range, json) => {
    303. if (!json.series)
    304. json.series = [];
    305.  
    306. json.legend = json.choropleth.legend || {};
    307. for (let i = 0; i < domain.length; i++) {
    308. json.series[i] = {
    309. /*
    310. * merge text if user wants to define new text.
    311. * else format thousands separator
    312. */
    313. text: (json.legend.items && json.legend.items[i] && json.legend.items[i].text) ? json.legend.items[i].text : Math.round(domain[i]).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','),
    314. lineColor: range[i],
    315. backgroundColor: range,
    316. dataDomain: domain[i],
    317. dataVisible: true
    318. };
    319. }
    320. };
    321.  
    322. let legendClickForMaps = (e) => {
    323. let clickedDomain = e.xdata.domain;
    324. let plotIsVisible = e.xdata.visible;
    325. let plotIndex = e.plotindex;
    326. let json = zingchart.exec(e.id, 'getdata');
    327. json = json.graphset ? json.graphset[0] : json;
    328. let items = json.shapes;
    329. let toggleOffColor = '#c3c3c3';
    330. e.xdata.visible = !e.xdata.visible;
    331.  
    332. for (let i = 0; i < items.length; i++) {
    333. if (clickedDomain == items[i].domain) {
    334. if (plotIsVisible) {
    335. items[i]['background-color'] = toggleOffColor;
    336. } else {
    337. items[i]['background-color'] = items[i]['original-background-color'];
    338. }
    339. zingchart.exec(e.id, 'updateobject', {
    340. type: 'shape',
    341. data: items[i]
    342. });
    343. }
    344. }
    345. };
    346.  
    347. // define a range of thresholds for domain
    348. let threshold = (value, domain, range) => {
    349. let index = thresholdIndex(value, domain);
    350. return {
    351. range: range[index],
    352. domain: domain[index],
    353. group: index
    354. };
    355. };
    356.  
    357. /* custom module for choropleth charts */
    358. zingchart.defineModule('choropleth', 'plugin', (originalJson) => {
    359. if (originalJson.shapes[0].options) {
    360. let options = originalJson.shapes[0].options;
    361. let mapType = options.name;
    362. let scaleType = options.scale.type;
    363. let range = options.scale.range;
    364. let domain = generateDomain(scaleType, options.scale.domain, range);
    365. let scaleFunction = (scaleType == 'quantize' ? quantize : threshold);
    366.  
    367. // Initialize items object
    368. let items = {};
    369. // Iterate over options items
    370. for (let key in options.style.items) {
    371. let item = options.style.items[key];
    372. let name = item.name;
    373. let value = item.value;
    374. let rangeIndex = scaleFunction(value, domain, range);
    375. let keyInfo = zingchart.maps.getItemInfo(options.name, key)
    376. item['background-color'] = rangeIndex.range;
    377. item['original-background-color'] = rangeIndex.range;
    378. item['domain'] = rangeIndex.domain;
    379. item['tooltip'] = options.style.tooltip ? JSON.parse(JSON.stringify(options.style.tooltip)) : {};
    380. item['tooltip']['text'] = keyInfo.tooltip.text + ' <br>' + item.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    381. item['group'] = rangeIndex.group + 1;
    382.  
    383. // border color, font-color and background color can inherit
    384. if (item['tooltip']['border-color'] == 'inherit')
    385. item['tooltip']['border-color'] = rangeIndex.range;
    386. if (item['tooltip']['backgroundColor'] == 'inherit')
    387. item['tooltip']['backgroundColor'] = rangeIndex.range;
    388. if (item['tooltip']['background-color'] == 'inherit')
    389. item['tooltip']['background-color'] = rangeIndex.range;
    390. if (item['tooltip']['font-color'] == 'inherit')
    391. item['tooltip']['font-color'] = rangeIndex.range;
    392. }
    393.  
    394. // Draw the legend
    395. if (originalJson.choropleth.legend) {
    396. drawLegend(domain, range, originalJson);
    397.  
    398. // only bind events on first load
    399. if (firstTimeLoad) {
    400. zingchart.bind(null, 'legend_item_click', legendClickForMaps);
    401. zingchart.bind(null, 'legend_marker_click', legendClickForMaps);
    402. firstTimeLoad = false;
    403. }
    404. }
    405.  
    406. return originalJson;
    407. } else {
    408. console.error('Whoa there... You need an `options` object to set the styles.');
    409. }
    410. });