| <!doctype html> |
| <html> |
| |
| <head> |
| <meta charset="utf-8"> |
| <title>ZingChart Demo: Financial Widget Dashboard</title> |
| <script nonce="undefined" src="./zingchart.min.js"></script> |
| <style> |
| .zc-body { |
| background: #fff; |
| } |
| |
| #myChart { |
| margin: 10px 0 20px; |
| opacity: 0; |
| visibility: hidden; |
| transition: opacity .3s; |
| } |
| |
| #myChart.loaded { |
| opacity: 1; |
| visibility: visible; |
| } |
| |
| .zc-demo { |
| margin: 0 auto; |
| width: 100%; |
| max-width: 910px; |
| } |
| |
| .zc-favorites { |
| z-index: 100; |
| position: absolute; |
| top: 0; |
| left: 0; |
| box-shadow: 3px 3px 3px #333; |
| } |
| |
| .zc-favorites-wrap { |
| margin-top: 10px; |
| margin: 0 auto; |
| padding: 10px; |
| min-height: 120px; |
| background: #ebebeb; |
| border: 0; |
| } |
| |
| .zc-favorites-headline { |
| font-size: 13px; |
| display: block; |
| margin-bottom: 7px; |
| } |
| |
| .zc-favorites-db { |
| display: grid; |
| grid-template-columns: repeat(4, 1fr); |
| grid-column-gap: 10px; |
| grid-row-gap: 10px; |
| } |
| |
| .zc-favorites-fb-db { |
| float: left; |
| } |
| |
| .zc-ref { |
| display: none; |
| } |
| </style> |
| </head> |
| |
| <body class="zc-body"> |
| |
| <div class="zc-demo"> |
| |
| <div id="myChart"> |
| <a href="https://www.zingchart.com/" rel="noopener" class="zc-ref">Powered by ZingChart</a> |
| </div> |
| |
| |
| |
| |
| |
| |
| </div> |
| |
| <script> |
| ZC.LICENSE = ["xxx", "xxx"]; |
| zingchart.MODULESDIR = 'https://cdn.zingchart.com/modules/'; |
| |
| |
| |
| |
| let chartData = { |
| type: 'null', |
| backgroundColor: '#ddd #eee', |
| height: '100%', |
| width: '100%', |
| widgets: [{ |
| type: 'exchange', |
| rate: 'EUR/USD', |
| colors: [ |
| ['#55154D', '#4E0E46'], '#fff', '#ccc' |
| ], |
| refresh: 500, |
| ticks: 100, |
| width: 450, |
| x: '10px', |
| y: '10px', |
| }, |
| { |
| type: 'exchange', |
| rate: 'USD/CAD', |
| colors: [ |
| ['#56000E', '#5F0017'], '#fff', '#ccc' |
| ], |
| x: '470px', |
| y: '10px', |
| }, |
| { |
| type: 'exchange', |
| rate: 'USD/JPY', |
| colors: [ |
| ['#014358', '#013D52'], '#fff', '#ccc' |
| ], |
| decimals: 2, |
| height: 200, |
| width: 200, |
| x: '700px', |
| y: '10px', |
| }, |
| { |
| type: 'exchange', |
| rate: 'BTC/USD', |
| colors: [ |
| ['#264031', '#243C2E'], '#fff', '#ccc' |
| ], |
| decimals: 2, |
| refresh: 200, |
| ticks: 60, |
| x: '10px', |
| y: '160px', |
| }, |
| { |
| type: 'exchange', |
| rate: 'CRUDE OIL WTI', |
| colors: [ |
| ['#264F14', '#244B13'], '#fff', '#ccc' |
| ], |
| decimals: 2, |
| x: '240px', |
| y: '160px', |
| }, |
| { |
| type: 'exchange', |
| rate: 'GOLD', |
| colors: [ |
| ['#704F00', '#6B4A00'], '#fff', '#ccc' |
| ], |
| decimals: 2, |
| height: 260, |
| refresh: 2000, |
| x: '470px', |
| y: '160px', |
| }, |
| { |
| type: 'exchange', |
| rate: 'GBP/USD', |
| colors: [ |
| ['#262400', '#242200'], '#fff', '#ccc' |
| ], |
| height: 110, |
| x: '10px', |
| y: '310px', |
| }, |
| { |
| type: 'exchange', |
| rate: 'NZD/USD', |
| colors: [ |
| ['#260031', '#24002E'], '#fff', '#ccc' |
| ], |
| height: 110, |
| x: '240px', |
| y: '310px', |
| }, |
| { |
| type: 'exchange', |
| rate: 'USD/CHF', |
| colors: [ |
| ['#363636', '#333333'], '#fff', '#ccc' |
| ], |
| height: 200, |
| width: 200, |
| x: '700px', |
| y: '220px', |
| }, |
| ], |
| }; |
| |
| |
| let chartDataFB = { |
| backgroundColor: '#ddd #eee', |
| type: 'null', |
| widgets: [], |
| }; |
| let SEQ = 0; |
| |
| |
| let chartId = 'myChart'; |
| |
| |
| let fbId = 'fb'; |
| |
| |
| |
| |
| let aws = document.createElement('script'); |
| aws.src = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/widgets.js'; |
| document.body.appendChild(aws); |
| aws.addEventListener('load', init); |
| |
| |
| |
| window.fetchData = function(rate, callback) { |
| let oRefValues = { |
| 'EUR/USD': 1.1143, |
| 'USD/JPY': 120.88, |
| 'USD/CAD': 1.2219, |
| 'BTC/USD': 232.71, |
| 'CRUDE OIL WTI': 58.59, |
| GOLD: 1208.21, |
| 'GBP/USD': 1.552, |
| 'NZD/USD': 0.7368, |
| 'USD/CHF': 0.9364, |
| }; |
| let fRefValue = oRefValues[rate], |
| fDiff = fRefValue / 100; |
| oRefValues[rate] = fRefValue + (-fDiff / 2 + fDiff * Math.random()); |
| let json = { |
| rate: rate, |
| ts: 100 * Math.round(new Date().getTime() / 100), |
| value: oRefValues[rate], |
| }; |
| callback.call(window, JSON.stringify(json)); |
| }; |
| |
| |
| |
| |
| |
| function init() { |
| |
| zingchart.render({ |
| id: chartId, |
| width: '100%', |
| height: 430, |
| output: 'svg', |
| strictmode: true, |
| data: chartData, |
| events: { |
| load: loaded, |
| }, |
| }); |
| |
| |
| zingchart.bind(chartId, 'mousedown', md); |
| } |
| |
| |
| |
| |
| function loaded() { |
| let chart = document.querySelector('#' + chartId); |
| chart.classList.add('loaded'); |
| } |
| |
| |
| |
| |
| function md(p) { |
| |
| if (p.ev.button !== 0) return; |
| |
| let wdata = getData(p, chartData); |
| |
| if (!wdata) return; |
| |
| |
| chartDataFB.widgets = [wdata]; |
| p.ev.preventDefault(); |
| |
| |
| let appendData = |
| '<div id="fb" class="zc-favorites" style="width:' + |
| wdata.width + |
| 'px;height:' + |
| wdata.height + |
| 'px;"></div>'; |
| document.body.insertAdjacentHTML('beforeend', appendData); |
| |
| |
| setTimeout(function() { |
| |
| |
| |
| let fb = document.querySelector('#' + fbId); |
| |
| if (!fb) return; |
| |
| |
| fb.style.top = p.ev.clientY - wdata.height / 2 + 'px'; |
| fb.style.left = p.ev.clientX - wdata.width / 2 + 'px'; |
| |
| |
| document.addEventListener('mousemove', mouseMove); |
| document.addEventListener('mouseup', mouseUp); |
| |
| |
| zingchart.render({ |
| id: fbId, |
| width: wdata.width, |
| height: wdata.height, |
| output: 'svg', |
| strictmode: true, |
| data: chartDataFB, |
| }); |
| }, 0); |
| |
| |
| |
| |
| function mouseMove(ev) { |
| ev.preventDefault(); |
| let fb = document.querySelector('#' + fbId); |
| let doc = document.documentElement; |
| let body = document.body; |
| let offsetTop = doc.scrollTop ? doc.scrollTop : document.body.scrollTop; |
| fb.style.top = ev.clientY - wdata.height / 2 + offsetTop + 'px'; |
| fb.style.left = ev.clientX - wdata.width / 2 + 'px'; |
| } |
| |
| |
| function mouseUp(ev) { |
| let fb = document.querySelector('#' + fbId); |
| if (fb) { |
| let db = document.querySelector('#db'); |
| let dbData = '<div id="fb' + SEQ + '" class="zc-favorites-fb-db"></div>'; |
| db.insertAdjacentHTML('beforeend', dbData); |
| zingchart.render({ |
| id: fbId + SEQ, |
| width: wdata.width, |
| height: wdata.height, |
| output: 'svg', |
| strictmode: true, |
| data: chartDataFB, |
| }); |
| SEQ++; |
| fb.remove(); |
| zingchart.exec(fbId, 'destroy'); |
| } |
| document.removeEventListener('mousemove', mouseMove); |
| document.removeEventListener('mouseup', mouseUp); |
| } |
| } |
| |
| |
| |
| |
| function getData(p, data) { |
| if (!data) return; |
| let wdata; |
| for (let w = 0; w < data.widgets.length; w++) { |
| let rate = data.widgets[w].rate; |
| let id = p.id + '-graph-' + p.id + rate.replace(/[^a-zA-Z0-9]/g, ''); |
| if (id === p.graphid) { |
| wdata = data.widgets[w]; |
| wdata.x = 0; |
| wdata.y = 0; |
| wdata.width = 220; |
| wdata.height = 100; |
| } |
| } |
| return wdata; |
| } |
| </script> |
| </body> |
| |
| </html> |
- 效果图

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?