echarts = require("https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js")
upColor = '#00da3c';
downColor = '#ec0000';
<!-- toColumns = function(rawdata) { -->
<!-- // Initialize columns -->
<!-- const columns = {}; -->
<!-- // Get keys from first row (assumes all rows have the same keys) -->
<!-- const keys = Object.keys(rawdata[0]); -->
<!-- // Initialize empty arrays for each key -->
<!-- keys.forEach(key => { -->
<!-- columns[key] = []; -->
<!-- }); -->
<!-- // Populate columns -->
<!-- rawdata.forEach(row => { -->
<!-- keys.forEach(key => { -->
<!-- columns[key].push(row[key]); -->
<!-- }); -->
<!-- }); -->
<!-- return columns; -->
<!-- } -->
function calculateMA(dayCount, data) {
var result = [];
for (var i = 0, len = data.values.length; i < len; i++) {
if (i < dayCount) {
result.push('-');
continue;
}
var sum = 0;
for (var j = 0; j < dayCount; j++) {
sum += data.values[i - j][1];
}
result.push(+(sum / dayCount).toFixed(3));
}
return result;
}
function mycandleplot(data, name, div_name, width, height) {
var option = {
animation: false,
legend: {
bottom: 10,
left: 'center',
data: [name, 'MA7', 'MA14', 'MA21', 'MA30'],
textStyle: {
color: '#eee', // Light grey color for better visibility in dark mode
textShadowColor: '#000', // Black shadow
textShadowBlur: 2 // Blur effect to make the shadow softer
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
borderWidth: 1,
borderColor: '#ccc',
padding: 10,
textStyle: {
color: '#000'
},
position: function (pos, params, el, elRect, size) {
const obj = {
top: 10
};
obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30;
return obj;
}
},
axisPointer: {
link: [
{
xAxisIndex: 'all'
}
],
label: {
backgroundColor: '#777'
}
},
toolbox: {
feature: {
dataZoom: {
yAxisIndex: false
},
brush: {
type: ['lineX', 'clear']
}
}
},
brush: {
xAxisIndex: 'all',
brushLink: 'all',
outOfBrush: {
colorAlpha: 0.1
}
},
visualMap: {
show: false,
seriesIndex: 5,
dimension: 2,
pieces: [
{
value: -1,
color: downColor
},
{
value: 1,
color: upColor
}
]
},
grid: [
{
left: '10%',
right: '8%',
height: '50%'
},
{
left: '10%',
right: '8%',
top: '63%',
height: '16%'
}
],
xAxis: [
{
type: 'category',
data: data.categoryData,
boundaryGap: false,
axisLine: { onZero: false },
splitLine: { show: false },
min: 'dataMin',
max: 'dataMax',
axisPointer: {
z: 100
}
},
{
type: 'category',
gridIndex: 1,
data: data.categoryData,
boundaryGap: false,
axisLine: { onZero: false },
axisTick: { show: false },
splitLine: { show: false },
axisLabel: { show: false },
min: 'dataMin',
max: 'dataMax'
}
],
yAxis: [
{
scale: true,
splitArea: {
show: true
}
},
{
scale: true,
gridIndex: 1,
splitNumber: 2,
axisLabel: { show: false },
axisLine: { show: false },
axisTick: { show: false },
splitLine: { show: false }
}
],
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 1],
start: 80,
end: 100
},
{
show: true,
xAxisIndex: [0, 1],
type: 'slider',
top: '85%',
start: 80,
end: 100
}
],
series: [
{
name: name,
type: 'candlestick',
data: data.values,
itemStyle: {
color: upColor,
color0: downColor,
borderColor: undefined,
borderColor0: undefined
}
},
{
name: 'MA7',
type: 'line',
data: calculateMA(7, data),
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'MA14',
type: 'line',
data: calculateMA(14, data),
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'MA21',
type: 'line',
data: calculateMA(21, data),
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'MA30',
type: 'line',
data: calculateMA(30, data),
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'Volume',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
data: data.volumes
}
]
}
return draw_echart(option, div_name, width, height);
};
function draw_echart(option, div_name, w, h) {
var div = html`<div id=${div_name} style="width: ${w}px;height:${h}px;" ></div>`;
var chart = echarts.init(div);
chart.setOption(option);
return div;
}
function sparkbar(max) {
return x => htl.html`<div style="
background: lightblue;
width: ${100 * x / max}%;
float: right;
padding-right: 3px;
box-sizing: border-box;
overflow: visible;
display: flex;
justify-content: end;">${x.toLocaleString("en")}`
}