ChartJS with dates on the X axis not displaying any graph - chart.js

I have a Vue.JS project getting data from a REST API (mine, so I can modify it if needed). This data is formatted for Chart.JS.
I am supposed to display a graph with 3 datasets, 2 of type line with the same X values, but 1 of type bar with different X values (that's why I don't want to specify labels). Whatever, all the X values are dates, so I would like only 1 X axis for all the curves.
I am using datasets with (x,y) data format :
x is an ISO8601 date
y is a float
My problem is that NOTHING is displayed at all...could anyone help me please, I don't understand why. I feel like having done things right. I saw somewhere that I needed to include momentjs, but in the official documentation they say that it is not the case. I bet that the problems come from the dates because I tried changing the y values, and the 2 y axis bounds are modified (so y values are understood). I also tried addind the "xAxisID" option, nothing changed.
Here is a sample of my data (normally hundreds of values) :
{
"type": "line",
"data": {
"datasets": [
{
"label": "Température",
"borderColor": "red",
"backgroundColor": "red",
"fill": false,
"data": [
{
"x": "2020-07-05T15:38:47.933711",
"y": 2.8224692
},
{
"x": "2020-07-05T15:48:47.490669",
"y": 33.63129
},
{
"x": "2020-07-05T15:58:48.182698",
"y": 40.540405
},
{
"x": "2020-07-05T16:08:47.829882",
"y": 3.0312533
},
{
"x": "2020-07-05T16:18:47.489026",
"y": 49.145626
}
],
"yAxisID": "yAxeTemperature"
},
{
"label": "Humidité",
"borderColor": "blue",
"backgroundColor": "blue",
"fill": false,
"data": [
{
"x": "2020-07-05T15:38:47.933711",
"y": 33.980587
},
{
"x": "2020-07-05T15:48:47.490669",
"y": 2.0313625
},
{
"x": "2020-07-05T15:58:48.182698",
"y": 24.249685
},
{
"x": "2020-07-05T16:08:47.829882",
"y": 7.4426904
},
{
"x": "2020-07-05T16:18:47.489026",
"y": 2.6335742
},
{
"x": "2020-07-05T16:28:48.175547",
"y": 25.92827
}
],
"yAxisID": "yAxeHumidite"
}
]
},
"options": {
"responsive": true,
"hoverMode": "index",
"stacked": false,
"title": null,
"scales": {
"xAxes": [
{
"type": "time",
"display": true,
"position": "bottom",
"id": "xAxeTime",
"scaleLabel": {
"display": true,
"labelString": "Temps",
"fontColor": "black"
},
"time": {
"unit": "minute",
"parser": "moment.ISO_8601",
"tooltipFormat": "ll"
}
}
],
"yAxes": [
{
"type": "linear",
"display": true,
"position": "left",
"id": "yAxeTemperature",
"scaleLabel": {
"display": true,
"labelString": "Température",
"fontColor": "red"
}
},
{
"type": "linear",
"display": true,
"position": "left",
"id": "yAxeHumidite",
"scaleLabel": {
"display": true,
"labelString": "Humidité",
"fontColor": "blue"
}
}
]
}
}
}
Here is how my chart is created (using vue-chartjs and chart.js) :
createChart(chartId : string, chartData : GrapheBean) {
const ctx = document.getElementById(chartId);
// #ts-ignore
const myChart = new Chart(ctx, {
type: chartData.type,
data: chartData.data,
options: chartData.options,
});
}
Here is the result :
I am stuck now, even if still trying things with little hope. Thanks a lot in advance for the ones who could help me.

