I'm trying to create one real-time flot and my problem is that I can't get to see the flot grid through the filling of my data's lines..
If you have any idea to get my filling a bit transparent like the picture below, I'd like to apply it as well on my Fiddle!
What I'm trying to achieve is something like that:
Picture of what I try to get
Here is the Fiddle on what I'm working:
My flot on Fiddle
Code:
$(function () {
getRandomData = function(){
var rV = [];
for (var i = 0; i < 10; i++){
rV.push([i,Math.random() * 10]);
}
return rV;
}
getRandomDataa = function(){
var rV = [];
for (var i = 0; i < 10; i++){
rV.push([i,Math.random() * 10 + 5]);
}
return rV;
}
getSeriesObj = function() {
return [
{
data: getRandomDataa(),
lines: {
show: true,
fill: true,
lineWidth: 5,
fillColor: { colors: [ "#b38618", "#b38618" ] },
tickColor: "#FFFFFF",
tickLength: 5
}
}, {
data: getRandomData(),
lines: {
show: true,
lineWidth: 0,
fill: true,
fillColor: { colors: [ "#1A508B", "#1A508B" ] },
tickColor: "#FFFFFF",
tickLength: 5
}
}];
}
update = function(){
plot.setData(getSeriesObj());
plot.draw();
setTimeout(update, 1000);
}
var flotOptions = {
series: {
shadowSize: 0, // Drawing is faster without shadows
tickColor: "#FFFFFF"
},
yaxis: {
min: 0,
autoscaleMargin: 0,
position: "right",
transform: function (v) { return -v; }, /* Invert data on Y axis */
inverseTransform: function (v) { return -v; },
font: { color: "#FFFFFF" },
tickColor: "#FFFFFF"
},
grid: {
backgroundColor: { colors: [ "#EDC240", "#EDC240" ], opacity: 0.5 }, // "Ground" color (May be a color gradient)
show: true,
borderWidth: 1,
borderColor: "#FFFFFF",
verticalLines: true,
horizontalLines: true,
tickColor: "#FFFFFF"
}
};
var plot = $.plot("#placeholder", getSeriesObj(), flotOptions);
setTimeout(update, 1000);
});
Thanks a lot!
You can use the rgba() color specification with flot to specify the fill color and alpha level (transparency):
fillColor: { colors: [ "rgba(179, 134, 24, .2)", "rgba(179, 134, 24, .2)" ] },
An alpha value of 0 is fully transparent, while an alpha value of 1 is fully opaque.
Related
I need to plot a single value in line chart. Currently i am using charts.JS library for line graph purpose.
The data will be varied some times i'll get the single data inside the data set at that time i need to plot the single value with line in the line chart.
I tried with the charts.js annotation plugin but it wasn't met my requirements. which is like it wis overlapping the plotted point in the graph area.
CODE WHICH I HAD TRIED
createLineChart() {
this.lineChart = new Chart(this.lineCanvas.nativeElement, {
type: "line",
data: {
labels:[],
datasets: [
{
fill: false,
backgroundColor: "#0168FF",
borderColor: "#0168FF",
pointBackgroundColor: "white", // wite point fill
pointBorderWidth: 1, // point border width
lineTension: 0,
pointBorderColor: "blue",
pointRadius: 4,
},
],
},
options: {
scales: {
yAxes: [
{
ticks: {
padding: 20,
beginAtZero: true,
min: 0,
stepSize: 100,
},
gridLines: {
drawBorder: false,
},
},
],
xAxes: [
{
// offset: true,
ticks: {
display: false,
//beginAtZero: true,
min: 0,
},
gridLines: {
zeroLineColor: "transparent",
drawBorder: false,
display: false,
},
//offset:true,
},
],
legend: {
display: false,
},
tooltips: {
enabled: false,
},
},
drawTime: "afterDraw", // (default)
} as ChartOptions,
// plugins: [ChartAnnotation]
},
});
}
To generate dynamic data and plot in the graph area.
generateRandomDataSet(size) {
let yaxisArr = [];
let xaxisArr = [];
let random_data:any = this.getRandomData(size)
let maxYTickVal = Math.max.apply(Math, random_data.map((val) => {return val.yaxis}));
let maxVal = Math.ceil((maxYTickVal+1) / 10) * 10
for(let data of random_data) {
yaxisArr.push(data.yaxis)
xaxisArr.push(data.xaxis)
}
console.log("X-Axis array values : "+xaxisArr)
console.log("Y-Axis array values : "+yaxisArr)
this.lineChart.data.datasets[0].data = yaxisArr
this.lineChart.config.data.labels = []
this.lineChart.config.data.labels = xaxisArr
this.lineChart.config.options.scales.yAxes[0].ticks.max =maxVal
this.lineChart.config.options.scales.yAxes[0].ticks.stepSize = maxVal/2
this.lineChart.update()
}
getRandomData(arraySize) {
let data = []
for(var i=1; i<=arraySize; i++) {
let number = Math.floor(Math.random() * 200) + 1
data.push({'xaxis':i,'yaxis':number})
}
return data
}
with the above code i am getting like
what i need to have
You can define an animation.onComplete function as follows to draw the line in case a single data value is present.
animation: {
onComplete: e => {
var ctx = chart.chart.ctx;
var data = chart.config.data.datasets[0].data;
if (data[0] == null) {
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
var y = yAxis.getPixelForValue(data[1]);
ctx.save();
ctx.globalCompositeOperation='destination-over';
ctx.strokeStyle = 'blue'
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(xAxis.left, y);
ctx.lineTo(xAxis.right, y);
ctx.stroke();
ctx.restore();
}
}
},
This function expects the data array to be of format [null, <value>, null] in case a single value is present, otherwise it will be hard to horizontally center the data point (see this answer). It's up to you to change the generateRandomDataSet() function in a way that it provides such data.
Please have a look at your changed code below.
const chart = new Chart('line-chart', {
type: "line",
data: {
labels: ['', 'A', ''],
datasets: [{
data: [null, 120, null],
fill: false,
backgroundColor: "#0168FF",
borderColor: "#0168FF",
pointBackgroundColor: "white",
pointBorderWidth: 1,
lineTension: 0,
pointBorderColor: "blue",
pointRadius: 4,
}],
},
options: {
legend: {
display: false
},
tooltips: {
enabled: false
},
animation: {
onComplete: e => {
var ctx = chart.chart.ctx;
var data = chart.config.data.datasets[0].data;
if (data[0] == null) {
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
var y = yAxis.getPixelForValue(data[1]);
ctx.save();
ctx.globalCompositeOperation='destination-over';
ctx.strokeStyle = 'blue'
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(xAxis.left, y);
ctx.lineTo(xAxis.right, y);
ctx.stroke();
ctx.restore();
}
}
},
scales: {
yAxes: [{
ticks: {
padding: 20,
min: 0,
stepSize: 100
},
gridLines: {
drawBorder: false
}
}],
xAxes: [{
ticks: {
display: false
},
gridLines: {
zeroLineColor: "transparent",
drawBorder: false,
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="line-chart" height="80"></canvas>
I'm having some issues when trying to update a chart's data using $scope.
I know there's a function to update charts myChart.update(); but I can't get to update the char when I put it in a $scope.
The following code gets the chart's data and then tries to update the chart. The problem comes at $scope.lineChart.update();. It looks like chartjs can't detect any changes.
The following code is executed after triggering a select, so the chart has an initial data and the following code just tries to update it.
This does not work: $scope.lineChart.update();
$scope.getLineChartMaxData().then(function () {
$scope.getLineChartMinData().then(function () {
$scope.lineChart.update();
});
});
The chart function:
$scope.fillLineChart = function () {
console.log("FILLING LINE CHART");
const brandProduct = 'rgba(0,181,233,0.5)'
const brandService = 'rgba(0,173,95,0.5)'
var data1 = $scope.lineChartMaxWeekData;
var data2 = $scope.lineChartMinWeekData;
var maxValue1 = Math.max.apply(null, data1)
var maxValue2 = Math.max.apply(null, data2)
var minValue1 = Math.min.apply(null, data1)
var minValue2 = Math.min.apply(null, data2)
var maxValue;
var minValue;
if (maxValue1 >= maxValue2) {
maxValue = maxValue1;
} else {
maxValue = maxValue2;
}
if (minValue1 >= minValue2) {
minValue = minValue2;
} else {
minValue = minValue1;
}
$scope.minValue = minValue;
$scope.maxValue = maxValue;
var ctx = document.getElementById("recent-rep-chart");
if (ctx) {
ctx.height = 250;
$scope.lineChart = new Chart(ctx, {
type: 'line',
data: {
labels: $scope.lineChartMaxWeekLabels,
datasets: [{
label: 'Valor',
backgroundColor: brandService,
borderColor: 'transparent',
pointHoverBackgroundColor: '#fff',
borderWidth: 0,
data: data1
},
{
label: 'My Second dataset',
backgroundColor: brandProduct,
borderColor: 'transparent',
pointHoverBackgroundColor: '#fff',
borderWidth: 0,
data: data2
}
]
},
options: {
maintainAspectRatio: true,
legend: {
display: false
},
responsive: true,
scales: {
xAxes: [{
gridLines: {
drawOnChartArea: true,
color: '#f2f2f2'
},
ticks: {
fontFamily: "Poppins",
fontSize: 12
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
maxTicksLimit: 5,
stepSize: 50,
max: maxValue,
fontFamily: "Poppins",
fontSize: 12
},
gridLines: {
display: true,
color: '#f2f2f2'
}
}]
},
elements: {
point: {
radius: 0,
hitRadius: 10,
hoverRadius: 4,
hoverBorderWidth: 3
}
}
}
});
}
};
UPDATE: $scope.lineChart.destroy(); works well, but I don't want to destroy the chart and build it again because it is built with another sizes.
I've seen tutorials and posts about getting data from the x axis into the tooltip but I am overriding it with categories and cannot figure out how to get the x axis to show up in the tooltip.
This is what im working with:
function showTooltip(x, y, contents) {
$('<div id="tooltip" class="flot-tooltip tooltip"><div class="tooltip-arrow"></div>' + contents + '</div>').css({
top: y - 43,
left: x - 15,
}).appendTo("body").fadeIn(200);
}
var data = [[1492854610, -1240],[1492939020, -1273],[1493025073, -1279],[1493117066, -1186],[1493198484, -1269],[1493289175, -1198],[1493370646, -1280],[1493458518, -1255],[1493543731, -1275],[1493630250, -1273],[1493716306, -1279],[1493803609, -1264],[1493889258, -1276],[1493975557, -1278],[1494064529, -1235],[1494155440, -1160],[1494237980, -1224],[1494321047, -1280],[1494407990, -1271],[1494494125, -1275],[1494581609, -1257],[1494668321, -1252],[1494753220, -1277],[1494847855, -1140],[1494925963, -1278],[1495012537, -1275],[1495099289, -1269],[1495188205, -1227],[1495273568, -1244],[1495358329, -1272]];
$.plot($("#placeholder"), [{
label: "Delay: ",
data: data,
color: "#3a8ce5"
}], {
xaxis: {
mode: "categories",
tickLength: 0,
ticks: [[0, "1:50 AM"],[1, "1:17 AM"],[2, "1:11 AM"],[3, "2:44 AM"],[4, "1:21 AM"],[5, "2:32 AM"],[6, "1:10 AM"],[7, "1:35 AM"],[8, "1:15 AM"],[9, "1:17 AM"],[10, "1:11 AM"],[11, "1:26 AM"],[12, "1:14 AM"],[13, "1:12 AM"],[14, "1:55 AM"],[15, "3:10 AM"],[16, "2:06 AM"],[17, "1:10 AM"],[18, "1:19 AM"],[19, "1:15 AM"],[20, "1:33 AM"],[21, "1:38 AM"],[22, "1:13 AM"],[23, "3:30 AM"],[24, "1:12 AM"],[25, "1:15 AM"],[26, "1:21 AM"],[27, "2:03 AM"],[28, "1:46 AM"],[29, "1:18 AM"]]
},
yaxis: {
min: -2000,
max: 1000,
},
series: {
lines: {
show: true,
fill: true
},
points: {
show: true,
}
},
grid: {
hoverable: true,
clickable: true,
markings: [
{ color: '#000', lineWidth: 1, yaxis: { from: 0, to: 0 } },
]
},
legend: {
show: false
}
});
$("#placeholder").bind("plothover", function(event, pos, item) {
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$("#tooltip").remove();
var y = item.datapoint[1].toFixed();
showTooltip(item.pageX, item.pageY,
item.series.label + " = " + y);
}
} else {
$("#tooltip").remove();
previousPoint = null;
}
});
I am trying to get the times part of the categories. The item array has 3 pieces of data, none of which are the times
jFiddle:
http://jsfiddle.net/zw14y8c3/2/
The item.datapoint[0] data has the index of the x-axis tick. With that you can get the actual tick label from the ticks array:
var x = $("#placeholder").data('plot').getAxes().xaxis.ticks[item.datapoint[0]].label;
See the updated fiddle for the full example.
I'm using highCharts, and creating a highChart in fancybox. I want animation off in highCharts. but when I set 'animation: false' the bars in the charts disappears
I don't know what's the problem I've tried many things, if I create highChart without fancybox it creates ok, but fancybox is the requirement. below is my code createHighChart() function create HighChart from the settings that user would set on the page.
$.fancybox.open({
'href' : '#container',
'titleShow' : false,
'transitionIn' : 'elastic',
'transitionOut' : 'elastic',
prevEffect : 'none',
nextEffect : 'none',
afterShow: function(){
for(var i=0; i<10000; i++);
createHighChart();
$("#container").show();
}
});
and createHighChart function:
function createHighChart() {
var xData = getXdata();
var yAxisData = getYAxisData();
var t = getInt("threshold_id");
var type = getType();
var backColors = getBackgroundColor();
var isAreaOrLineChart = false;
var customColors = false;
var customPlotOptions = Highcharts.getOptions().plotOptions;
/*uncomment following two lines to provide your custom
* colors (an array of colors) for the bars in bar chart*/
/*customColors = true;
customPlotOptions.column.colors = customPlotOptions.bar.colors =
['#FF0000', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572'];*/
/***************************change font style****************************/
/*Highcharts.setOptions({
chart: {
style: {
fontSize: '25px',
fontWeight: 'bold',
fontFamily: 'serif',
}
}
});*/
if(type == "pie") {
createPieChart();
return;
}
if(type == "line" || type == "area") {
isAreaOrLineChart = true;
}
/******************Bar chart specific settings************************/
var barColor = getStr("barcolor_id");
var isMultiColor = false;
if(barColor == "multicolor") {
barColor = null;
isMultiColor = true;
}
else if(barColor == "") {
barColor = null;
}
if(isStacking() == "normal"){
barColor = isMultiColor = null;
}
var isGrouping = true;
if(getStr("barlayout_id") == "overlap") {
isGrouping = false;
barColor = isMultiColor = null;
}
/******************Line chart specific settings************************/
var thickLine = 2;
if(isCheckBoxEnabled("thickline_id")){
thickLine = 5;
}
/*if(isCheckBoxEnabled("show3d_id")) {
loadjsfile();
}
else {
$("#scripto").remove();
//removejsfile();
}
*/
/*******************Creates the bar chart************************/
var chart = new Highcharts.Chart({
chart : {
//backgroundColor: getStr("chrtbkgndcolor_id"),
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 },
stops: [
[0, backColors[0]],
[1, backColors[1]]
]
},
renderTo : 'container',
type : type,
margin: 75,
//animation: false,
options3d: {
enabled: isCheckBoxEnabled("show3d_id") && !isAreaOrLineChart,
alpha: 10,
beta: 10,
depth: 50,
viewDistance: 25
},
borderColor: '#A9A9A9',
borderRadius: isRoundCorner(),
borderWidth: isBorder(),
width: getInt("width_id"),
height: getInt("height_id")
},
title : {
text : getStr("title_id"),
style: {
fontWeight: getFontWeight("fonttypetitle_id"),
fontStyle: getFontStyle("fonttypetitle_id")
}
},
subtitle: {
text: getStr("subtitle_id"),
style: {
fontWeight: getFontWeight("fonttypetitle_id"),
fontStyle: getFontStyle("fonttypetitle_id")
}
},
tooltip: {
enabled: isCheckBoxEnabled("tooltip_id")
},
credits: {
text: getStr("source_id"),
href: '#'
},
legend: {
enabled: isCheckBoxEnabled("legend_id"),
},
xAxis : {
title:{
text: getStr("xtitle_id"),
style: {
fontWeight: getFontWeight("fonttypetitle_id"),
fontStyle: getFontStyle("fonttypetitle_id")
}
},
categories : xData,
labels: {
rotation: getRotation(),
style: {
fontWeight: getFontWeight("fonttypelabel_id"),
fontStyle: getFontStyle("fonttypelabel_id")
}
},
/*below two lines are for x-axis line, it is not working
* due to inclusion of the 3D charts library
* (namely this line:
* <script src="http://code.highcharts.com/highcharts-3d.js"></script>)
* in the include/ChartGoLiteJSFiles.jsp */
lineWidth: 1,
lineColor: '#FF0000',
gridLineWidth: false
},
yAxis :
{
//lineWidth: 20,
min: getMinMaxY("min_yaxis_id"),
max: getMinMaxY("max_yaxis_id"),
plotLines: [{
color: '#FF0000',
width: 2,
value: t,
dashStyle: 'shortdash',
id: 'plotline-1'
}],
title : {
text : getStr("ytitle_id"),
style: {
fontWeight: getFontWeight("fonttypetitle_id"),
fontStyle: getFontStyle("fonttypetitle_id")
}
},
labels: {
style: {
fontWeight: getFontWeight("fonttypelabel_id"),
fontStyle: getFontStyle("fonttypelabel_id")
}
},
/*below two lines are for x-axis line, it is not working
* due to inclusion of the 3D charts library
* (namely this line:
* <script src="http://code.highcharts.com/highcharts-3d.js"></script>)
* in the include/ChartGoLiteJSFiles.jsp */
lineWidth: 1,
lineColor: '#FF0000',
gridLineColor: '#197F07',
gridLineWidth: isCheckBoxEnabled("gridlines_id")
},
plotOptions: {
series: {
animation: false,//this is not working right
shadow: isShadow(),
color: barColor,
//colorByPoint: isMultiColor || customColors,
stacking: isStacking(),
marker: {
enabled: isCheckBoxEnabled("shape_id")
},
lineWidth: thickLine
},
column: {
//animation: false,
colorByPoint: isMultiColor || customColors,
depth: 25,
grouping: isGrouping
},
bar: {
colorByPoint: isMultiColor || customColors,
},
},
series : yAxisData
});
chart.container.onclick = isCheckBoxEnabled("mouse_interaction_id");
if(t == 0)
chart.yAxis[0].removePlotLine('plotline-1');
}
I have a chart with ordering by date.
My problem is the chart lines joining false from start to end.
My options:
var options =
{
grid:
{
color: "#dedede",
borderWidth: 1,
borderColor: "transparent",
clickable: true,
hoverable: true
},
series: {
grow: {active:false},
lines: {
show: true,
fill: false,
lineWidth: 2,
steps: false
},
points: {
show:true,
radius: 5,
lineWidth: 3,
fill: true,
fillColor: "#000"
}
},
legend: { position: "nw", backgroundColor: null, backgroundOpacity: 0, noColumns: 2 },
yaxis: { tickSize:50 },
xaxis: {
mode: "time",
tickFormatter: function(val, axis) {
var d = new Date(val);
return d.getUTCDate() + "/" + (d.getUTCMonth() + 1);
}
},
colors: [],
shadowSize:1,
tooltip: true,
tooltipOpts: {
content: "%s : %y.0",
shifts: {
x: -30,
y: -50
},
defaultTheme: false
}
};
Note: I'm not re-ordering any data. Just giving the timestamp with this function:
function gd(year, month, day) {
return new Date(year, month - 1, day).getTime();
}
Setting the data like this:
$.each(e.data, function(i, e){
data.push([gd(parseInt(e['year']), parseInt(e['month']), parseInt(e['day'])), parseInt(e['value'])]);
});
var entity = {
label: e.campaign,
data: data,
lines: {fillColor: randomColor},
points: {fillColor: randomColor}
};
entities.push(entity);
Console log:
When creating line charts, flot will connect the data points using the order from the data series, ignoring the actual x-coordinates. That's why data series should be in ascending order.
A minimal example (using your data in ascending order):
var d1 = [
[1401310800000, 275],
[1401397200000, 270],
[1401483600000, 313],
[1401570000000, 279],
[1401656400000, 216],
[1401742800000, 255],
[1401829200000, 244],
[1401915600000, 70]
];
$.plot("#chart", [ d1 ]);
Here is a jsfiddle showing the chart.