How to show all x-axis tick values in Plotly? - node.js

I am using this library
https://plot.ly/nodejs/axes/
to plot graphs in node.js. I have this code:
var data = [
{
x: xs,
y: ys,
type: "scatter"
}
];
var graphOptions = {filename: "date-axes", fileopt: "overwrite"};
plotly.plot(data, graphOptions, function (err, msg) {
console.log(msg);
console.log("DONE!");
});
to plot a graph with 5000 x-axis points. The problem is that in the rendered image, it x-axis values are not continuously increment by for each value I put. There is a rather large step, for example, if the x-axis labels are
['item1', 'item2', ..., 'item5000']
then it outputs with labels
['item1', 'item10', ..., 'item5000']
All the yaxis points are there, but I just want to see all x-axis labels.
Does anyone know what setting enables this? I assume that they did this by default so the text labels don't overlap each other, but in my case I want to see them all.
Thanks

I am using Python, though I have encountered the same problem. When you are specifying the layout of your chart, you need to set tickmode='linear', at least it worked for me!
import plotly
import plotly.plotly as py
import plotly.graph_objs as go
layout = go.Layout(
title='some title',
xaxis=dict(
title='Xaxis Name',
tickmode='linear')

Use layout.xaxis.dtick
Example here: https://plot.ly/nodejs/axes/

I run into the same problem and I managed to solve it: the trick is to define your values on xaxis as "categorical".
This is what my code looked like:
var layout = {
xaxis: {
tickangle: 35,
showticklabels: true,
type: 'category',
}
};
Plotly.newPlot(divname, data, layout);

Related

Normalize x values and log y values in d3.js

I am using Scatter plot to visualize data http://bl.ocks.org/mbostock/3887118. I have more than 2 graphs on a page. I want to keep two options where an user can select
1. Normalize button: Values at x-axes will get normalized and new graphs are plotted.
2. log y button: Values at y axes are changed to log y and new graphs are built on the same page accordingly.
How to do this d3.js?
Also I am plotting this using Nodejs, Express and d3.js.
Till now I have built the graphs. These are the options to increase interactivity.
I think the best is to define two different scales:
var yNormal = d3.scale.linear() ...
and
var yLog = d3.scale.log() ....
and on button click redraw the circles using the other scale:
//in button event handler
if( /* log */) {
svg.selectAll(".dot").attr('cy', function() { return yLog(d.yourDataField); }
}
else {
svg.selectAll(".dot").attr('cy', function() { return yNorm(d.yourDataField); }
}
You can also use transition to animate the redraw like this:
svg.selectAll(".dot").transition().duration(500).attr('cy', function() { return yLog(d.yourDataField); }
You can also animate the rescaling of the axis using this method.
You can apply the same to X axis as well.

How to manage event through a fill color with highchart?

I've got two series in an Highchart graph. Both are handling event like mousemove (to show tooltip) and mouse click.
Unfortunatly one of those series is an area serie which block any event to be triggered by the other one.
Let's say I've got those series with those plot options :
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function() {
alert ('Category: '+ this.category +', value: '+ this.y);
}
}
}
}
},
series: [{
color:'red',
data: [29.9, 51.5, 16.4, 19.2, 44.0, 16.0, 35.6, 48.5, 26.4, 4.1, 9.6, 54.4]
},
{
type:'area',
data: [39.9, 75.5, 120.4, 150.2, 130.0, 120.0, 140.6, 158.5, 216.4, 194.1, 95.6, 54.4]}
]
}
as seen in this JSFiddle
I can never click or see the tooltip on the red series points.
What I could do is to change the order of the series so the red one is over the blue one.
( like this). But I've got situations where I've got several area graphs over each other like that. In this case, change the order won't help.
Is there a way I can handle events through the fill area?
Ok I found a way that suit my need : manimulating SVG element order as indicated in this topic :
SVG re-ordering z-index (Raphael optional)
I'm using this code in the redraw event of the chart :
redraw : function(){
//get a reference on the first series svg element.
var svgSeriesParent = document.querySelectorAll('.highcharts-series')[0];
//loop on all the path drawn by highchart
var pathArray = document.querySelectorAll('path');
for (var pathIndex = 0; pathIndex < pathArray.length; pathIndex++) {
var pathObj = pathArray[pathIndex];
//if attribute fill is not "none", this is an area path.
if ($(pathObj).attr('fill') !== "none") {
//move the current fill path before the first series svg element.
svgSeriesParent.insertBefore(pathObj, svgSeriesParent.firstChild);
}
}
}
See the result in this JSFiddle
Limitation :
The fill area doesn't have the same svg group anymore thus, hidding / showing the series is broken : all the fill area are considered being part of the first series. (click in the legend to see it).
In my case I don't need to hide series so I'll go on with this solution.
The svg order manipulation is not complicated that's why I would expect highchart to manage this case : add a fillZIndex parametter doesn't seem difficult and could be pretty usefull...
Only what comes to my mind is using 4 series, 2 area and 2 lines and use index.
http://jsfiddle.net/j8qYK/3/