First you should remove the option xAxes.time.parser. It is not needed when the dates are of ISO8601 format.
Further Chart.js effectively internally uses Moment.js for the functionality of the time axis. Therefore you should use the bundled version of Chart.js that includes Moment.js in a single file.
Please have a look at your amended code in a pure JavaScript version.
const chartData = {
"type": "line",
"data": {
"datasets": [{
"label": "Température",
"borderColor": "red",
"backgroundColor": "red",
"fill": false,
"data": [{
"x": "2020-07-05T15:38:47.933711",
"y": 2.8224692
},
{
"x": "2020-07-05T15:48:47.490669",
"y": 33.63129
},
{
"x": "2020-07-05T15:58:48.182698",
"y": 40.540405
},
{
"x": "2020-07-05T16:08:47.829882",
"y": 3.0312533
},
{
"x": "2020-07-05T16:18:47.489026",
"y": 49.145626
}
],
"yAxisID": "yAxeTemperature"
},
{
"label": "Humidité",
"borderColor": "blue",
"backgroundColor": "blue",
"fill": false,
"data": [{
"x": "2020-07-05T15:38:47.933711",
"y": 33.980587
},
{
"x": "2020-07-05T15:48:47.490669",
"y": 2.0313625
},
{
"x": "2020-07-05T15:58:48.182698",
"y": 24.249685
},
{
"x": "2020-07-05T16:08:47.829882",
"y": 7.4426904
},
{
"x": "2020-07-05T16:18:47.489026",
"y": 2.6335742
},
{
"x": "2020-07-05T16:28:48.175547",
"y": 25.92827
}
],
"yAxisID": "yAxeHumidite"
}
]
},
"options": {
"responsive": true,
"hoverMode": "index",
"stacked": false,
"title": null,
"scales": {
"xAxes": [{
"type": "time",
"display": true,
"position": "bottom",
"id": "xAxeTime",
"scaleLabel": {
"display": true,
"labelString": "Temps",
"fontColor": "black"
},
"time": {
"unit": "minute",
// "parser": "moment.ISO_8601", -> remove this line
"tooltipFormat": "ll"
}
}],
"yAxes": [{
"type": "linear",
"display": true,
"position": "left",
"id": "yAxeTemperature",
"scaleLabel": {
"display": true,
"labelString": "Température",
"fontColor": "red"
}
},
{
"type": "linear",
"display": true,
"position": "left",
"id": "yAxeHumidite",
"scaleLabel": {
"display": true,
"labelString": "Humidité",
"fontColor": "blue"
}
}
]
}
}
}
const ctx = document.getElementById('myChart');
const myChart = new Chart(ctx, {
type: chartData.type,
data: chartData.data,
options: chartData.options,
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="myChart" height="120"></canvas>
In your question you also wrote "I am supposed to display a graph with 3 datasets, 2 of type line with the same X values, but 1 of type bar with different X values". Your code however only defines 2 datasets. In case you're also facing problems with this point, please post a new question for this separate issue.

Related

Can I partially color a bar based on percentage complete on a temporal axis?

I am trying to create a Gantt chart and I want to color a single task with two colors, based on a percentage complete. Say, make the complete part green and the remaining part orange.
How can I achieve this?
Below is a sample code, also available in the editor here.
{
"data": {
"values": [
{"Description": "Task 1", "Start": "2023-01-05", "End": "2023-01-10", "Percentage complete": 0},
{"Description": "Task 2", "Start": "2023-01-01", "End": "2023-01-15", "Percentage complete": 75},
{"Description": "Task 3", "Start": "2023-01-01", "End": "2023-01-03", "Percentage complete": 100}
]
},
"layer": [
{
"mark": "bar",
"encoding": {
"y": {
"field": "Description",
"type": "ordinal",
"stack": null
},
"x": {
"field": "Start",
"type": "temporal"
},
"x2": {
"field": "End",
"type": "temporal"
}
}
}
]
}
The expected result should look like this.
I tried looking at folding, transforming, and scale. But as I am new to Vega-lite, to no avail.
You have two options.
Reshape your data upstream. Your partially coloured bars should be rendered as two bars stacked - one for incomplete and one for complete.
Use Reactive Geometry as described here. This may need Vega rather than VL.
Here it is using reactive geometry.
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"background": "white",
"padding": 5,
"width": 200,
"style": "cell",
"data": [
{
"name": "source_0",
"values": [
{
"Description": "Task 1",
"Start": "2023-01-05",
"End": "2023-01-10",
"Percentatecomplete": 0
},
{
"Description": "Task 2",
"Start": "2023-01-01",
"End": "2023-01-15",
"Percentatecomplete": 0.75
},
{
"Description": "Task 3",
"Start": "2023-01-01",
"End": "2023-01-03",
"Percentatecomplete": 1
}
]
},
{
"name": "data_0",
"source": "source_0",
"transform": [
{"type": "formula", "expr": "toDate(datum[\"Start\"])", "as": "Start"},
{"type": "formula", "expr": "toDate(datum[\"End\"])", "as": "End"},
{
"type": "filter",
"expr": "(isDate(datum[\"Start\"]) || (isValid(datum[\"Start\"]) && isFinite(+datum[\"Start\"])))"
}
]
}
],
"signals": [
{"name": "y_step", "value": 20},
{
"name": "height",
"update": "bandspace(domain('y').length, 0.1, 0.05) * y_step"
}
],
"marks": [
{
"name": "layer_0_marks",
"type": "rect",
"style": ["bar"],
"from": {"data": "data_0"},
"encode": {
"update": {
"fill": {"value": "#4c78a8"},
"x": {"scale": "x", "field": "Start"},
"x2": {"scale": "x", "field": "End"},
"y": {"scale": "y", "field": "Description"},
"height": {"signal": "max(0.25, bandwidth('y'))"}
}
}
},
{
"type": "rect",
"from": {"data": "layer_0_marks"},
"encode": {
"update": {
"x": {"field": "x"},
"y": {"field": "y"},
"fill": {"value": "red"},
"width": {"signal": "(datum.x2 - datum.x) * datum.datum.Percentatecomplete"},
"height": {"signal": "max(0.25, bandwidth('y'))"}
}
}
}
],
"scales": [
{
"name": "x",
"type": "time",
"domain": {"data": "data_0", "fields": ["Start", "End"]},
"range": [0, {"signal": "width"}]
},
{
"name": "y",
"type": "band",
"domain": {"data": "data_0", "field": "Description", "sort": true},
"range": {"step": {"signal": "y_step"}},
"paddingInner": 0.1,
"paddingOuter": 0.05
}
],
"axes": [
{
"scale": "x",
"orient": "bottom",
"gridScale": "y",
"grid": true,
"tickCount": {"signal": "ceil(width/40)"},
"domain": false,
"labels": false,
"aria": false,
"maxExtent": 0,
"minExtent": 0,
"ticks": false,
"zindex": 0
},
{
"scale": "x",
"orient": "bottom",
"grid": false,
"title": "Start, End",
"labelFlush": true,
"labelOverlap": true,
"tickCount": {"signal": "ceil(width/40)"},
"zindex": 0
},
{
"scale": "y",
"orient": "left",
"grid": false,
"title": "Description",
"zindex": 0
}
]
}

Vega-lite trend line based on aggregated mark

I've got a line chart in which i have a line that is aggregated by sum.
I have a trend line based on regression which works fine for the none-aggregated data, but i would like it to show a trend line based on the points given by the aggregate.
here is my vega-lite specification - can someone help me out?:
"data": {"name": "dataset"},
"layer": [
{
"mark": {"type": "line"},
"encoding": {
"y": {
"field": "Weekly Avg"
},
"color": {
"field": "Loan Type",
"scale": {
"range": [
"#4795CA",
"#F9B96A",
"#779E41",
"#F54f0F",
"#cfcfcf"
]
}
}
}
},
{
"mark": {"type": "line"},
"encoding": {
"y": {
"field": "Weekly Avg",
"aggregate": "sum"
},
"color": {"datum": "Total"}
}
},
{
"mark": {
"type": "line",
"strokeDash": [5, 5]
},
"transform": [
{
"regression": "Weekly Avg",
"on": "W / C",
"groupBy": "W / C"
}
],
"encoding": {
"y": {
"field": "Weekly Avg"
},
"color": {"datum": "Trend"}
}
}
],
"encoding": {
"x": {
"field": "W / C",
"timeUnit": "monthdateyear",
"type": "ordinal",
"axis": {"format": "%d/%m/%Y"}
},
"y": {
"type": "quantitative",
"axis": {"format": "~s"}
}
}
}

