DYGRAPHS: Annotation on scatter point of the same date - annotations

In my scatter plot, there are points of the same date but i only want to annotate one. How can I specify that in my annotation data?
jsfiddle
g = new Dygraph(
document.getElementById("container"),
"Date,Temperature\n" +
"2008-05-07,75\n" +
"2008-05-08,70\n" +
"2008-05-08,20\n" +
"2008-05-09,80\n"
);
g.ready(function() {
g.setAnnotations([
{
series: "Temperature",
x: "2008-05-08",
shortText: "L",
text: "Coldest Day"
}
]);
});

You could do it this way, by adding a second to your datapoint you don't want to be labeled.
https://jsfiddle.net/55ktaue1/3/
I would then use the formatting functionality to remove the timestamp from the date. 'legendFormatter' examples: http://dygraphs.com/tests/legend-formatter.html http://dygraphs.com/tests/labelsDateMilliseconds.html http://dygraphs.com/tests/labelsDateUTC.html
g = new Dygraph(
document.getElementById("container"),
"Date,Temperature\n" +
"2008-05-07,75\n" +
"2008-05-08,70\n" +
"2008-05-08 00:00:01,20\n" +
"2008-05-09,80\n"
);
g.ready(function() {
g.setAnnotations([
{
series: "Temperature",
x: "2008-05-08",
shortText: "L",
text: "Coldest Day"
}
]);
});

Related

How to dynamically create ticks (month) in google chart?

Given an aggregated data table that is defined as:
aggData: [Date: date][Team: string][Score: number]
I want to plot the aggregated data with the ability to filter by year. I am using dynamic ticks on the hAxis to avoid the repeating labels problem. However, the label for the custom ticks does not appear.
I want the hAxis to display the months. My hunch is I'm not creating the ticks properly
See images below
var hAxisTicks = [];
var dateRange = aggData.getColumnRange(0);
for (var y = dateRange.min.getFullYear(); y <= dateRange.max.getFullYear(); y = y + 1) {
for(var m = dateRange.min.getMonth(); m <= dateRange.max.getMonth(); m = m + 1){
hAxisTicks.push(new Date(y,m));
}
}
var yearPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'categoryFilter_div',
options: {
filterColumnIndex: 0,
ui: {
allowTyping: false,
allowMultiple: false,
label: 'Year:',
labelStacking: 'vertical'
},
useFormattedValue: true
}
});
var lineChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
options: {
width: 900,
height: 500,
hAxis: {
format: 'MMM',
ticks: hAxisTicks
}
}
});
aggData.sort([{ column: 0 }]);
// draw chart
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_div'));
dashboard.bind(yearPicker, lineChart);
dashboard.draw(aggData);
<div id="dashboard_div">
<div id="categoryFilter_div"></div>
<div id="chart_div"></div>
</div>
When specifying the hAxisTicks value, the chart comes out without labels on the hAxis
Without specifying hAxisTicks the chart looks like:
i've logged the data to console using
google.visualization.dataTableToCsv(aggData)
the output is:
"Oct 1, 2019",128,0,0,0
"Nov 1, 2019",152,75,0,0
"Dec 1, 2019",0,0,23,0
"Jan 1, 2020",225,0,0,84
the issue with the for loop is in the month portion.
given the data you provided, the month for the min date = 9 (Oct)
however, the month for the max date = 0 (Jan)
so the month for loop does not run, because 9 > 0
instead, let's use a while loop.
var dateTick = dateRange.min;
while (dateTick.getTime() <= dateRange.max.getTime()) {
hAxisTicks.push(dateTick);
dateTick = new Date(dateTick.getFullYear(), dateTick.getMonth() + 1);
}

Grid line only on data point for scratter points

