I have implement a large amount of code to display highchart
Below is the full code
my JS Code
const getBenchmarkChartSettings = (model, isEpd) => {
let isStrScore = model.isStrScore;
let metricSeries = reorderMetricSeries(model.series.metricSeries);
let generatedSeries = model.series.generatedSeries;
let benchmarkSeries = model.series.benchmarkSeries;
let pitSeries = getPitSeries(model);
_.forEach(metricSeries, s => { s.color = s.prop ? propColor : metricColor; });
_.forEach(generatedSeries, s => { s.color = genColor; });
_.forEach(benchmarkSeries, (s, i) => {
s.color = colors[i];
s.type = 'spline';
if (s.benchmarkLegend && s.benchmarkType) {
s.name = s.benchmarkLegend;
}
_.forEach(s.data, d => {
d.x = new Date(d.dataDate).getTime();
d.y = isStrScore ? defaultscores.indexOf(d.value) : parseFloat(d.value);
});
});
_.forEach(metricSeries, e => { e.minPointLength = 6; e.type = 'column'; });
_.forEach(generatedSeries, e => { e.minPointLength = 6; e.type = 'column'; });
let seriesRaw = _.union(metricSeries, generatedSeries, benchmarkSeries, pitSeries);
let series = _.filter(seriesRaw, { 'errorMessage': null });
let shiftedSeries = _.map(series, ser => _.assign({}, ser, {
data: _.map(ser.data, d => _.assign({}, d, { x: d.x }))
}));
let allDefaultScore = isStrScore && _(shiftedSeries).flatMap('data').flatMap('value').value()
.every(val => val === 'd');
_.forEach(shiftedSeries, e => {
// allow for series longer than 1000 elements
e.turboThreshold = 0;
_.forEach(e.data, d => {
if (!d.isPit) {
d.x = new Date(d.dataDate).getTime();
d.y = isStrScore ?
(allDefaultScore ? defaultCompanyScores.indexOf(d.value) : defaultscores.indexOf(d.value))
: parseFloat(d.value);
}
});
});
const getShiftedSeries = (shiftedSeries, date) => {
let maxYear = new Date(date).getFullYear();
let updatedShiftedSeries = _.map(shiftedSeries, o => {
if (!o.isPit) {
let sdata = o.data.filter(itm => new Date(itm.x).getFullYear() >= maxYear);
o.data = sdata;
if (sdata.length > 0) { return o; }
return null;
}
return o;
});
updatedShiftedSeries = _.without(updatedShiftedSeries, undefined || null);
return updatedShiftedSeries;
};
let maxDate = _.chain(shiftedSeries)
.map(o => _.maxBy(o.data, 'x'))
.filter(e => e !== undefined)
.map('x')
.max()
.value();
if (pitSeries) {
let pitAdjSeries = _.filter(shiftedSeries, { 'isPit': true });
pitAdjSeries[0].data[0].x = maxDate;
}
let minDate = _.chain(shiftedSeries)
.map(o => _.minBy(o.data, 'x'))
.filter(e => e !== undefined)
.map('x')
.min()
.value();
let dateBuffer = ((maxDate - minDate) * 0.1);
shiftedSeries = getShiftedSeries(shiftedSeries, minDate);
let hasOnlyFewStatements = _.filter(shiftedSeries, e =>
(e.name.indexOf('CIQ Data') > -1 || e.name.indexOf('Prop Data') > -1))
.reduce((dataPoints, { data }) => dataPoints.concat(data), [])
.length < 3;
let chartSettings = {
chart: {
width: 220,
height: 135,
spacingLeft: 0,
marginLeft: !isStrScore ? 25 : 12,
marginRight: 1,
backgroundColor: isEpd ? '#f2f2f2' : 'transparent',
plotBorderColor: '#9A9A9A',
plotBorderWidth: 1
},
title: {
text: null
},
credits: {
enabled: false
},
legend: {
align: 'left',
layout: 'horizontal',
verticalAlign: 'top',
alignColumns: false,
itemDistance: 0,
symbolHeight: 10,
symbolWidth: 6,
padding: 0,
width: 200,
symbolRadius: 0,
margin: 7,
itemMarginTop: 2,
itemStyle: {
fontSize: '4px'
},
y: -5,
x: !isStrScore ? 25 : 10
},
xAxis: [
{
type: 'datetime',
dateTimeLabelFormats: {
millisecond: '%b-%d-%Y',
second: '%b-%d-%Y',
minute: '%b-%d-%Y',
hour: '%b-%d-%Y',
day: '%b-%Y',
week: '%b-%Y',
month: '%b-%d-%Y',
year: '%Y'
},
labels: {
rotation: 0,
style: {
fontSize: '4px',
color: '#000'
},
y: 7,
x: isEpd ? -5 : !isStrScore ? 0 : (hasOnlyFewStatements ? 0 : -10)
},
min: minDate - dateBuffer,
max: maxDate + dateBuffer,
marginRight: 10,
gridLineColor: 'white',
gridLineWidth: 1,
lineWidth: 0.5,
minorGridLineWidth: 0,
lineColor: '#808080',
minorTickLength: 0,
tickLength: 0,
tickInterval: isEpd ? (364 * 24 * 60 * 60000) : (maxDate - minDate) > 32000000000 ? undefined :
(hasOnlyFewStatements ? undefined : 8000000000),
align: 'left'
}
],
yAxis: [
{
gridLineWidth: 0,
lineWidth: 0.5,
lineColor: '#808080',
minRange: 0,
min: 0,
ceiling: 100,
tickAmount: isStrScore ? undefined : 5,
labels: {
style: {
fontSize: '4px',
color: 'black'
},
x: -2,
y: isStrScore ? 7 : 3
},
title: {
text: !isStrScore ? '(PD%)' : '',
align: 'middle',
margin: 0,
x: -2,
rotation: -90,
ceiling: 100,
style: {
fontSize: '5px',
color: 'black'
},
labels: {
style: {
fontWeight: 'bold',
color: 'black',
fontSize: '2px'
},
x: -3
}
}
}
],
plotOptions: {
column: {
maxPointWidth: 10
},
series: {
states: {
hover: {
enabled: false
},
inactive: {
opacity: 1
}
},
enableMouseTracking: false,
borderWidth: 1,
borderColor: '#FFFFFF',
threshold: 0,
lineWidth: 1.5,
marker: {
enabled: false
},
minPointLength: 10,
dataLabels: {
enabled: true,
style: {
fontSize: '4px',
color: 'black',
textOutline: false
},
y: isLabelAdjustmentRequired(metricSeries, benchmarkSeries) ? -2 : undefined
}
}
},
series: shiftedSeries?.map(item => ({
...item,
data: item?.data.sort((a, b) => new Date(a.dataDate || null) - new Date(b.dataDate || null))
})) || []
};
if (isStrScore) {
chartSettings.yAxis[0].tickInterval = 4;
}
_.forEach(chartSettings.series, e => {
if (e.type === 'column' || e.isPit) {
e.dataLabels = {
padding: 1,
allowOverlap:true,
format: '<span style=\'font-size:4px;\'>{point.formattedValue}</span>' };
}
else if (e.type === 'spline') {
e.dataLabels = { enabled: false };
}
});
return chartSettings;
}
Below is the code, with this code higchart is displaying the overlapped values on chart
_.forEach(chartSettings.series, e => {
if (e.type === 'column' || e.isPit) {
e.dataLabels = {
padding: 1,
allowOverlap:true,
format: '<span style=\'font-size:4px;\'>{point.formattedValue}</span>' };
}
else if (e.type === 'spline') {
e.dataLabels = { enabled: false };
}
});
How to manage value displaying under chart shows proper, I have tried doing allowOverlap:false but it hide one of the value, even tried many thing but not able to get proper result like displaying values differently on chart.
Even tried finding answer on copilot and ChatGPT but still not get proper answer, the changes they ask me to do doesn't helped me.
MY data is coming something like below
0 = {
data: (2)[{… }, {… }]
0: {
formattedValue: '9.36%'
value: '9.36062867480189400'
x: 1640889000000
y: 9.360628674801895
}
1: {
formattedValue: '9.23%'
value: '9.23670432063350600'
x: 1672425000000
y: 9.236704320633507
[[Prototype]]: Object
}
}
1 = {
data: (1)[{… }]
0:
{
formattedValue: '9.23%'
value: '9.23670432063350600'
x: 1672425000000
y: 9.236704320633507
}
}
Here x and y axis for value 9.23 is coming same and because of that my data is displaying on same place, I have tried adding rotation like rotation: -45, and I am getting chart display as
But I dont want my value to rotate
then after I tried updating logic like below, but top:10px is not applying to my chart value
let previousX = null;
let previousY = null;
_.forEach(chartSettings.series, e => {
if (e.type === 'column' || e.isPit) {
_.forEach(e.data, point => {
let formatString = '<span style="font-size:4px;">{point.formattedValue}</span>';
if (previousX === point.x && previousY === point.y) {
formatString = '<span style="font-size:4px; position: relative; top: 10px;">{point.formattedValue}</span>'; // Adjust top position as needed
}
point.dataLabels = {
allowOverlap: true,
format: formatString
};
previousX = point.x;
previousY = point.y;
});
}
else if (e.type === 'spline') {
e.dataLabels = { enabled: false };
}
});
I have tried putting y which made to value top and then after start displaying label properly, matched the x and y axis with previous 1 if they matched it will set y as -6 which shift the label at top.
let previousX = null;
let previousY = null;
_.forEach(chartSettings.series, e => {
if (e.type === 'column' || e.isPit) {
_.forEach(e.data, point => {
let yOffset = undefined;
if (previousX === point.x && previousY === point.y) {
yOffset = -6;
}
point.dataLabels = {
allowOverlap: true,
format: '<span style=\'font-size:4px;\'>{point.formattedValue}</span>',
y: yOffset
};
previousX = point.x;
previousY = point.y;
});
}
else if (e.type === 'spline') {
e.dataLabels = { enabled: false };
}
});