Amazon Rekognition - Detect Faces - not returning all attributes

I am calling the Amazon Rekognition Detect faces API from Post man. I pass the image as base64 and pass the "Attributes" as ["ALL"].
{
"Image": {
"Attributes": ["ALL"],
"Bytes": <base64 image>
}
}
The response I get is as below. You can see that it has only a few attributes and does not include age range, beard, glasses etc. Same set of attributes are returned irrespective of whether I pass the value as "ALL", or "DEFAULT" or "ALL","DEFAULT" in the Attributes parameter.
Am I missing something here? Any pointers would be much appreciated.
{
"FaceDetails": [
{
"BoundingBox": {
"Height": 0.49429410696029663,
"Left": 0.35876789689064026,
"Top": 0.15820752084255219,
"Width": 0.3210359811782837
},
"Confidence": 100.0,
"Landmarks": [
{
"Type": "eyeLeft",
"X": 0.4103875756263733,
"Y": 0.35949569940567017
},
{
"Type": "eyeRight",
"X": 0.5616039037704468,
"Y": 0.3441786468029022
},
{
"Type": "mouthLeft",
"X": 0.4385274350643158,
"Y": 0.5330458879470825
},
{
"Type": "mouthRight",
"X": 0.5625125169754028,
"Y": 0.5202205181121826
},
{
"Type": "nose",
"X": 0.48630291223526,
"Y": 0.436920166015625
}
],
"Pose": {
"Pitch": 8.636483192443848,
"Roll": -5.8078813552856445,
"Yaw": -3.338975429534912
},
"Quality": {
"Brightness": 82.37736511230469,
"Sharpness": 83.14741516113281
}
}
]
}