I need to draw x & y intercepts for all data points in a scratter chart. I went through major and minor grid lines. But it could not be my perfect solution.
Like the image below:
The sample image with x and y intercepts only on data points
You can use the render function of the chart to draw the horizontal and vertical lines on the chart surface. In the following demo, I name the x and y axes so that in the render function I can use the getAxis() method along with slot and range. See DOCS.
DEMO
var data = [[0.67, 5.4], [2.2, 2], [3.1, 3]];
$("#chart").kendoChart({
series: [{
type: "scatter",
data: data,
markers: {size: 16},
}],
yAxis: { name: "value", majorGridLines: {visible: false } },
xAxis: { name: "category", majorGridLines: {visible: false } },
render: function(e){
var chart = e.sender;
var yAxis = chart.getAxis("value");
var xAxis = chart.getAxis("category");
//iterate each point on the chart
for (var i=0; i<data.length; i++){
//vertical line
var valRange = yAxis.range();
var valSlot = yAxis.slot(valRange.min, valRange.max);
var point = data[i];
var catSlot = xAxis.slot(point[0]);
var path = new kendo.drawing.Path({
stroke: {color: "#B3BDBD", width: 1}
}).moveTo(catSlot.origin.x + catSlot.size.width/2, valSlot.origin.y)
.lineTo(catSlot.origin.x + catSlot.size.width/2, valSlot.bottomRight().y);
chart.surface.draw(path);
//horizontal line
var ySlot = yAxis.slot(point[1]);
var xRange = xAxis.range();
var xSlot = xAxis.slot(xRange.min, xRange.max);
var pathH = new kendo.drawing.Path({
stroke: {color: "#B3BDBD", width: 1}
}).moveTo(xSlot.origin.x, ySlot.origin.y + ySlot.size.width/2)
.lineTo(xSlot.bottomRight().x, ySlot.origin.y + ySlot.size.width/2);
chart.surface.draw(pathH);
}
}
});

ChartJS / MomentJS - Unable to remove deprecation warning. Graph not showing in firefox/opera

so browsers throw
warning about using momentJS incorrectly.
Deprecation warning: value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.
Arguments:
[0] _isAMomentObject: true, _isUTC: false, _useUTC: false, _l: undefined, _i: 12.30, _f: false, _strict: undefined, _locale: [object Object]
Error
So i looked at my code
data: {
labels: ['01.01', '02.01', '03.01', '04.01', '05.01', '06.01', '07.01', '08.01', '09.01', '10.01', '11.01', '12.01'],
datasets: createChatterData(data, this)
},
And read that I should provide a format when dealing with non iso strings.
labels: [moment('01.01', 'MM.DD'), moment('02.01', 'MM.DD'), ...];
Ok that removed first deprecation.
But my datasets data also contains of date
dataset.data.pushObject({
x: moment(datum).format('MM.DD'),
y: parseInt(moment(datum).format('YYYY'))
});
So I tried different variations to that (premodified ambigious datetime)
x: moment(date, 'YYYY.MM.DD').format('MM.DD')
and
x: moment(date, 'MM.DD')
But my graph doesnt map correctly anymore.
Example of codepen chart working in chrome: http://codepen.io/kristjanrein/pen/wJrQLE
Does not display in firefox/opera
I see a couple of issues here.
1) Since you want your X axis to be a time scale, then you should leave your X data value as a moment object. Your current implementation is creating a moment object from a date string and then formatting it back to a string. When you do this, chart.js then takes the string and tries to create a moment object internally when it builds the chart.
Therefore, It is best to keep the data as either a Date or Moment object and use the time scale configuration properties to determine how the data is displayed on the chart. This prevents chart.js from having to construct the moment object and guess at the string format.
2) You are using the pre-2.0 way to create a chart when you use Chart.Scatter. Instead you should use the new style (new Chart()) and pass in a type property.
Here is a modified version of you code that results in no browser warnings and works in Chrome and Firefox (I did not test in Opera).
var getData = function() {
var dummyDataset = [
'2007-11-09T00:00:00.000Z',
'2006-08-04T00:00:00.000Z',
'2006-08-06T00:00:00.000Z',
'2008-01-10T00:00:00.000Z'
];
return dummyDataset.map(function(datum) {
var myMoment = moment(datum);
return {
x: myMoment,
y: parseInt(myMoment.format('YYYY')),
};
});
};
var ctx = document.getElementById("chart1").getContext("2d");
var myScatter = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: "My First dataset",
borderColor: 'rgb(255, 99, 132)',
fill: false,
pointRadius: 4,
pointHoverRadius: 8,
showLine: false,
data: getData()
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Random Data'
},
legend: {
display: true,
labels: {
fontSize: 10,
boxWidth: 20
}
},
elements: {
point: {
pointStyle: 'rect'
}
},
hover: {
mode: 'nearest'
},
scales: {
xAxes: [{
type: 'time',
position: 'bottom',
scaleLabel: {
display: true,
labelString: 'Months'
},
time: {
unit: 'month',
displayFormats: {
month: 'MM'
},
}
}],
yAxes: [ {
type: 'linear',
ticks: {
min: 2005,
max: 2015,
stepSize: 1
},
scaleLabel: {
display: true,
labelString: 'Year'
}
}]
}
}
});
You can see it in action at this forked codepen.
One other thing to keep in mind is that because your data spans multiple years, you will see duplicate months on the X axis. Remember, a time scale is used to plot dates so even if you only display the months, a data point with the same month but with different years will not be plotted at the same location.
If you are actually only wanting to show month string/number values in the X axis, then you should not use the time scale at all and use the linear scale instead. Then when you build your data values, you would extract the month from the data (the same way you are already doing for your Y value).
var getData = function() {
var dummyDataset = [
'2007-11-09T00:00:00.000Z',
'2006-08-04T00:00:00.000Z',
'2006-08-06T00:00:00.000Z',
'2008-01-10T00:00:00.000Z'
];
return dummyDataset.map(function(datum) {
var myMoment = moment(datum);
return {
x: parseInt(myMoment.format('MM')),
y: parseInt(myMoment.format('YYYY')),
};
});
};
So in addition to jordan's answer
I changed my labels and x axis from
['01.01', '02.01', ...] to [1,2,...]
and
from type: 'time' to type: 'linear'
And to make it map not only by month but also by day. I had to make date objects to correct floats. 05.20 to 5.66
const date = datum.key;
const day = parseInt(moment(date).format('DD')) / 30 * 100;
const fullDate = parseFloat(moment(date).format('MM') + '.' + Math.round(day))
// 05.10 would be 5.3 (10 of 30 is 33%)
{
x: fullDate,
y: parseInt(moment(date).format('YYYY'))
date: date, // for tooltip
count: count // for tooltip
}
And i also had to make corrections to my tooltips
callbacks: {
title: function([tooltipItem], data) {
const tooltipInfo = getTooltip(tooltipItem, data.datasets);
return tooltipInfo.date;
},
label: function(tooltipItem, data) {
const tooltipInfo = getTooltip(tooltipItem, data.datasets);
return i18n.t('chart.count') + ': ' + tooltipInfo.count;
},
}
corresponding tooltip dataset
function getTooltip(tooltipItem, datasets) {
return datasets[tooltipItem.datasetIndex].data.find(datum => {
return datum.x === tooltipItem.xLabel && datum.y === tooltipItem.yLabel;
});
}

