fix: indicator panel overlap and performance optimizations
This commit is contained in:
@ -167,15 +167,11 @@ body {
|
|||||||
/* Indicator Panel (Sidebar/Modal Adaptation) */
|
/* Indicator Panel (Sidebar/Modal Adaptation) */
|
||||||
/* We will float the sidebar over the content or use it as a modal */
|
/* We will float the sidebar over the content or use it as a modal */
|
||||||
#rightSidebar {
|
#rightSidebar {
|
||||||
position: fixed;
|
/* Position handled by Tailwind classes in HTML */
|
||||||
top: 64px; /* Below header */
|
|
||||||
right: 0;
|
|
||||||
bottom: 64px; /* Above bottom nav */
|
|
||||||
width: 350px;
|
|
||||||
background-color: #1a2333;
|
background-color: #1a2333;
|
||||||
border-left: 1px solid #2d3a4f;
|
border-left: 1px solid #2d3a4f;
|
||||||
z-index: 40;
|
z-index: 40;
|
||||||
transform: translateX(100%);
|
/* Transform handled by Tailwind/Inline styles */
|
||||||
transition: transform 0.3s ease-in-out;
|
transition: transform 0.3s ease-in-out;
|
||||||
box-shadow: -4px 0 20px rgba(0,0,0,0.5);
|
box-shadow: -4px 0 20px rgba(0,0,0,0.5);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
BIN
ignore/indicator_panel issue.PNG
Normal file
BIN
ignore/indicator_panel issue.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 181 KiB |
@ -215,7 +215,7 @@
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- Sidebar Overlay (Acts as Modal) -->
|
<!-- Sidebar Overlay (Acts as Modal) -->
|
||||||
<div id="rightSidebar" class="collapsed fixed top-[64px] right-0 md:right-[72px] bottom-[64px] md:bottom-0 w-full max-w-[350px] bg-[#1a2333] border-l border-[#2d3a4f] shadow-2xl z-40 flex flex-col">
|
<div id="rightSidebar" class="collapsed fixed top-[64px] right-0 md:right-[72px] bottom-[64px] md:bottom-0 w-full max-w-[370px] bg-[#1a2333] border-l border-[#2d3a4f] shadow-2xl z-40 flex flex-col">
|
||||||
<div class="flex justify-between items-center p-3 border-b border-[#2d3a4f] bg-[#1a2333]">
|
<div class="flex justify-between items-center p-3 border-b border-[#2d3a4f] bg-[#1a2333]">
|
||||||
<!-- Hidden tab buttons triggers -->
|
<!-- Hidden tab buttons triggers -->
|
||||||
<div class="flex space-x-2">
|
<div class="flex space-x-2">
|
||||||
|
|||||||
@ -136,6 +136,19 @@ function formatDate(timestamp) {
|
|||||||
return TimezoneConfig.formatDate(timestamp);
|
return TimezoneConfig.formatDate(timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function throttle(func, limit) {
|
||||||
|
let inThrottle;
|
||||||
|
return function() {
|
||||||
|
const args = arguments;
|
||||||
|
const context = this;
|
||||||
|
if (!inThrottle) {
|
||||||
|
func.apply(context, args);
|
||||||
|
inThrottle = true;
|
||||||
|
setTimeout(() => inThrottle = false, limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class TradingDashboard {
|
export class TradingDashboard {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.chart = null;
|
this.chart = null;
|
||||||
@ -157,6 +170,9 @@ constructor() {
|
|||||||
this.dailyMAData = new Map(); // timestamp -> { ma44, ma125, price }
|
this.dailyMAData = new Map(); // timestamp -> { ma44, ma125, price }
|
||||||
this.currentMouseTime = null;
|
this.currentMouseTime = null;
|
||||||
|
|
||||||
|
// Throttled versions of heavy functions
|
||||||
|
this.throttledOnVisibleRangeChange = throttle(this.onVisibleRangeChange.bind(this), 150);
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -756,7 +772,6 @@ onVisibleRangeChange() {
|
|||||||
console.log(`[VisibleRange] Chart data (${data.length}) vs dataset (${allData?.length || 0}) differ, redrawing indicators...`);
|
console.log(`[VisibleRange] Chart data (${data.length}) vs dataset (${allData?.length || 0}) differ, redrawing indicators...`);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.drawIndicatorsOnChart?.();
|
|
||||||
this.loadSignals().catch(e => console.error('Error loading signals:', e));
|
this.loadSignals().catch(e => console.error('Error loading signals:', e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -966,16 +966,30 @@ class SeriesAreaFillRenderer {
|
|||||||
const color = this._source._color;
|
const color = this._source._color;
|
||||||
const ratio = scope.horizontalPixelRatio;
|
const ratio = scope.horizontalPixelRatio;
|
||||||
|
|
||||||
|
// Optimization: Get visible range to avoid iterating over thousands of historical points
|
||||||
|
const timeScale = chart.timeScale();
|
||||||
|
const visibleRange = timeScale.getVisibleLogicalRange();
|
||||||
|
if (!visibleRange) return;
|
||||||
|
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
|
|
||||||
let started = false;
|
let started = false;
|
||||||
|
|
||||||
|
// Find start and end indices in data based on visible range for massive performance boost
|
||||||
|
// Since data is sorted by time, we could use binary search, but even a linear scan
|
||||||
|
// with visibility check is better than drawing everything.
|
||||||
|
|
||||||
// Draw top line (upper) forward
|
// Draw top line (upper) forward
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
const point = data[i];
|
const point = data[i];
|
||||||
const timeCoordinate = chart.timeScale().timeToCoordinate(point.time);
|
const timeCoordinate = timeScale.timeToCoordinate(point.time);
|
||||||
if (timeCoordinate === null) continue;
|
|
||||||
|
// Skip points far outside the visible area
|
||||||
|
if (timeCoordinate === null) {
|
||||||
|
if (started) break; // We've passed the visible range
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const upperY = series.priceToCoordinate(point.upper);
|
const upperY = series.priceToCoordinate(point.upper);
|
||||||
if (upperY === null) continue;
|
if (upperY === null) continue;
|
||||||
@ -994,8 +1008,12 @@ class SeriesAreaFillRenderer {
|
|||||||
// Draw bottom line (lower) backward
|
// Draw bottom line (lower) backward
|
||||||
for (let i = data.length - 1; i >= 0; i--) {
|
for (let i = data.length - 1; i >= 0; i--) {
|
||||||
const point = data[i];
|
const point = data[i];
|
||||||
const timeCoordinate = chart.timeScale().timeToCoordinate(point.time);
|
const timeCoordinate = timeScale.timeToCoordinate(point.time);
|
||||||
if (timeCoordinate === null) continue;
|
|
||||||
|
if (timeCoordinate === null) {
|
||||||
|
if (started && i < data.length / 2) break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const lowerY = series.priceToCoordinate(point.lower);
|
const lowerY = series.priceToCoordinate(point.lower);
|
||||||
if (lowerY === null) continue;
|
if (lowerY === null) continue;
|
||||||
@ -1021,30 +1039,15 @@ function renderIndicatorOnPane(indicator, meta, instance, candles, paneIndex, li
|
|||||||
// Recalculate with current TF candles (or use cached if they exist and are the correct length)
|
// Recalculate with current TF candles (or use cached if they exist and are the correct length)
|
||||||
let results = indicator.cachedResults;
|
let results = indicator.cachedResults;
|
||||||
if (!results || !Array.isArray(results) || results.length !== candles.length) {
|
if (!results || !Array.isArray(results) || results.length !== candles.length) {
|
||||||
console.log(`[renderIndicatorOnPane] ${indicator.name}: Calling instance.calculate()...`);
|
// console.log(`[renderIndicatorOnPane] ${indicator.name}: Recalculating... (${candles.length} candles)`);
|
||||||
results = instance.calculate(candles);
|
results = instance.calculate(candles);
|
||||||
indicator.cachedResults = results;
|
indicator.cachedResults = results;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!results || !Array.isArray(results)) {
|
if (!results || !Array.isArray(results)) {
|
||||||
console.error(`[renderIndicatorOnPane] ${indicator.name}: Failed to get valid results (got ${typeof results})`);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.length !== candles.length) {
|
|
||||||
console.error(`[renderIndicatorOnPane] ${indicator.name}: MISMATCH! Expected ${candles.length} results but got ${results.length}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear previous series for this indicator
|
|
||||||
if (indicator.series && indicator.series.length > 0) {
|
|
||||||
indicator.series.forEach(s => {
|
|
||||||
try {
|
|
||||||
window.dashboard.chart.removeSeries(s);
|
|
||||||
} catch(e) {}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
indicator.series = [];
|
|
||||||
|
|
||||||
const lineStyle = lineStyleMap[indicator.params._lineType] || LightweightCharts.LineStyle.Solid;
|
const lineStyle = lineStyleMap[indicator.params._lineType] || LightweightCharts.LineStyle.Solid;
|
||||||
const lineWidth = indicator.params._lineWidth || 1;
|
const lineWidth = indicator.params._lineWidth || 1;
|
||||||
|
|
||||||
@ -1052,21 +1055,19 @@ function renderIndicatorOnPane(indicator, meta, instance, candles, paneIndex, li
|
|||||||
const firstNonNull = Array.isArray(results) ? results.find(r => r !== null && r !== undefined) : null;
|
const firstNonNull = Array.isArray(results) ? results.find(r => r !== null && r !== undefined) : null;
|
||||||
let isObjectResult = firstNonNull && typeof firstNonNull === 'object' && !Array.isArray(firstNonNull);
|
let isObjectResult = firstNonNull && typeof firstNonNull === 'object' && !Array.isArray(firstNonNull);
|
||||||
|
|
||||||
// Fallback: If results are all null (e.g. during warmup or MTF fetch),
|
|
||||||
// use metadata to determine if it SHOULD be an object result
|
|
||||||
if (!firstNonNull && meta.plots && meta.plots.length > 1) {
|
if (!firstNonNull && meta.plots && meta.plots.length > 1) {
|
||||||
isObjectResult = true;
|
isObjectResult = true;
|
||||||
}
|
}
|
||||||
// Also check if the only plot has a specific ID that isn't just a number
|
|
||||||
if (!firstNonNull && meta.plots && meta.plots.length === 1 && meta.plots[0].id !== 'value') {
|
if (!firstNonNull && meta.plots && meta.plots.length === 1 && meta.plots[0].id !== 'value') {
|
||||||
isObjectResult = true;
|
isObjectResult = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let plotsCreated = 0;
|
indicator.series = indicator.series || [];
|
||||||
|
let seriesIdx = 0;
|
||||||
|
|
||||||
// Special logic for Hurst fill
|
// Special logic for Hurst fill
|
||||||
let hurstFillData = [];
|
let hurstFillData = [];
|
||||||
const isFirstHurst = indicator.type === 'hurst' && activeIndicators.filter(ind => ind.type === 'hurst')[0].id === indicator.id;
|
const isFirstHurst = indicator.type === 'hurst' && activeIndicators.filter(ind => ind.type === 'hurst')[0]?.id === indicator.id;
|
||||||
|
|
||||||
meta.plots.forEach((plot, plotIdx) => {
|
meta.plots.forEach((plot, plotIdx) => {
|
||||||
if (isObjectResult) {
|
if (isObjectResult) {
|
||||||
@ -1075,17 +1076,13 @@ function renderIndicatorOnPane(indicator, meta, instance, candles, paneIndex, li
|
|||||||
}
|
}
|
||||||
|
|
||||||
const plotColor = indicator.params[`_color_${plotIdx}`] || plot.color || '#2962ff';
|
const plotColor = indicator.params[`_color_${plotIdx}`] || plot.color || '#2962ff';
|
||||||
|
|
||||||
const data = [];
|
const data = [];
|
||||||
|
|
||||||
for (let i = 0; i < candles.length; i++) {
|
for (let i = 0; i < candles.length; i++) {
|
||||||
let value;
|
let value;
|
||||||
if (isObjectResult) {
|
if (isObjectResult) {
|
||||||
value = results[i]?.[plot.id];
|
value = results[i]?.[plot.id];
|
||||||
|
|
||||||
// Collect fill data if this is Hurst
|
|
||||||
if (isFirstHurst && results[i]) {
|
if (isFirstHurst && results[i]) {
|
||||||
// Ensure we only add once per index
|
|
||||||
if (!hurstFillData[i]) hurstFillData[i] = { time: candles[i].time };
|
if (!hurstFillData[i]) hurstFillData[i] = { time: candles[i].time };
|
||||||
if (plot.id === 'upper') hurstFillData[i].upper = value;
|
if (plot.id === 'upper') hurstFillData[i].upper = value;
|
||||||
if (plot.id === 'lower') hurstFillData[i].lower = value;
|
if (plot.id === 'lower') hurstFillData[i].lower = value;
|
||||||
@ -1095,45 +1092,19 @@ function renderIndicatorOnPane(indicator, meta, instance, candles, paneIndex, li
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (value !== null && value !== undefined && typeof value === 'number' && Number.isFinite(value)) {
|
if (value !== null && value !== undefined && typeof value === 'number' && Number.isFinite(value)) {
|
||||||
data.push({
|
data.push({ time: candles[i].time, value: value });
|
||||||
time: candles[i].time,
|
|
||||||
value: value
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.length === 0) return;
|
if (data.length === 0) return;
|
||||||
|
|
||||||
let series;
|
let series = indicator.series[seriesIdx];
|
||||||
let plotLineStyle = lineStyle;
|
let plotLineStyle = lineStyle;
|
||||||
if (plot.style === 'dashed') plotLineStyle = LightweightCharts.LineStyle.Dashed;
|
if (plot.style === 'dashed') plotLineStyle = LightweightCharts.LineStyle.Dashed;
|
||||||
else if (plot.style === 'dotted') plotLineStyle = LightweightCharts.LineStyle.Dotted;
|
else if (plot.style === 'dotted') plotLineStyle = LightweightCharts.LineStyle.Dotted;
|
||||||
else if (plot.style === 'solid') plotLineStyle = LightweightCharts.LineStyle.Solid;
|
else if (plot.style === 'solid') plotLineStyle = LightweightCharts.LineStyle.Solid;
|
||||||
|
|
||||||
if (plot.type === 'histogram') {
|
const seriesOptions = {
|
||||||
series = window.dashboard.chart.addSeries(LightweightCharts.HistogramSeries, {
|
|
||||||
color: plotColor,
|
|
||||||
priceFormat: { type: 'price', precision: 0, minMove: 1 },
|
|
||||||
priceLineVisible: false,
|
|
||||||
lastValueVisible: false
|
|
||||||
}, paneIndex);
|
|
||||||
} else if (plot.type === 'baseline') {
|
|
||||||
series = window.dashboard.chart.addSeries(LightweightCharts.BaselineSeries, {
|
|
||||||
baseValue: { type: 'price', price: plot.baseValue || 0 },
|
|
||||||
topLineColor: plot.topLineColor || plotColor,
|
|
||||||
topFillColor1: plot.topFillColor1 || plotColor,
|
|
||||||
topFillColor2: '#00000000',
|
|
||||||
bottomFillColor1: '#00000000',
|
|
||||||
bottomColor: plot.bottomColor || '#00000000',
|
|
||||||
lineWidth: plot.width || indicator.params._lineWidth || lineWidth,
|
|
||||||
lineStyle: plotLineStyle,
|
|
||||||
title: plot.title || '',
|
|
||||||
priceLineVisible: false,
|
|
||||||
lastValueVisible: plot.lastValueVisible !== false,
|
|
||||||
priceFormat: { type: 'price', precision: 0, minMove: 1 }
|
|
||||||
}, paneIndex);
|
|
||||||
} else {
|
|
||||||
series = window.dashboard.chart.addSeries(LightweightCharts.LineSeries, {
|
|
||||||
color: plotColor,
|
color: plotColor,
|
||||||
lineWidth: plot.width || indicator.params._lineWidth || lineWidth,
|
lineWidth: plot.width || indicator.params._lineWidth || lineWidth,
|
||||||
lineStyle: plotLineStyle,
|
lineStyle: plotLineStyle,
|
||||||
@ -1141,14 +1112,35 @@ function renderIndicatorOnPane(indicator, meta, instance, candles, paneIndex, li
|
|||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
lastValueVisible: plot.lastValueVisible !== false,
|
lastValueVisible: plot.lastValueVisible !== false,
|
||||||
priceFormat: { type: 'price', precision: 0, minMove: 1 }
|
priceFormat: { type: 'price', precision: 0, minMove: 1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!series) {
|
||||||
|
// Create new series if it doesn't exist
|
||||||
|
if (plot.type === 'histogram') {
|
||||||
|
series = window.dashboard.chart.addSeries(LightweightCharts.HistogramSeries, seriesOptions, paneIndex);
|
||||||
|
} else if (plot.type === 'baseline') {
|
||||||
|
series = window.dashboard.chart.addSeries(LightweightCharts.BaselineSeries, {
|
||||||
|
...seriesOptions,
|
||||||
|
baseValue: { type: 'price', price: plot.baseValue || 0 },
|
||||||
|
topLineColor: plot.topLineColor || plotColor,
|
||||||
|
topFillColor1: plot.topFillColor1 || plotColor,
|
||||||
|
topFillColor2: '#00000000',
|
||||||
|
bottomFillColor1: '#00000000',
|
||||||
|
bottomColor: plot.bottomColor || '#00000000',
|
||||||
}, paneIndex);
|
}, paneIndex);
|
||||||
|
} else {
|
||||||
|
series = window.dashboard.chart.addSeries(LightweightCharts.LineSeries, seriesOptions, paneIndex);
|
||||||
|
}
|
||||||
|
indicator.series[seriesIdx] = series;
|
||||||
|
} else {
|
||||||
|
// Update existing series options
|
||||||
|
series.applyOptions(seriesOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
series.setData(data);
|
series.setData(data);
|
||||||
indicator.series.push(series);
|
seriesIdx++;
|
||||||
plotsCreated++;
|
|
||||||
|
|
||||||
// Attach RSI bands
|
// RSI bands
|
||||||
if (meta.name === 'RSI' && indicator.series.length > 0) {
|
if (meta.name === 'RSI' && indicator.series.length > 0) {
|
||||||
const mainSeries = indicator.series[0];
|
const mainSeries = indicator.series[0];
|
||||||
const overbought = indicator.params.overbought || 70;
|
const overbought = indicator.params.overbought || 70;
|
||||||
@ -1160,32 +1152,31 @@ function renderIndicatorOnPane(indicator, meta, instance, candles, paneIndex, li
|
|||||||
indicator.bands = indicator.bands || [];
|
indicator.bands = indicator.bands || [];
|
||||||
|
|
||||||
indicator.bands.push(mainSeries.createPriceLine({
|
indicator.bands.push(mainSeries.createPriceLine({
|
||||||
price: overbought,
|
price: overbought, color: '#787B86', lineWidth: 1,
|
||||||
color: '#787B86',
|
lineStyle: LightweightCharts.LineStyle.Dashed, axisLabelVisible: false, title: ''
|
||||||
lineWidth: 1,
|
|
||||||
lineStyle: LightweightCharts.LineStyle.Dashed,
|
|
||||||
axisLabelVisible: false,
|
|
||||||
title: ''
|
|
||||||
}));
|
}));
|
||||||
indicator.bands.push(mainSeries.createPriceLine({
|
indicator.bands.push(mainSeries.createPriceLine({
|
||||||
price: oversold,
|
price: oversold, color: '#787B86', lineWidth: 1,
|
||||||
color: '#787B86',
|
lineStyle: LightweightCharts.LineStyle.Dashed, axisLabelVisible: false, title: ''
|
||||||
lineWidth: 1,
|
|
||||||
lineStyle: LightweightCharts.LineStyle.Dashed,
|
|
||||||
axisLabelVisible: false,
|
|
||||||
title: ''
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Cleanup extra series if any
|
||||||
|
while (indicator.series.length > seriesIdx) {
|
||||||
|
const extra = indicator.series.pop();
|
||||||
|
try { window.dashboard.chart.removeSeries(extra); } catch(e) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Attach Hurst Fill Primitive
|
// Attach Hurst Fill Primitive
|
||||||
if (isFirstHurst && hurstFillData.length > 0 && indicator.series.length > 0) {
|
if (isFirstHurst && hurstFillData.length > 0 && indicator.series.length > 0) {
|
||||||
// Filter out incomplete data points
|
|
||||||
const validFillData = hurstFillData.filter(d => d && d.time && d.upper !== undefined && d.lower !== undefined);
|
const validFillData = hurstFillData.filter(d => d && d.time && d.upper !== undefined && d.lower !== undefined);
|
||||||
|
if (!indicator.fillPrimitive) {
|
||||||
// Attach to the first series (usually upper or lower band)
|
indicator.fillPrimitive = new SeriesAreaFillPrimitive(validFillData, 'rgba(128, 128, 128, 0.05)');
|
||||||
const fillPrimitive = new SeriesAreaFillPrimitive(validFillData, 'rgba(128, 128, 128, 0.05)');
|
indicator.series[0].attachPrimitive(indicator.fillPrimitive);
|
||||||
indicator.series[0].attachPrimitive(fillPrimitive);
|
} else {
|
||||||
|
indicator.fillPrimitive.setData(validFillData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1246,13 +1237,13 @@ export function drawIndicatorsOnChart() {
|
|||||||
|
|
||||||
const activeIndicators = getActiveIndicators();
|
const activeIndicators = getActiveIndicators();
|
||||||
|
|
||||||
// Remove all existing series
|
// Remove all existing series - OPTIMIZATION: Removed aggressive clearing to allow reuse
|
||||||
activeIndicators.forEach(ind => {
|
// activeIndicators.forEach(ind => {
|
||||||
ind.series?.forEach(s => {
|
// ind.series?.forEach(s => {
|
||||||
try { window.dashboard.chart.removeSeries(s); } catch(e) {}
|
// try { window.dashboard.chart.removeSeries(s); } catch(e) {}
|
||||||
});
|
// });
|
||||||
ind.series = [];
|
// ind.series = [];
|
||||||
});
|
// });
|
||||||
|
|
||||||
const lineStyleMap = {
|
const lineStyleMap = {
|
||||||
'solid': LightweightCharts.LineStyle.Solid,
|
'solid': LightweightCharts.LineStyle.Solid,
|
||||||
@ -1271,6 +1262,13 @@ export function drawIndicatorsOnChart() {
|
|||||||
// Process all indicators, filtering by visibility
|
// Process all indicators, filtering by visibility
|
||||||
activeIndicators.forEach(ind => {
|
activeIndicators.forEach(ind => {
|
||||||
if (ind.visible === false || ind.visible === 'false') {
|
if (ind.visible === false || ind.visible === 'false') {
|
||||||
|
// Hide existing series if they exist by setting empty data
|
||||||
|
if (ind.series && ind.series.length > 0) {
|
||||||
|
ind.series.forEach(s => s.setData([]));
|
||||||
|
}
|
||||||
|
if (ind.fillPrimitive) {
|
||||||
|
ind.fillPrimitive.setData([]);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user