Amazon Rekognition for Video - getFaceSearch: index number

I’m new using Amazon Rekognition to analyze faces on a video.
I’m using startFaceSearch to start my analysis. After the job is completed successfully, I’m using the JobId generated to call getFaceSearch.
On my first video analyzed, the results were as expected. But when I analyze the second example some strange behavior occurs and I can’t understand why.
Viewing the JSON generated as results for my second video, completely different faces are identified with the same index number.
Please see the results below.
{
"Timestamp": 35960,
"Person": {
"Index": 11,
"BoundingBox": {
"Width": 0.09375,
"Height": 0.24583333730698,
"Left": 0.1875,
"Top": 0.375
},
"Face": {
"BoundingBox": {
"Width": 0.06993006914854,
"Height": 0.10256410390139,
"Left": 0.24475525319576,
"Top": 0.375
},
"Landmarks": [
{
"Type": "eyeLeft",
"X": 0.26899611949921,
"Y": 0.40649232268333
},
{
"Type": "eyeRight",
"X": 0.28330621123314,
"Y": 0.41610333323479
},
{
"Type": "nose",
"X": 0.27063181996346,
"Y": 0.43293061852455
},
{
"Type": "mouthLeft",
"X": 0.25983560085297,
"Y": 0.44362303614616
},
{
"Type": "mouthRight",
"X": 0.27296212315559,
"Y": 0.44758656620979
}
],
"Pose": {
"Roll": 22.106262207031,
"Yaw": 6.3516845703125,
"Pitch": -6.2676968574524
},
"Quality": {
"Brightness": 41.875026702881,
"Sharpness": 65.948883056641
},
"Confidence": 90.114051818848
}
}
}
{
"Timestamp": 46520,
"Person": {
"Index": 11,
"BoundingBox": {
"Width": 0.19034090638161,
"Height": 0.42083331942558,
"Left": 0.30681818723679,
"Top": 0.17916665971279
},
"Face": {
"BoundingBox": {
"Width": 0.076486013829708,
"Height": 0.11217948794365,
"Left": 0.38680067658424,
"Top": 0.26923078298569
},
"Landmarks": [
{
"Type": "eyeLeft",
"X": 0.40642243623734,
"Y": 0.32347011566162
},
{
"Type": "eyeRight",
"X": 0.43237379193306,
"Y": 0.32369664311409
},
{
"Type": "nose",
"X": 0.42121160030365,
"Y": 0.34618207812309
},
{
"Type": "mouthLeft",
"X": 0.41044121980667,
"Y": 0.36520344018936
},
{
"Type": "mouthRight",
"X": 0.43202903866768,
"Y": 0.36483728885651
}
],
"Pose": {
"Roll": 0.3165397644043,
"Yaw": 2.038902759552,
"Pitch": -1.9931464195251
},
"Quality": {
"Brightness": 54.697460174561,
"Sharpness": 53.806159973145
},
"Confidence": 95.216400146484
}
}
}
In fact, in this video, all faces have the same index number, regardless of they are different. Any suggestions?
PersonDetail object is the result of the API . "index" is the identifier for the person detected in the video. So the index doesn't span across videos. It is just an internal reference.
Link below which details Index
https://docs.aws.amazon.com/rekognition/latest/dg/API_PersonDetail.html