Flot reset zoom

I'm using Flot Charts with mouse scroll to zoom in and out. I created a button to call zoomOut() and it works well, but I can't find any solution to how I can zoom out all the way so that it Looks just like when it was first loaded. I don't want to reload that who container because it using ajax to pull data from mysql on refresh.
I Googled but couldn't find anything.
You can also set a double click to reset the zoom function of the Flot chart. It redraws the Flot chart to its original state and can be used with dynamic data.
$("#placeholder").dblclick(function () {
plot = $.plot(placeholder, dataset, options);
});
You can set the ranges of the axes to null. By setting this, the zoom level will be set so every data point is visible, just like the default zoom level.
Unlike the other solutions, this solution will not construct a whole new plot.
var axes = plot.getAxes(),
xaxis = axes.xaxis.options,
yaxis = axes.yaxis.options;
xaxis.min = null;
xaxis.max = null;
yaxis.min = null;
yaxis.max = null;
// Don't forget to redraw the plot
plot.setupGrid();
plot.draw();
You can save your initial ranges of axes and redraw your plot like in example for navigating. But your code will be look like these:
// do the zooming
plotObjectPointer = $.plot(placeholder, plotData,
$.extend(true, {}, options, {
xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to },
yaxis: { min: ranges.yaxis.from, max: ranges.yaxis.to }
}));
where ranges will be your initial ranges. To prevent repeated Ajax loading you can use window.localStorage or just another var for storing plotData.

Display custom tool tip in Jqplot Line chart?

For example I have plotted a line chart based on the date and number of students registered on a particular day on x and y axis respectively. When i mouse over to a particular point in the line chart i can view the tool tip displaying the x and y axis values. Instead I want to display the names of the students registered on that day when I mouse over to a particular point. Is there any solution for this problem? If there is no work around with Jqplot, please suggest me any other charts.. Please help me out. Thanks in advance.
Here's a little example I put together for you.
It uses the largely undocumented tooltipContentEditor property of the highlighter plugin:
highlighter: {
show: true,
sizeAdjust: 7.5,
tooltipContentEditor:tooltipContentEditor
}
Where your data is predefined like:
var students = [
['Bob','Mark','Dave'],
['Tim','Mike']
];
var data = [students[0].length,students[1].length];
function tooltipContentEditor(str, seriesIndex, pointIndex, plot) {
// display series_label, x-axis_tick, y-axis value
return students[pointIndex].join(", ");
}

jQuery Flot: Change xaxis when zooming

Is there a way I can get the x-axis to switch from showing hour, to e.g. week days, months .. when zooming out?
Currently my x-axis is configured as such:
xaxis: {
mode: "time",
minTickSize: [1, "second"],
timeformat: "%H:%M:%S",
}
My default the graph looks nice, but when I zoom out enough times, the labels on the xaxis just display "00:00". How can I change the timeformat so that the date is included also? E.g. Tue 27 00:00 or similar.
Here's an example of when the graph is zoomed out a lot (obviously I need to remote some datapoints to make it look smoother..)
You can add a date using the standard specifiers, like %Y-%m-%d. A full list can be found in the API docs under the Time Series Data section.
To get the format to update based on the range, i.e. show HMS when zoomed in but YMD when zoomed out, is trickier. You'll need to listen for the 'plotzoom' event and check the range to see whether the format needs to change. If so, use getOptions() to retrieve and update the plot's options, then call setupGrid & draw to redraw the plot using the new format.
I solved this by making a custom tickFormatter for the X-axis:
In your xaxis options put:
xaxis: {
mode: "time",
tickFormatter: customXAxisFormatter,
...
}
Then your customXAxisFormatter could be eg. :
function customXAxisFormatter(val, axis)
{
var d = new Date(val);
// If time difference is more than 24 hours
if ((axis.max - axis.min) > (24*3600*1000))
return d.strftime("%a<br>%H:%M");
else
return d.strftime("%H:%M");
}
I hope this helps :)

Resources