D3 axis origin changes as per its scales range - javascript

I am a little confused on how D3s axis object takes its origin position and where it is anchored(I assume its top left)
Also it seem like the origin point changes as per the range of the associated scale for instance,the two axis below would start at different position
1st axis
//Xscale with scale not augmented
var stageXScale=d3.scaleLinear()
.domain([0,150])
.range([0,150]);
var stageXAxis = d3.axisBottom(stageXScale) //unaug axis
.ticks(20);
2nd axis
//scale which is augmented
var stageXScaleAug=d3.scaleLinear()
.domain([0,stageWidth])
.range([0+stageMarginLeft,150+stageMarginLeft]);
var stageXAxisAug = d3.axisBottom(stageXScaleAug) //aug axis
.ticks(20);
Isn't the origin of the axis mapped to the origin of the parent container,if so why does the scale of the axis change this.
Here is Js fiddle example :
https://jsfiddle.net/Snedden27/3wsx8bdy/12/

The position of the origin of the axis (prior to transform) is determined by the minimum value of the range of the scale.
For axis 1, the range is [0,150] and the axis starts at screen x-coordinate 0 of the parent element. (The axis ends at x-coordinate 150.)
For axis 2, the range is [0+stageMarginLeft,150+stageMarginLeft], so that axis starts at screen x-coordinate stageMarginLeft (20) of the parent element.

Related

D3: Use brush to zoom to specific interval

please see the following D3 example:
https://bl.ocks.org/mbostock/f48fcdb929a620ed97877e4678ab15e6
In this example, the user is able to draw a brush on the screen and then the graph zooms to the region encapsulated by the brush. The way this example works is by updating the x and y scale domains based on the brush extent. You can see that in the brushended() function.
I am looking to achieve this same functionality. However, I do not want to update the x and y scale domains but want to update the zoom scale and translate. The following example achieves this for a map:
https://bl.ocks.org/mmazanec22/586ee6674f52840492c16cc194aacb1f
You can see this is the brushend() function. Here the writer calculates a scale and translation based on the brush extent and then uses them to set a new scale and translate for the zoom behaviour. I am looking to achieve this however for a scatter plot.
I have a written an example of what I have tried in this jsfiddle: https://jsfiddle.net/SSS123/uxdd760k/1/ - see the part where I do my scale and translate calculations below:
var extent = brush.extent();
// Get box coordinates
var lowerX = d3.min([extent[0][0], extent[1][0]]);
var upperX = d3.max([extent[0][0], extent[1][0]]);
var lowerY = d3.min([extent[0][1], extent[1][1]]);
var upperY = d3.max([extent[0][1], extent[1][1]]);
var scale = Math.max( ( width / (x(upperX) - x(lowerX)) ), ( height / (y(upperY) - y(lowerY)) ) );
graphContainer.transition()
.duration(750)
.call(zoom.scale(scale).translate([-x(lowerX), -y(upperY)]).event);
I believe this now works fine for the case when you draw a brush with a width the same size as the height i.e. if you try drawing a box that stretches from 0 to 5 on the xAxis and 0 to 5 on the yAxis then this will zoom in quite well.
However, if you draw a box with 0 - 5 on the xAxis but 0 - 30 on the yAxis then this will no longer calculate a sensible zoom scale.
Has anyone any advise on how to solve this?

Graph points between ticks - crosshair height equal with the point y

Is it posible to display graph points between ticks to represent a duration period?
Is crosshair, in x axis, able to have custom height according to the y of the graph's point.
Can tick step:2 to begin with empty value?
Expectation:
Reality:
fiddle.jshell.net/ssbeefeater/fx5d8wvk/

NVD3: Have labels at certain tick values at the top of the graph

I am using NVD3 to draw a graph that uses an ordinal scale on the x axis for dates. I also have a "focus graph" under it to highlight a specific region to display. To automatically update the ticks that are displayed, I use the tickValues() property.
I want to have label on specific dates at the top of the graph. My solution for this was to create another x axis, but above the the graph, plot the same data, but with a 0 height, and then use tickValues() to set the position of the labels. However, the labels don't show up on the top axis. Is there a solution or alternative?
I guess using a secondary x axis is fine. I forgot to remove the line setting the domain property for my secondary axis. When I removed that, it scaled just like my primary axis :)

Highstock data points pixel spacing

Is there a way to set point spacing in pixels on x/y axis for highstock? For example data points should be 5px apart.
Also is there way to shift chart left or right? For example shift all data points 5px right or left?
The spacing between points can be control by
pointPadding
groupPadding
pointWidth
If you want the points of a line to be a certain distance apart, you need to make sure that the width of the plot area, divided by the number of points , equals that pixel value.
(or divided by the number of axis units, if you are artificially setting a min and max beyond the range of the data)
There can't possibly be a property to account for this - it's all about the space available and the number of points.
As for shifting left or right, it depends exactly what you mean. If you're looking to add spacing to the left or right end of the x axis, you can use midPadding or maxPadding.
http://api.highcharts.com/highcharts#xAxis.minPadding
http://api.highcharts.com/highcharts#xAxis.maxPadding

Raphael js: Scale and translate elements in a set proportionally

It seems that if you scale a set in raphael, it will scale the elements inside, but not translate them proportionally. So for instance if I have two squares next to each other in my set, and I scale the set up, the squares begin overlapping each other instead of the second square moving over as it resizes in order to stay right next to the first square. Is there a way to get this behavior in raphael?
As Ian mentioned, the key is to set the X,Y origin for the scale. By default, when you scale an element, it uses the geometric center of the element as the origin to scale from:
path.transform('S1.5'); // Scale 1.5x in both axis
So if you scale a set of objects, it will scale each individual element from it's own individual geometric center.
But you can optionally set an X and Y origin for the scale:
path.transform('S1.5,1.5,0,0'); // Scale 1.5 in X and 1.5 in Y, with origin set at the Paper's 0,0 as the origin.
Therefore, if you have a set of elements, and all of them are scaled using the Paper's 0,0 as their scale origin, then they will all scale proportionally to each other.

Categories