Chartjs Stacked bar chart not displaying correctly

I'm trying to create a stacked bar chart with chartjs. I have time series with discrepencies in time, this means some series can have value for a time but others don't. For this reason I chose to include directly the x values in the dataset and not as a label array, but the chart does not render correctly.
Here is my code:
var config = {
type:'bar',
data:{
datasets:datasets
},
options: {
responsive: true,
title:{
display:true,
text:"MyChart"
},
tooltips: {
mode: 'index'
},
hover: {
mode: 'index'
},
legend: {
position: 'bottom'
},
elements: { point: { radius: 0 }},
scales: {
xAxes: [{
stacked: true,
type: 'time',
time: {
unit: 'minutes',
unitStepSize: 5,
displayFormats:{
minutes:'HH:mm'
}
},
scaleLabel: {
display: true,
labelString: 'Date'
}
}],
yAxes: [{
stacked:true,
scaleLabel: {
display: true,
labelString: 'Resources Consumed'
}
}]
}
}
};
var ctx = document.getElementById('session-sql-activity').getContext("2d");
ctx.canvas.height = 300;
ctx.canvas.width = 800;
new Chart(ctx,config);
I think the issue is with the x axis stacking.
Here is a JSFiddle illustrating the problem.
https://jsfiddle.net/1kLyyjfp/
I think a solution is to specify a value for the y axis anyway.
{
"y": 0,
"x": "2017-12-22 08:59"
}
The resulting dataset is:
[{
"data": [{
"y": 2,
"x": "2017-12-22 08:59"
}, {
"y": 18,
"x": "2017-12-22 09:00"
}],
"backgroundColor": "#32AA09",
"label": "7726bj0dhtnmt"
}, {
"data": [{
"y": 0,
"x": "2017-12-22 08:59"
}, {
"y": 2,
"x": "2017-12-22 09:00"
}],
"backgroundColor": "#CF5A26",
"label": "0ks4u5nywjbdj"
}, {
"data": [{
"y": 0,
"x": "2017-12-22 08:59"
}, {
"y": 4,
"x": "2017-12-22 09:00"
}],
"backgroundColor": "#DA43AA",
"label": "1mnbsygj75jvx"
}, {
"data": [{
"y": 0,
"x": "2017-12-22 08:59"
}, {
"y": 2,
"x": "2017-12-22 09:00"
}],
"backgroundColor": "#5200A0",
"label": "39ymdt11ybwhz"
}, {
"data": [{
"y": 0,
"x": "2017-12-22 08:59"
}, {
"y": 2,
"x": "2017-12-22 09:00"
}],
"backgroundColor": "#925E44",
"label": "4v1whmzv76j2z"
}, {
"data": [{
"y": 0,
"x": "2017-12-22 08:59"
}, {
"y": 2,
"x": "2017-12-22 09:00"
}],
"backgroundColor": "#477BD4",
"label": "5sfyujuhwbj9n"
}, {
"data": [{
"y": 0,
"x": "2017-12-22 08:59"
}, {
"y": 4,
"x": "2017-12-22 09:00"
}],
"backgroundColor": "#272755",
"label": "6x0zvf2mw8t6g"
}, {
"data": [{
"y": 0,
"x": "2017-12-22 08:59"
}, {
"y": 2,
"x": "2017-12-22 09:00"
}],
"backgroundColor": "#F581E0",
"label": "7kpk62m5n8j9q"
}, {
"data": [{
"y": 0,
"x": "2017-12-22 08:59"
}, {
"y": 20,
"x": "2017-12-22 09:00"
}],
"backgroundColor": "#4128A8",
"label": "7mwz4m103nn1k"
}];