dynamic-loaded-chart.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  7. <title>Dynamic Loaded Column Chart</title>
  8. <link href="../../assets/styles.css" rel="stylesheet" />
  9. <style>
  10. body {
  11. background: #fff;
  12. }
  13. #wrap {
  14. margin: 45px auto;
  15. max-width: 800px;
  16. position: relative;
  17. }
  18. .chart-box {
  19. padding-left: 0;
  20. }
  21. #chart-year,
  22. #chart-quarter {
  23. width: 96%;
  24. max-width: 48%;
  25. box-shadow: none;
  26. padding-left: 0;
  27. padding-top: 20px;
  28. background: #fff;
  29. border: 1px solid #ddd;
  30. }
  31. #chart-year {
  32. float: left;
  33. position: relative;
  34. transition: 1s ease transform;
  35. z-index: 3;
  36. }
  37. #chart-year.chart-quarter-activated {
  38. transform: translateX(0);
  39. transition: 1s ease transform;
  40. }
  41. #chart-quarter {
  42. float: left;
  43. position: relative;
  44. z-index: -2;
  45. transition: 1s ease transform;
  46. }
  47. #chart-quarter.active {
  48. transition: 1.1s ease-in-out transform;
  49. transform: translateX(0);
  50. z-index: 1;
  51. }
  52. @media screen and (min-width: 480px) {
  53. #chart-year {
  54. transform: translateX(50%);
  55. }
  56. #chart-quarter {
  57. transform: translateX(-50%);
  58. }
  59. }
  60. select#model {
  61. display: none;
  62. position: absolute;
  63. top: -40px;
  64. left: 0;
  65. z-index: 2;
  66. cursor: pointer;
  67. transform: scale(0.8);
  68. }
  69. </style>
  70. <script>
  71. window.Promise ||
  72. document.write(
  73. '<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"><\/script>'
  74. )
  75. window.Promise ||
  76. document.write(
  77. '<script src="https://cdn.jsdelivr.net/npm/eligrey-classlist-js-polyfill@1.2.20171210/classList.min.js"><\/script>'
  78. )
  79. window.Promise ||
  80. document.write(
  81. '<script src="https://cdn.jsdelivr.net/npm/findindex_polyfill_mdn"><\/script>'
  82. )
  83. </script>
  84. <script src="https://cdn.jsdelivr.net/npm/react@16.12/umd/react.production.min.js"></script>
  85. <script src="https://cdn.jsdelivr.net/npm/react-dom@16.12/umd/react-dom.production.min.js"></script>
  86. <script src="https://cdn.jsdelivr.net/npm/prop-types@15.7.2/prop-types.min.js"></script>
  87. <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
  88. <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
  89. <script src="https://cdn.jsdelivr.net/npm/react-apexcharts@1.3.6/dist/react-apexcharts.iife.min.js"></script>
  90. <script>
  91. Apex = {
  92. chart: {
  93. toolbar: {
  94. show: false
  95. }
  96. },
  97. tooltip: {
  98. shared: false
  99. },
  100. legend: {
  101. show: false
  102. }
  103. }
  104. var colors = ['#008FFB', '#00E396', '#FEB019', '#FF4560', '#775DD0', '#00D9E9', '#FF66C3'];
  105. /**
  106. * Randomize array element order in-place.
  107. * Using Durstenfeld shuffle algorithm.
  108. */
  109. function shuffleArray(array) {
  110. for (var i = array.length - 1; i > 0; i--) {
  111. var j = Math.floor(Math.random() * (i + 1));
  112. var temp = array[i];
  113. array[i] = array[j];
  114. array[j] = temp;
  115. }
  116. return array;
  117. }
  118. var arrayData = [{
  119. y: 400,
  120. quarters: [{
  121. x: 'Q1',
  122. y: 120
  123. }, {
  124. x: 'Q2',
  125. y: 90
  126. }, {
  127. x: 'Q3',
  128. y: 100
  129. }, {
  130. x: 'Q4',
  131. y: 90
  132. }]
  133. }, {
  134. y: 430,
  135. quarters: [{
  136. x: 'Q1',
  137. y: 120
  138. }, {
  139. x: 'Q2',
  140. y: 110
  141. }, {
  142. x: 'Q3',
  143. y: 90
  144. }, {
  145. x: 'Q4',
  146. y: 110
  147. }]
  148. }, {
  149. y: 448,
  150. quarters: [{
  151. x: 'Q1',
  152. y: 70
  153. }, {
  154. x: 'Q2',
  155. y: 100
  156. }, {
  157. x: 'Q3',
  158. y: 140
  159. }, {
  160. x: 'Q4',
  161. y: 138
  162. }]
  163. }, {
  164. y: 470,
  165. quarters: [{
  166. x: 'Q1',
  167. y: 150
  168. }, {
  169. x: 'Q2',
  170. y: 60
  171. }, {
  172. x: 'Q3',
  173. y: 190
  174. }, {
  175. x: 'Q4',
  176. y: 70
  177. }]
  178. }, {
  179. y: 540,
  180. quarters: [{
  181. x: 'Q1',
  182. y: 120
  183. }, {
  184. x: 'Q2',
  185. y: 120
  186. }, {
  187. x: 'Q3',
  188. y: 130
  189. }, {
  190. x: 'Q4',
  191. y: 170
  192. }]
  193. }, {
  194. y: 580,
  195. quarters: [{
  196. x: 'Q1',
  197. y: 170
  198. }, {
  199. x: 'Q2',
  200. y: 130
  201. }, {
  202. x: 'Q3',
  203. y: 120
  204. }, {
  205. x: 'Q4',
  206. y: 160
  207. }]
  208. }];
  209. function makeData() {
  210. var dataSet = shuffleArray(arrayData)
  211. var dataYearSeries = [{
  212. x: "2011",
  213. y: dataSet[0].y,
  214. color: colors[0],
  215. quarters: dataSet[0].quarters
  216. }, {
  217. x: "2012",
  218. y: dataSet[1].y,
  219. color: colors[1],
  220. quarters: dataSet[1].quarters
  221. }, {
  222. x: "2013",
  223. y: dataSet[2].y,
  224. color: colors[2],
  225. quarters: dataSet[2].quarters
  226. }, {
  227. x: "2014",
  228. y: dataSet[3].y,
  229. color: colors[3],
  230. quarters: dataSet[3].quarters
  231. }, {
  232. x: "2015",
  233. y: dataSet[4].y,
  234. color: colors[4],
  235. quarters: dataSet[4].quarters
  236. }, {
  237. x: "2016",
  238. y: dataSet[5].y,
  239. color: colors[5],
  240. quarters: dataSet[5].quarters
  241. }];
  242. return dataYearSeries
  243. }
  244. function updateQuarterChart(sourceChart, destChartIDToUpdate) {
  245. var series = [];
  246. var seriesIndex = 0;
  247. var colors = []
  248. if (sourceChart.w.globals.selectedDataPoints[0]) {
  249. var selectedPoints = sourceChart.w.globals.selectedDataPoints;
  250. for (var i = 0; i < selectedPoints[seriesIndex].length; i++) {
  251. var selectedIndex = selectedPoints[seriesIndex][i];
  252. var yearSeries = sourceChart.w.config.series[seriesIndex];
  253. series.push({
  254. name: yearSeries.data[selectedIndex].x,
  255. data: yearSeries.data[selectedIndex].quarters
  256. })
  257. colors.push(yearSeries.data[selectedIndex].color)
  258. }
  259. if (series.length === 0) series = [{
  260. data: []
  261. }]
  262. return ApexCharts.exec(destChartIDToUpdate, 'updateOptions', {
  263. series: series,
  264. colors: colors,
  265. fill: {
  266. colors: colors
  267. }
  268. })
  269. }
  270. }
  271. </script>
  272. </head>
  273. <body>
  274. <div id="app"></div>
  275. <div id="html">
  276. &lt;div id=&quot;wrap&quot;&gt;
  277. &lt;select id=&quot;model&quot; class=&quot;flat-select&quot;
  278. onChange={() =&gt; this.changeData()}
  279. &gt;
  280. &lt;option value=&quot;iphone5&quot;&gt;iPhone 5&lt;/option&gt;
  281. &lt;option value=&quot;iphone6&quot;&gt;iPhone 6&lt;/option&gt;
  282. &lt;option value=&quot;iphone7&quot;&gt;iPhone 7&lt;/option&gt;
  283. &lt;/select&gt;
  284. &lt;div id=&quot;chart-year&quot;&gt;
  285. &lt;ReactApexChart options={this.state.options} series={this.state.series} type=&quot;bar&quot; height={400} /&gt;
  286. &lt;/div&gt;
  287. &lt;div id=&quot;chart-quarter&quot;&gt;
  288. &lt;ReactApexChart options={this.state.optionsQuarter} series={this.state.seriesQuarter} type=&quot;bar&quot; height={400} /&gt;
  289. &lt;/div&gt;
  290. &lt;/div&gt;
  291. </div>
  292. <script type="text/babel">
  293. class ApexChart extends React.Component {
  294. constructor(props) {
  295. super(props);
  296. this.state = {
  297. series: [{
  298. data: makeData()
  299. }],
  300. options: {
  301. chart: {
  302. id: 'barYear',
  303. height: 400,
  304. width: '100%',
  305. type: 'bar',
  306. events: {
  307. dataPointSelection: function (e, chart, opts) {
  308. var quarterChartEl = document.querySelector("#chart-quarter");
  309. var yearChartEl = document.querySelector("#chart-year");
  310. if (opts.selectedDataPoints[0].length === 1) {
  311. if (quarterChartEl.classList.contains("active")) {
  312. updateQuarterChart(chart, 'barQuarter')
  313. } else {
  314. yearChartEl.classList.add("chart-quarter-activated")
  315. quarterChartEl.classList.add("active");
  316. updateQuarterChart(chart, 'barQuarter')
  317. }
  318. } else {
  319. updateQuarterChart(chart, 'barQuarter')
  320. }
  321. if (opts.selectedDataPoints[0].length === 0) {
  322. yearChartEl.classList.remove("chart-quarter-activated")
  323. quarterChartEl.classList.remove("active");
  324. }
  325. },
  326. updated: function (chart) {
  327. updateQuarterChart(chart, 'barQuarter')
  328. }
  329. }
  330. },
  331. plotOptions: {
  332. bar: {
  333. distributed: true,
  334. horizontal: true,
  335. barHeight: '75%',
  336. dataLabels: {
  337. position: 'bottom'
  338. }
  339. }
  340. },
  341. dataLabels: {
  342. enabled: true,
  343. textAnchor: 'start',
  344. style: {
  345. colors: ['#fff']
  346. },
  347. formatter: function (val, opt) {
  348. return opt.w.globals.labels[opt.dataPointIndex]
  349. },
  350. offsetX: 0,
  351. dropShadow: {
  352. enabled: true
  353. }
  354. },
  355. colors: colors,
  356. states: {
  357. normal: {
  358. filter: {
  359. type: 'desaturate'
  360. }
  361. },
  362. active: {
  363. allowMultipleDataPointsSelection: true,
  364. filter: {
  365. type: 'darken',
  366. value: 1
  367. }
  368. }
  369. },
  370. tooltip: {
  371. x: {
  372. show: false
  373. },
  374. y: {
  375. title: {
  376. formatter: function (val, opts) {
  377. return opts.w.globals.labels[opts.dataPointIndex]
  378. }
  379. }
  380. }
  381. },
  382. title: {
  383. text: 'Yearly Results',
  384. offsetX: 15
  385. },
  386. subtitle: {
  387. text: '(Click on bar to see details)',
  388. offsetX: 15
  389. },
  390. yaxis: {
  391. labels: {
  392. show: false
  393. }
  394. }
  395. },
  396. seriesQuarter: [{
  397. data: []
  398. }],
  399. optionsQuarter: {
  400. chart: {
  401. id: 'barQuarter',
  402. height: 400,
  403. width: '100%',
  404. type: 'bar',
  405. stacked: true
  406. },
  407. plotOptions: {
  408. bar: {
  409. columnWidth: '50%',
  410. horizontal: false
  411. }
  412. },
  413. legend: {
  414. show: false
  415. },
  416. grid: {
  417. yaxis: {
  418. lines: {
  419. show: false,
  420. }
  421. },
  422. xaxis: {
  423. lines: {
  424. show: true,
  425. }
  426. }
  427. },
  428. yaxis: {
  429. labels: {
  430. show: false
  431. }
  432. },
  433. title: {
  434. text: 'Quarterly Results',
  435. offsetX: 10
  436. },
  437. tooltip: {
  438. x: {
  439. formatter: function (val, opts) {
  440. return opts.w.globals.seriesNames[opts.seriesIndex]
  441. }
  442. },
  443. y: {
  444. title: {
  445. formatter: function (val, opts) {
  446. return opts.w.globals.labels[opts.dataPointIndex]
  447. }
  448. }
  449. }
  450. }
  451. },
  452. };
  453. }
  454. changeData() {
  455. Apex.exec('barYear', 'updateSeries', [{
  456. data: makeData()
  457. }])
  458. }
  459. render() {
  460. return (
  461. <div>
  462. <div id="wrap">
  463. <select id="model" class="flat-select"
  464. onChange={() => this.changeData()}
  465. >
  466. <option value="iphone5">iPhone 5</option>
  467. <option value="iphone6">iPhone 6</option>
  468. <option value="iphone7">iPhone 7</option>
  469. </select>
  470. <div id="chart-year">
  471. <ReactApexChart options={this.state.options} series={this.state.series} type="bar" height={400} />
  472. </div>
  473. <div id="chart-quarter">
  474. <ReactApexChart options={this.state.optionsQuarter} series={this.state.seriesQuarter} type="bar" height={400} />
  475. </div>
  476. </div>
  477. <div id="html-dist"></div>
  478. </div>
  479. );
  480. }
  481. }
  482. const domContainer = document.querySelector('#app');
  483. ReactDOM.render(React.createElement(ApexChart), domContainer);
  484. </script>
  485. </body>
  486. </html>