I would like to know how to get x-axis start value in JS library Flot. I know x-axis value in the start (obviously, because I fill it with my own data), but if you set:
pan: {
interactive: true
}
Than the user is able to pan through graph (example here) and if the user pans through graph, the x-values change. I looked inside jquery.flot.js to find where this values are computed but with no luck.
I got it. The solution was in front of me the whole time (example):
var axes = plot.getAxes();
var min = axes.xaxis.min;
Related
I'm using chart.js 2.9.4 and the ng2-charts wrapper for Angular. I'm trying to display incoming live data, but have trouble configuring the chart so that the ticks/axis don't stretch beyond the data in the chart. In other words, I want the chart data points to fill the entire width of the chart grid.
StackBlitz showing my issue.
If you keep looking at the chart as data is added, you see that most of the time the ticks stretch beyond the last point in the chart:
The only solution I could come up with is overwriting the max value of the ticks on the x-axis each time new data is added to the chart: options.scales.xAxes[0].ticks.max = x;. Uncomment line 68 in the StackBlitz in order to apply this. This solves my problem but introduces another. Sometimes as data gets added, the last two ticks overlap:
I've tried experimenting with various parameters of the scales and ticks options (bounds,distribution,stepSize,source,autoSkip,autoSkipPadding) with no results. Is there any combination of configuration parameters to solve my issue ?
You may want to add delay at streaming plugin, the config will look something like:
scales: {
x: {
type: 'realtime', // x axis will auto-scroll from right to left
realtime: { // per-axis options
delay: 1000, // delay of 1000 ms, so upcoming values are known before plotting a line
pause: false, // chart is not paused
ttl: undefined, // data will be automatically deleted as it disappears off the chart
}
},
I have tested this on your code, and it seems to work as expected, you may want to tune some parameters as needed.
I am new to Chart.js and JavaScript. Currently working with a line chart, and now I want to add custom data points to a mouse click event (when I press somewhere on the data set, it takes the current value of the Y axis and using that value it creates a data point in that place). I took the code from http://www.chartjs.org/samples/latest/charts/line/basic.html and trying to modify it. Here is a link to my current chart:
https://i.stack.imgur.com/M9MF1.jpg
I am using the basic chart.bundle.js library, and used D3.js libraries for making data points draggable.
Trying to implement the creation of points per mouse click using the following code, but it seems that it's not good so far.
document.getElementById('canvas').onclick = function(e){
//getting value by pressing on dataset
value = chartInstance.scales[scale].getValueForPixel(e.clientY)
//trying to create dataPoint
myLineChart.points.push(new this.PointClass({
y: value;
strokeColor: this.datasets[datasetIndex].pointStrokeColor,
fillColor: this.datasets[datasetIndex].pointColor
}));
//after all updating my chart
chartInstance.Update(0)
};
Maybe anyone could explain more about this library and how it creates data points?
Every new point in the chart is data, so you need to add that point in the data (chartData.data.dataset[]) array. Instead of adding to the, myLineChart.points which i'm not sure why you have used you should add the data-point in the data array and the UI decorations such as colors are supposed to be specified in the chartOptions.scales.yAxes[] array. Therefore in order to add the point in the chart use:
// here i is the corresponding parameter for which you want to add the new point
chartInstance.data.datasets[i].push(value);
chartInstance.update();
I am having problems controlling the Y-Axis range of a highcharts graph. It seems like highcharts likes nice round numbers. When my data passes or is close to certain thresholds, the Y-Axis range can expand a lot which effectively compresses all the plot points downward.
Here is a jsfiddle that illustrates the problem I am having:
https://jsfiddle.net/shannonwrege/z8h5eork
The relevant code for this post is this:
chart.yAxis[0].setExtremes(0, max, true, false);
Keep in mind that I don't know what the data will look like in advance, so I must dynamically modify the Y-Axis range. Right now I am using the setExtremes because of other suggestions I've read on stackoverflow.
The maximum y-value of the data in the first two charts is 99. You'll notice that the y-axis is set at 150 in the first chart where the range is automatically calculated and 100 in the second chart where I specifically set the extreme values. The look of the 2nd chart is what I want. So it seems like setExtremes(0,99,true,false) should do the trick, but it actually doesn't.
In the 3rd chart I changed the data so that the maximum y-value of the data is 101, and I called setExtremes(0,101,true,false). You'll note that the y-axis is now back to 150.
Ideally I want the scale of the graph to be capped on the maximum value to limit the about of extra white space. I want to see all of the data, but I don't necessarily care about the y-axis displaying a maximum band that is greater than the max data value. In this case, I would be happy with the y-axis displaying 100 on the axis and some points over but still visible.
Does anyone know how to make this work?
I ended up using the endOnTick parameter to solve this problem. Adding the following line to the yAxis configuration parameters did exactly what I wanted:
endOnTick: false,
Here's the updated Fiddle showing the results.
https://jsfiddle.net/shannonwrege/z8h5eork/3/
All of the charts look pretty good in my opinion (even the one where the yAxis range was auto calculated).
You will need to read the data and then round up to set the idealMax
var chart,
idealMax = 0; // init the max value
// Read the data to find the highest value
for (i=0;i < (options.series[0].data).length; i++ ){
if (options.series[0].data[i][1] > idealMax) {
idealMax = options.series[0].data[i][1];
}
}
// Round the max to the nearest 10
idealMax = Math.round(idealMax / 10) * 10;
options.yAxis.tickPixelInterval = idealMax/10;
Highcharts.chart('container1', options);
chart = $('#container1').highcharts();
chart.yAxis[0].setExtremes(0, idealMax, true, false);
Updated Fiddle
I'm using the d3 parcoords library. When I modify data plotted in a parallel coordinates chart, and reload the chart, the scale of the axis isn't refreshed.
I tried calling .autoscale(), but if I call it before .render(), it has no effect, and if I call it after .render(), then no polylines are drawn anymore.
$("#example").html(""); //to make sure "ghost" axes are removed
parcoords = d3.parcoords()("#example")
.data(parsedData)
.createAxes()
.brushMode("1D-axes")
.reorderable()//;
.detectDimensions()
.dimensions(dimensionObj)
.autoscale() //no visible effect if placed here
.render()
.updateAxes();
Not sure if this is related (although the issue started at the same time), I started specifying an order for the dimensions. To do this, instead of using an array containing the axes (dimensionArray), I use a JS object dimensionObj containing numbered "index" keys, as follows:
//dimensionArray = ["axis1", "axis2", "axis3", "axis4"]; //orderless array
//Default axes to display with predefined ordering
dimensionObj = {
"axis1": {index:0},
"axis2": {index:1},
"axis3": {index:2},
"axis4": {index:3}
}
For illustration purposes, the following screenshots show how on the top image, the scales are properly set, but on the second (updated) chart, some new polylines are going to 0 on the 1st and 3rd axis, but the scale isn't updated so lines go out of range.
Is there a simple way to refresh the axis scales when reloading a chart? Is it possible that using the JS object in .dimensions() is creating some conflicts with the underlying scale function?
Found what was causing this behaviour: an if statement in d3.parcoords.js pc.autoscale function which was only resetting scales if the yscale was not previously defined. Essentially I edited the if statement from original:
d3.keys(__.dimensions).forEach(function(k) {
if (!__.dimensions[k].yscale){
__.dimensions[k].yscale = defaultScales[__.dimensions[k].type](k);
}
});
to this (of course the if statement could be dropped altogether, I simply kept it in this form in case I need to revert to original version later for any reason):
d3.keys(__.dimensions).forEach(function(k) {
if (!__.dimensions[k].yscale || __.dimensions[k].yscale){
__.dimensions[k].yscale = defaultScales[__.dimensions[k].type](k);
}
});
Take this scenario from a graph I'm working on at the moment:
The problem I'm having is in the bottom left. My dataset's first coordinate is defined at approximately (60,5), yet the domain I'm looking to cover extends right down to 0. Is there any way I can get d3 to extrapolate this data to my origin? I've browsed the API but nothing clearly stands out.
I'm well aware I could just .push a new object with coordinates (0,0) onto my dataset array, but I would prefer not to as I may need to do manipulation with my data later, making this an undesirable option.
Since you have not provided a fiddle i chose to put up a small fiddle to explain this:
My Data set is like this:
data = [{
xval: 10,
yval: 100
}, {
xval: 40,
yval: 90
}, {
xval: 50,
yval: 12
}, {
xval: 90,
yval: 70
}]
You can see the values of x and y value varies from 0 to 100.
So you will define the range like:
x.domain([0, 100]);//this will show x axis start from 0
y.domain([0,100]);//this will show y axis start from 0
example here:
as per your requirement you want the y axis to start from 10 so you do
x.domain([0, 100]);//this will show x axis start from 0
y.domain([10,100]);//this will show y axis start from 10
example here
Hope this solves your problem. ..:)
You can also adjust your data domain to the maximum and the minimum using the extent function that d3 provides.
var x_domain = d3.extent(data,function(d){return d.xval});
var y_domain = d3.extent(data,function(d){return d.yval});
x.domain(x_domain);
y.domain(y_domain);
That way the graph will always be adjusted to the data domain in both coordinates whatever data comes.
Watch this working.
Well, I found an answer to my own question here.
d3 will never extend a line beyond the final data point.
The solution is the following:
If your really must have the line start and end at the very end of your range, then you have two options:
Create a custom interpolation function; or,
Add an "end-value" data point when you pass your data array to d3.svg.line.
For me, it looks like I'm going to have to include a "start value" datapoint. Disappointing.