I had this issue, for days…it felt like. Finally got a nice boilerplate setup with GPT4.
It pulls from 3 queries right now, and i label the values as such…you should be able to figure it out.
// Function to process series data from multiple queries
function processData(context) {
const seriesData = context.panel.data.series.flatMap((s) => {
if (s.refId === "A") {
// Assuming you've modified your query to include these fields
const sTime = s.fields.find((f) => f.name === 'Datetime').values.buffer || s.fields.find((f) => f.name === 'Datetime').values;
const sOpen = s.fields.find((f) => f.name === 'Open').values.buffer || s.fields.find((f) => f.name === 'Open').values;
const sHigh = s.fields.find((f) => f.name === 'High').values.buffer || s.fields.find((f) => f.name === 'High').values;
const sLow = s.fields.find((f) => f.name === 'Low').values.buffer || s.fields.find((f) => f.name === 'Low').values;
const sClose = s.fields.find((f) => f.name === 'Close').values.buffer || s.fields.find((f) => f.name === 'Close').values;
// Format data for candlestick chart
const candlestickData = sTime.map((time, index) => {
return [
time, // Datetime
parseFloat(sOpen[index]).toFixed(2), // Open
parseFloat(sClose[index]).toFixed(2), // Close
parseFloat(sLow[index]).toFixed(2), // Lowest
parseFloat(sHigh[index]).toFixed(2) // Highest
];
});
return [{
name: 'Price Movement',
type: 'candlestick',
data: candlestickData,
yAxisIndex: 0,
// Additional styling and options can be added here
}];
} else if (s.refId === "B") {
// Process data for 'Size'
const sTime = s.fields.find((f) => f.name === 'Time').values.buffer || s.fields.find((f) => f.name === 'Time').values;
const sSize = s.fields.find((f) => f.name === 'Size').values.buffer || s.fields.find((f) => f.name === 'Size').values;
return [{
name: 'Size',
type: 'bar',
showSymbol: false,
areaStyle: { opacity: 0.1 },
lineStyle: { width: 1 },
data: sTime.map((time, index) => [time, parseFloat(sSize[index]).toFixed(2)]),
yAxisIndex: 1,
}];
} else if (s.refId === "C") {
const sTime = s.fields.find((f) => f.name === 'Date').values.buffer || s.fields.find((f) => f.name === 'Date').values;
const sDataC = s.fields.find((f) => f.name === 'AtAskFilledSum').values.buffer || s.fields.find((f) => f.name === 'AtAskFilledSum').values;
const atBid = s.fields.find((f) => f.name === 'AtBidFilledSum').values.buffer || s.fields.find((f) => f.name === 'AtBidFilledSum').values;
const noMatch = s.fields.find((f) => f.name === 'NoMatchFilledSum').values.buffer || s.fields.find((f) => f.name === 'NoMatchFilledSum').values;
return [
{
name: 'AtAskFilledSum',
type: 'bar',
stack: 'total',
data: sTime.map((time, index) => [time, parseFloat(sDataC[index]).toFixed(2)]),
yAxisIndex: 1,
barWidth: '15', // Sets the width of the bars. Can be in percentage or absolute value in pixels.
itemStyle: {
color: '#ff4d4f', // Sets the color of the bars. Can be a single color or a gradient.
borderColor: '#333', // Border color of the bars.
borderWidth: 1, // Border width of the bars.
borderType: 'solid', // Border type. Other values: 'dashed', 'dotted'
shadowBlur: 10, // Shadow blur size. Greater value for bigger blur. Set to 0 to disable.
shadowColor: 'rgba(0, 0, 0, 0.5)', // Shadow color. Use RGBA values for transparency.
shadowOffsetX: 0, // Horizontal shadow offset.
shadowOffsetY: 0, // Vertical shadow offset.
opacity: 1.0, // Opacity of the bars. Range from 0 to 1.
},
emphasis: { // Styling for when a bar is hovered
itemStyle: {
color: '#67e0e3', // Color when a bar is hovered.
borderColor: '#67e0e3', // Border color when a bar is hovered.
borderWidth: 2, // Border width when a bar is hovered.
}
},
},
{
name: 'AtBidFilledSum',
type: 'bar',
stack: 'total',
data: sTime.map((time, index) => [time, parseFloat(atBid[index]).toFixed(2)]),
yAxisIndex: 1,
},
{
name: 'NoMatchFilledSum',
type: 'bar',
stack: 'total',
data: sTime.map((time, index) => [time, parseFloat(noMatch[index]).toFixed(2)]),
yAxisIndex: 1,
}
];
}
// No need for a return here; flatMap will flatten the arrays appropriately
});
// Configure the rest of the chart with the processed seriesData
return {
backgroundColor: 'transparent',
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow', // Recommended for bar charts to highlight the whole bar.
},
// Custom formatter function to display detailed information in the tooltip as needed.
},
legend: { left: '0', bottom: 'ee', data: seriesData.map(s => s.name), textStyle: { color: 'rgba(128, 128, 128, .9)' } },
toolbox: {
feature: {
// The dataZoom tool in the toolbox allows users to select a zoom area on the chart.
dataZoom: {
yAxisIndex: 'none', // This disables zooming on the y-axis, only allowing x-axis (time) zoom.
icon: { zoom: 'path://', back: 'path://' } // Icons can be customized here.
},
saveAsImage: {}
}
},
xAxis: { type: 'time' },
yAxis: [
{ type: 'value', min: 'dataMin' },
{ type: 'value', show: true } // Make sure the second y-axis is visible if needed.
],
grid: { left: '2%', right: '2%', top: '2%', bottom: '24%', containLabel: true },
series: seriesData,
dataZoom: [ // This is where the zoom and scrollbar functionality is configured.
{
type: 'inside', // Enables zooming via mouse scroll or touch gestures.
start: 0, // Initial zoom range start percentage.
end: 100 // Initial zoom range end percentage.
},
{
show: true, // Shows the zoom slider control at the bottom of the chart.
type: 'slider', // Type of dataZoom, a visible slider.
bottom: '15%', // Position of the slider.
start: 0, // Initial zoom range start percentage.
end: 100, // Initial zoom range end percentage.
height: '40', // Set the height of the slider. Adjust as needed.
handleSize: '20%',
moveHandleSize: 20,
handleStyle: {
color: '#fff', // Handle color
borderColor: '#666', // Handle border color
borderWidth: 1, // Handle border width
shadowBlur: 2, // Shadow blur effect for the handle
shadowColor: 'rgba(0, 0, 0, 0.6)', // Shadow color for the handle
shadowOffsetX: 1, // Horizontal shadow offset for the handle
shadowOffsetY: 2 // Vertical shadow offset for the handle
},
fillerColor: 'rgba(167,183,204,0.4)', // Color of the selected (zoomed) area in the slider.
backgroundColor: '#000000', // Background color of the slider area.
borderColor: '#ccc', // Border color of the slider.
}
],
};
}
// Use the function and pass the context to it
const echartConfig = processData(context); // Assuming 'context' is defined in your environment
return echartConfig;
How it works?
Query A- Select Datetime, Open etc etc
-Label the values as such and map them
-plot that series as a candlestick, give it options. etc etc
Query B- Select time, Size From database etc etc
-map it
-plot is as bars, give options etc etc
Query C-
Select Date, atask, atbid etc etc
-map it
-plot as bars, stack, give it opitions etc.
Then we define our regular chart options after that…
Your welcome