<!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 class="zc-favorites-wrap">
<strong class="zc-favorites-headline">Favorites (drag from above)</strong>
<div id="db" class="zc-favorites-db"></div>
</div> -->
</div>
<script>
ZC.LICENSE = ["xxx", "xxx"]; // Define Module Location
zingchart.MODULESDIR = 'https://cdn.zingchart.com/modules/';
// DEFINE DATA
// -----------------------------
// Data config
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;
// Main chart render location
let chartId = 'myChart';
// Favorites
let fbId = 'fb';
// INIT
// -----------------------------
// Append Amazon Script
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);
// 模擬獲取外部資料,並返回一個 JSON 物件
// Constantly fetch new data sets
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));
};
// 初始化
// LOAD EVENTS
// -----------------------------
// Run these after AWS script is init
function init() {
// Render the main demo
zingchart.render({
id: chartId,
width: '100%',
height: 430,
output: 'svg',
strictmode: true,
data: chartData, // 上面的小部件配置
events: {
load: loaded,
},
});
// Bind 'mousedown' action when you click/drag a chart
zingchart.bind(chartId, 'mousedown', md);
}
// CHART RENDERED
// -----------------------------
// Set CSS class to show chart after render
function loaded() {
let chart = document.querySelector('#' + chartId);
chart.classList.add('loaded');
}
// 判斷滑鼠事件是否是滑鼠左鍵的點選事件
// DEFINE 'MOUSE DOWN' FUNCTION
// -----------------------------
function md(p) {
// Early Exit: Element is not a button
if (p.ev.button !== 0) return;
// Add data
let wdata = getData(p, chartData);
// Early Exit: No data found
if (!wdata) return;
// Define data for 2nd location
chartDataFB.widgets = [wdata];
p.ev.preventDefault();
// Add data to Favorites
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() {
// Otherwise, create mouse functions and apply to the chart
// ---
// Get the Favorites DOM element
let fb = document.querySelector('#' + fbId);
// Early Exit: Not found
if (!fb) return;
// Position element
fb.style.top = p.ev.clientY - wdata.height / 2 + 'px';
fb.style.left = p.ev.clientX - wdata.width / 2 + 'px';
// Bind mouse movements
document.addEventListener('mousemove', mouseMove);
document.addEventListener('mouseup', mouseUp);
// Render 2nd chart in 'Favorites' DOM element
zingchart.render({
id: fbId,
width: wdata.width,
height: wdata.height,
output: 'svg',
strictmode: true,
data: chartDataFB,
});
}, 0);
// MOUSE FNS
// Mousemove
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';
}
// Mouseup
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);
}
}
// DEFINE 'GET DATA' FUNCTION
// -----------------------------
// Get the data from the clicked item
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>
- 效果圖