Flot bar chart - margin for the the largest bar - margin

Normally, the longest bar spans to the right border.
I want it like you see on the picture.
I've achieved that by computing the max value and setting xaxis: { max: maxValue * 1.1 }. Again, a bit hacky.
I have tried - without success:
grid: {
margin: 30,
minBorderMargin: 10,
},

You can add the autoscaleMargin property to your xaxis options (as long as you aren't setting a min or max value for your xaxis):
xaxis: {
autoscaleMargin: .02
}
From the Flot API documentation:
The "autoscaleMargin" is a bit esoteric: it's the fraction of margin that the scaling algorithm will add to avoid that the outermost points ends up on the grid border. Note that this margin is only applied when a min or max value is not explicitly set. If a margin is specified, the plot will furthermore extend the axis end-point to the nearest whole tick. The default value is "null" for the x axes and 0.02 for y axes which seems appropriate for most cases.
This JSFiddle shows an example of using the autoscaleMargin bump the grid border away from the longest bar value.

Related

How to get the width in pixels of a Y Axis and/or set the width explicitly

I am trying to perform my own logic for hit testing and have dynamic Y Axis that exist within my lightningchart JS charts. At the moment I am off by the amount of pixels that the axis is taking up, but have not found a way to determine this value.
Axis documentation shows the use of Axis.getHeight() which returns the height in pixels for the X Axis.
Is there a way to set/read the width of Y Axis in LightningCharts JS?
Thanks
Edit: As requested for more information.
I am using pointer down/move/end/out to detect finger/pointer/mouse position over the charts.
This particular chart presents for example the following data
[x: 0, y: 20]
[x: 3600, y: 21]
[x: 86400, y: 19]
Where x is time in seconds and y is temperature in Celsius.
This will be represented as a lineseries for visual but also a point series for interaction. Users will be able to drag the points up/down based on an interval of say 0.5C and left/right based on a time interval of say 600 (5 minutes).
On tablet, this interaction must be performed by first tapping on the point (to activate it, and present a tooltip) and then dragging the point. This is to prevent conflict with panning/zooming the chart.
All of the above has been developed and is working for the exception of when the YAxes are visible and impact the chart spacing.
I need a way to calculate very specifically the width of all yAxes collectively to support the manual hit testing logic.
Could you elaborate what kind of hit testing you are doing? It is possible that there is a better way to do it than something based on Axis height, hence I am asking.
The getHeight() method is available for both X and Y axis. To use it for Y axis, just do chart.getDefaultAxisY().getHeight(). However, this method is a bit unreliable - the result can be a frame behind. For example, if you use it immediately when the chart is created, it might return a wrong value. A possible workaround is to use it after a timeout.
Another way to know for sure the width of Y axis is to explicitly configure it yourself with Axis.setThickness(100). This would make the Axis 100 pixels wide always.

How to precisely find thumb position of input [type="range"]?

The idea was to put a tooltip with value related to slider. I thought initially to accomplish that task by using css grid. CSS provides you with grid of any size, 10 or 1000 cols, doesn't matter. By utilizing grid functionality, we can align out tooltip as we wish.
What we really get is:
Thumb position is sort of unpredictable. It seems that it is being offset, and the direction of that offset is dependent on whether input value is in the left or right part of slider.
Note: default thumb behaves exactly the same way. I mean, shape of thumb is not of concern.
So, how does html calculate position of thumb based on its value?
For anyone else stumbling upon this problem, the issue is that the first and last position of thumb are offset by half the width of thumb. Because of this, all of the other positions are slightly offset to compensate for the first and last one.
One simple solution for this is to normalize the thumb position between actual first and last thumb positions which are actually 0 + halfThumb and width - halfThumb respectively.
To normalize, we can use the formula recommended in this answer.
So the left offset of absolutely positioned element in px would be:
const left = (((value - minValue) / (valueMax - valueMin)) * ((totalInputWidth - thumbHalfWidth) - thumbHalfWidth)) + thumbHalfWidth;
Where
value is actual input value.
minValue is actual minimum value for input.
maxValue is actual maximum value for input.
thumbHalfWidth is half of the width of thumb used for slider drag.
totalInputWidth is width of input element in pixels.
You have to take into consideration the size of your thumb
It is possible to achieve this using a little bit of javascript (unless you can get the range ratio which I am not aware of as of now)
Therorical
Calculate the ratio of your current value relative to the min and max of your input (between 0 and 1)
(value - el.min) / (el.max - el.min)
So its position (starting from the arrow relative to the input container) would be:
thumbSize / 2 + ratio * 100% - ration * thumbSize
Method
This might give an idea of how to implement this in javascript
const thumbSize = 10
const range = document.querySelector('input[type=range]')
const tooltip = document.querySelector('.tooltip')
range.addEventListener('input', e => {
const ratio = (range.value - range.min) / (range.max - range.min)
tooltip.style.left = `calc(${thumbSize / 10}px + ${ratio * 100} - ${ratio} * ${thumbSize}px)`
}
This above code has not been tested but the same method has been implemented

Dynamic Sizing of Circles Along a Spiral

I have created an logarithmic spiral in canvas, and plotted circles along it. Using your mouse scroll wheel you can zoom in and out of the spiral (which works) – but I am having problems updating the size of the circles to match the zoom level... I'm no math expert!
There are two values I am using when trying to calculate the circle radius:
The initial size: This makes circles smaller the further down the spiral they are. I think I have this pretty close.
The growth size: This is the amount that each circle must increase to accurately grow in size as it gets closer to the viewer. Currently circles seem to be the correct size at the beginning and end of the spiral, but are too small in the middle.
I have hacked together some janky math and I'm sure there is an actual formula for this sort of sizing. Any help would be greatly appreciated – I just want the circles to feel "attached" to the spiral and scale appropriately.
Here is the jsFiddle for reference
// a = starting radius of spiral
// spiralNum = spiral length (100.6)
// timeOffset = scroll position
// node_count_visible = number of total circles
offset = (this.spiralNum - 0.05 - this.node_count_visible) + id + (this.timeOffset/30);
var initial = Math.exp(b * offset)/4;
var growth = (a/8.5);
node.radius = initial + growth;
Thank you in advance for any help provided...
I was able to get an affect you are looking for by doing
node.radius = a * Math.exp(b * offset)/6;
6 is an arbitrary number to adjust the size of the circle.

Colors in treemap

it would be great to clarify how colors are calculated when ploting treemap (I use gvisTreeMap function from R googleVis library).
Documentation is not very informative. What is it meant by "The color value is first recomputed on a scale from minColorValue to maxColorValue"? Usually I use treemap to display sales (size) and sales difference (color). So ideally I would like to color rectangles so that I can distinguish positive from negative growth, which as I understand is not possible at the moment.
What bothers me most right now is that "... colors are valued relative to all other nodes in the graph". Is there any way to fix colors, so that sales difference, say -25 always gets the same color.
If I have understood your problem correctly, I believe the following will solve it:
Let's say your data is percentages, so can go from 0 to 100. Set minColorValue=-100 and maxColorValue=100
(Or if using a different range, just set it so that the min value is the negative of the max value so that the average is 0.)
Then, if you set the colours to, for example, minColor='red' and maxColor='green', this should solve part 1 (negative values will be displayed in red, and positive in green)
Also, it seems that setting maxColor and minColor fixes the average value the colors are calculated from, so that this also solves part 2 (that is, -25 will then always have the same color in the graph)
Color is computed as the average color value of all child nodes of a branch. A branch with no child nodes uses the color value from the DataTable. This color value is then scaled on the minColorValue to maxColorValue scale, and a color is computed between minColor and maxColor based on the scale.
Colors are not relative to other nodes on the graph - the size of the node is relative.

Flex Chart : Minimum column height

In Flex columnchart, the height depends on the value, when 2 values have much difference.
the smaller value is not very clearly shown on the axis. Is it possible to define the minimum height of column to show, so that even a very small value can be seen?
Typically, in any charting library you'll want to do this by controlling the vertical axis. For example, consider the following data
Foo | Bar | Baz
0.7 | 30 | 80
If you were to chart this and let flex automatically calculate the vertical axis and it chooses for the vertical axis to go from 0.7 to 80 then Foo will barely show up.
However, if you were allowed to specify the vertical axis then you could programatically choose good axis values. For example, let maximumValue be the (previously calculated) maximum value of your data and let minimumValue be the (previously calculated) minimum value of your data. Then you can set your axis min and max as follows...
axisMinimum = minimumValue - ((maximumValue - minimumValue) * 0.2)
axisMaximum = maximumValue + ((maximumValue - minimumValue) * 0.2)
This would ensure that the smallest value in your chart appears at the 20% (0.2) position in your chart and the maximum value appears at the 80% (1-0.2) position of your chart. You can play with the multipliers to get a chart that looks good to you.
The only disadvantage you'll find is that when charts are very close in value then this will make them seem even closer.

Resources