flot: zoom, hover and series selection in the same plot - javascript

I am trying to plot 3 different series on the same plot. I want to do the following in the plot:
allow the user to select which series are plotted ("Turning series on/off" example on the flot website),
allow the user to zoom in and zoom out ("Rectangular selection with zooming" example),
show the values of the curves when the user hovers the mouse ("Tracking curves" example).
I have been trying to make it work for a long time now, and I can't get everything to work. My current attempt fails to properly turn series on/off. As soon as I check a box, the graph becomes blank. The javascript file which defines all the plotting functions etc., is plot_displacement.js.
The relevant part of the code is:
var choice_container = jQuery("#choices");
choice_container.find("input").change(do_plot);
The HTML is:
<p id="choices">Show:</p>
<div id="plotdiv" style="width:600px;height:300px;position:static;"></div>
I am using change and not click because of this question's answer. If I use click, then selecting/unselecting the checkboxes doesn't seem to have any effect.
I am sure I am overlooking something simple, but I can't figure out what. I would love to be able to do all the 3 things that I am trying to do in flot.
Thanks!

Your problem is simply that do_plot is being called from your change event with xmin being a jQuery Event object. You expect it to be undefined and then set to 0, but instead you're passing xmin: jQuery.Event to flot, which doesn't know what to do with it.
Edit: Since someone asked, the actual code you might want to put in there, when checking if xmin is undefined, additionally check whether it is an object (jQuery.Event has a typeof object):
if (typeof(xmin) == 'undefined' || typeof(xmin) == 'object') xmin = 0;

Click does work for me.
I use the code from the Flot example:
$("#checkboxes").find("input").click(plotAccordingToChoices);
Clicking the checkboxes calls:
function plotAccordingToChoices() {
var data = [];
$("#checkboxes").find("input:checked").each(function () {
var key = $(this).attr("name");
if (key && datasets[key])
data.push(datasets[key]);
});
if (data.length > 0){
plot = $.plot($("#chart1"), data, options);
}
}
datasets is a global array keyed by the set name and was created at initialization.

Related

Creating datapoints on mouseclick Chart.js

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();

Which plot.ly json property enables all hover data to be displayed when hovering over one line

I am plotting two lines on a graph in Matlab, and converting it to plot.ly using the Matlab library. When I use the 'strip' = false json property, it preserves the Matlab layout. However, it removes the nice feature where by you get all the data when you hover over one line. When 'strip' = false, you only get data pertaining to the line you hover over.
Does anyone know how to use 'strip' = false and yet retain all the hover overs?
Sample code in Matlab:
X = linspace(0,2*pi,50)';
Y = [cos(X), 0.5*sin(X)];
figure
plot(X,Y)
Then generate two plot.ly plots:
fig2plotly(gcf, 'strip', 0);
fig2plotly(gcf, 'strip', 1);
These can be respectively found at:
https://plot.ly/~alexdp/0
https://plot.ly/~alexdp/2
Note the difference in the hover over behaviour.
When you convert a matlab figure to Plotly Figure with strip=false, the hovermode attribute is set to closest by default, hence it only shows data pertaining to nearest curve on hovering. To override this behaviour:
X = linspace(0,2*pi,50);
Y = [cos(X), 0.5*sin(X)];
figure
plot(X,Y)
% Convert the chart..
plotly_fig = fig2plotly(gcf, 'strip', 0)
% Set hovermode to blank (basically disable the attribute)
plotly_fig.layout.hovermode=''
% Send the updated figure to plotly:
resp = plotly(plotly_fig)
url = resp.url

canvas js: how to remove a datapoint dynamically but without creating a "hole" in chart?

After hours and hours playing with canvasJS I couldn't find a way to dynamically remove points from my chart in an elegant way.
What I want to do is to allow users to select/deselect data he want to see plotted. For instance, on a chart that shows data from Jan/2014 to Dec/2014 (axis X), if the user choose not to show Feb/2014, I iterate thru dataPoints, remove such point and call render(). The column with data corresponding to February then disappear, but on X axis, the label for February is still shown, creating a "hole".
If First or Last item is deselected, then the result is OK, such month is not displayed.
I have tried using Date() for x, tried using Integers for x and formatting the Date as a label but none worked for me.
So, before starting looking for another solution I would like to know if you guys could help me out figuring what I`m doing wrong.
Best regards!!
I have gone through the question and created an example. Here is the JSFiddle
Here is the logic which I used:
for(var i=0; i<dataPoints.length ; i++){
var dp = dataPoints[i];
var dataPointMonth = (new Date(dp.label).getMonth());
if( dataPointMonth !== monthToHide){
dp.x = index++;
newDataPoints.push(dp);
}
}
You can use labels instead of x value in this case and use formatDate method in order to format date values as required and use labelFormatter for further customization.
labelFormatter : function ( e ) {
return CanvasJS.formatDate( e.label, "MMM");
}

highstock chart click get closest point

I use Highstock to display time series data and I want to get the closest data point to the point where a user clicks on the chart. Is there any API to do it ?
P.S: I know how to do it by getting xAxis value and searching over series but I want to know is there any built-in function or not ?
Thank you
There's no official API to get this.
However, look int othe sources, where you can find: runPointActions method. You can use exactly the same solution as for shared tooltip or default one.
Snippet from sources:
// Separate tooltip and general mouse events
followPointer = hoverSeries && hoverSeries.tooltipOptions.followPointer;
if (hoverSeries && hoverSeries.tracker && !followPointer) { // #2584, #2830
// get the point
point = hoverSeries.tooltipPoints[index];
// ABOVE LINE IS INTERESTENING, RIGHT? ;) where: index = pointer.getIndex(e),
// a new point is hovered, refresh the tooltip
if (point && point !== hoverPoint) {
// trigger the events
point.onMouseOver(e);
}
}

in d3js how can I filter data by clicking on stack bar

I'm trying to filter data by clicking on certain rect bar in a stacked bar. This stack bar is a two dimention graph, the horizontal index is years, and the vertical index different product revenues, I want to filter by certain product in certain year. means when I click on a rect bar of the whole graph, the data should get filtered by certain year and certain product.
my code is :
metrics.on("click", function(d,i,j){
d3.select(this)
.style("fill","lightcoral")
.style("stroke","red");
fdata =rawdata.filter(function(d){return (d[xvalue]==_seriesA[i])&&(d[yvalue]==_seriesB[j])});
});
but the weird thing is the value of j is always undefined, although if I attach a title to it :
metrics.append("title").text(
function(d,i,j) {
return i + ' - '+j ;
});
the value of j will get printed correctly, is there anything special about the 'on' click function? why I cannot get the value of j? any help will be appreciated....this is triving me crazy for the whole night...
According to the documentation, the second argument to .on() is a function that takes two arguments, not three. Similarly, it shouldn't work in your second example either.
I think you're getting confused about the distinction between the data and how it is rendered. The .on() function will get you the data. The scales you have created somewhere in your code take that data and map it to x and y coordinates in your graph (or you use the data directly without scales). In the .on() function, you use the data in exactly the same way you used it when you created the graph to start with. That is, the data item (d in your code) contains the data for the specific position that you're highlighting.

Categories

Resources