How to set xAxis in TIME type and formatted like {hh:mm} in Echarts?

I want to set xAxis in TIME type and formatted like {hh:mm} , such as 17:45.
In this demo, configuration works:
xAxis: {
type: "time",
},
value: [
[now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'),
Math.round(value)
]
But this fails, here is my demo in Echarts gallery :
xAxis: {
type: "time",
},
value: [
[now.getHours(), now.getMinutes()].join(":"),
Math.round(value)
]
I tried type: "value", still not working.
As mention above you need to use xAxis.axisLabel.formatter.
Here is your example.
// Horizontal axis
xAxis: [{
type: 'time',
axisLabel: {
formatter: (function(value){
let label;
if (value.getMinutes() < 10){
label = value.getHours() + ":0" +value.getMinutes();
}
else {
label = value.getHours() + ":" +value.getMinutes();
}
return label;
})
}
}],
Use xAxis.axisLabel.formatter. This can be a formatter string or a function.
Use this as reference: https://ecomfe.github.io/echarts-doc/public/en/option.html#xAxis.axisLabel.formatter
I made your demo working.
I've changed the value like this:
value: [
[now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/') + 'T' +
[now.getHours(), now.getMinutes()].join(':'),
Math.round(value)
]
Please see this screenshot:
For anyone looking for the answer, the link provided in the accepted answer is correct but has 404'd.
Here's the current working one: https://echarts.apache.org/en/option.html#xAxis.axisLabel.formatter

Issue with tooltip on flotchart for date format

I am facing an issue with tooltip showing date in x-axis.
Can anyone help on this?
fiddle code
grid: {
hoverable: true //IMPORTANT! this is needed for tooltip to work
},
tooltip: true,
tooltipOpts: {
content: "<h4>%s</h4><ul><li>Date is %x</li><li>Total Count: %y</li></ul>",
defaultTheme: false
},
points:
{
show: true
},
series: {
bars: {
show: true,
barWidth: 0.1,
order: 1
}
}
You need a function to convert the x value (which is only a number / timestamp) to an actual date.
Use something like this:
tooltipOpts: {
content: function (label, x, y) {
var date = new Date(+x);
var tooltip = '<h4>' + label + '</h4><ul>';
tooltip += '<li>Date is ' + date.toLocaleDateString() + '</li>';
tooltip += '<li>Total Count: ' + y + '</li></ul>';
return tooltip;
},
See this update fiddle.