stack bilitz url = https://stackblitz.com/edit/stackblitz-starters-ws9ujj?file=src%2Fapp%2Fperformance-chart%2Fperformance-chart.component.ts
It should be exactly like this image, but when I change the data, it shifts directly and I did it with transformation scale to show it correctly. Otherwise, if you change the data a little, it will immediately get corrupted.
.
I tried with position:absulute, I tried the average, I created the time part myself, but I cannot fit it somehow. In a chart that starts with 1 second and ends with 5 seconds, there should be 0.5 spaces on the left and 2.5 spaces on the right, but with which calculation function can I do this?
I tried to give the width with calculator but I didn’t get any results
Even though I did everything to average, the bar and graph in these 2 functions are not centered.
createScenes(): void {
const scenes = [
{ time: 0.4, likes: 29, dislikes: 0, comments: 29, label: 'S1' },
{ time: 2.3, likes: 0, dislikes: 0, comments: 11, label: 'S2' },
{ time: 0.7, likes: 87, dislikes: 0, comments: 87, label: 'S3' },
{ time: 0.3, likes: 0, dislikes: 0, comments: 64, label: 'S4' },
{ time: 3.2, likes: 0, dislikes: 64, comments: 64, label: 'S5' },
{ time: 3.9, likes: 43, dislikes: 0, comments: 43, label: 'S6' },
{ time: 0.3, likes: 0, dislikes: 0, comments: 64, label: 'S7' },
{ time: 0.1, likes: 0, dislikes: 64, comments: 64, label: 'S8' },
{ time: 0.5, likes: 43, dislikes: 0, comments: 43, label: 'S9' },
{ time: 0.6, likes: 0, dislikes: 22, comments: 22, label: 'S10' },
{ time: 2.9, likes: 0, dislikes: 22, comments: 22, label: 'S11' },
];
const totalTime = scenes.reduce((total, scene) => total + scene.time, 0);
const containerWidth =
this.el.nativeElement.querySelector('#scene-container').clientWidth;
const sceneContainer =
this.el.nativeElement.querySelector('#scene-container');
scenes.forEach((scene, index) => {
const sceneElement = this.renderer.createElement('div');
this.renderer.addClass(sceneElement, 'scene');
const widthPixels = ((scene.time / totalTime) * containerWidth).toFixed(
10
);
this.renderer.setStyle(sceneElement, 'width', `${widthPixels}px`);
this.renderer.setStyle(sceneElement, 'margin-right', '3px');
const timeElement = this.renderer.createElement('span');
this.renderer.addClass(timeElement, 'time');
const timeText = this.renderer.createText(`${scene.time}`);
this.renderer.appendChild(timeElement, timeText);
this.renderer.appendChild(sceneElement, timeElement);
const barElement = this.renderer.createElement('div');
this.renderer.addClass(barElement, 'bar');
this.renderer.appendChild(sceneElement, barElement);
const labelElement = this.renderer.createElement('span');
this.renderer.addClass(labelElement, 'scene-label');
const labelText = this.renderer.createText(scene.label);
this.renderer.appendChild(labelElement, labelText);
this.renderer.appendChild(sceneElement, labelElement);
this.renderer.appendChild(sceneContainer, sceneElement);
});
}
createLineChart(): void {
const canvas = this.el.nativeElement.querySelector(
'#lineChart'
) as HTMLCanvasElement;
const scenes = [
{
duration: 0.4,
label: 'S1',
attention: 10,
emotion: 30,
positivity: 40,
negativity: 70,
},
{
duration: 2.3,
label: 'S2',
attention: 50,
emotion: 20,
positivity: 30,
negativity: 40,
},
{
duration: 0.7,
label: 'S3',
attention: 70,
emotion: 50,
positivity: 80,
negativity: 20,
},
{
duration: 0.3,
label: 'S4',
attention: 60,
emotion: 80,
positivity: 20,
negativity: 50,
},
{
duration: 3.2,
label: 'S5',
attention: 30,
emotion: 50,
positivity: 100,
negativity: 80,
},
{
duration: 3.9,
label: 'S6',
attention: 90,
emotion: 30,
positivity: 50,
negativity: 30,
},
{
duration: 0.3,
label: 'S7',
attention: 80,
emotion: 40,
positivity: 40,
negativity: 20,
},
{
duration: 0.1,
label: 'S8',
attention: 75,
emotion: 45,
positivity: 60,
negativity: 30,
},
{
duration: 0.5,
label: 'S9',
attention: 70,
emotion: 55,
positivity: 50,
negativity: 40,
},
{
duration: 0.6,
label: 'S10',
attention: 65,
emotion: 70,
positivity: 30,
negativity: 50,
},
{
duration: 2.9,
label: 'S11',
attention: 55,
emotion: 90,
positivity: 60,
negativity: 60,
},
];
let currentStart = 0;
const marginRight = 3;
const adjustedScenes = scenes.map((scene, index) => {
const adjustedStart = currentStart + index * (marginRight / 110);
currentStart += scene.duration;
return {
...scene,
start: adjustedStart,
};
});
this.chart = new Chart(canvas, {
type: 'line',
data: {
datasets: [
{
label: 'Attention',
data: adjustedScenes.map((scene) => ({
x: +(scene.start + scene.duration / 2).toFixed(6),
y: scene.attention,
})),
borderColor: '#00ffff',
tension: 0.4,
fill: false,
pointRadius: 5,
pointHoverRadius: 5,
},
{
label: 'Emotion',
data: adjustedScenes.map((scene) => ({
x: +(scene.start + scene.duration / 2).toFixed(6),
y: scene.emotion,
})),
borderColor: '#ff66ff',
tension: 0.4,
fill: false,
pointRadius: 5,
pointHoverRadius: 5,
},
{
label: 'Positivity',
data: adjustedScenes.map((scene) => ({
x: +(scene.start + scene.duration / 2).toFixed(6),
y: scene.positivity,
})),
borderColor: '#66ff66',
tension: 0.4,
fill: false,
pointRadius: 5,
pointHoverRadius: 5,
},
{
label: 'Negativity',
data: adjustedScenes.map((scene) => ({
x: +(scene.start + scene.duration / 2).toFixed(6),
y: scene.negativity,
})),
borderColor: '#ff3333',
tension: 0.4,
fill: false,
pointRadius: 5,
pointHoverRadius: 5,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
},
},
scales: {
x: {
type: 'linear',
position: 'bottom',
ticks: {
display: false,
},
grid: {
display: false,
},
},
y: {
ticks: {
display: false,
},
grid: {
display: false,
},
},
},
},
});
}