Update the variable of sliderState after setting new min, max values - javascript

Sorry, I'm begginer in js, I want to update sliderState after changing min, max of the slider.
I've functions which update min, max in slider, also I have the variable which is calculated from min, max.
I need update to this variable.
const sliderStates = [
{
name: "low",
tooltip: "Great, we're confident we can complete your project within <strong>24 hours</strong> of launch.",
range: _.range(state.minValue, state.maxValue / 3)
},
{
name: "med",
tooltip: "Looks good! We can complete a project of this size within <strong>48 hours</strong> of launch.",
range: _.range(state.maxValue / 3, (state.maxValue / 3) * 2)
},
{
name: "high",
tooltip: "With a project of this size we'd like to talk with you before setting a completion timeline.",
range: _.range((state.maxValue / 3) * 2, state.maxValue + 1)
},
];
//update min
connector.updateMin = function (min) {
let attributeMin = {
min: min,
};
$element.attr(attributeMin).rangeslider('update', true);
}
//update max
connector.updateMax = function (max) {
let attributeMax = {
max: max,
};
$element.attr(attributeMax).rangeslider('update', true);
}

Related

how to get dynamic step size in react-chartjs-2

I am using Chart.js to draw graphs in typescript.
I want to get a dynamic weight and bring a minimum and a maximum. And with maxTicksLimit as 5, I want to keep 5 Ticks no matter what data comes in.
The decimal point of body weight is taken to the first decimal point.
ex) 50.3
I want to show the difference between minimum and maximum as much as possible.
please help me!!!
ex1) maximum weight: 74.5, minimum weight: 71
result
Y Axis maximum weight: 76 , Y Axis minimum weight: 71
ex1 result image
enter image description here
ex2) maximum weight: 76.9, minimum weight: 62
result
Y Axis maximum weight: 76 , Y Axis minimum weight: 61
ex2 result image
enter image description here
The beforeBuildTicks callback also works to create a dynamic tick step size. Here is the code:
{
maintainAspectRatio: false,
tooltips: {
mode: 'label',
position: 'nearest',
},
scales: {
xAxes:[
{...}
],
yAxes: [
{
position: 'left',
id: 'y-axis-0',
scaleLabel: {
display: true,
labelString: 'label string goes here',
fontSize: 16,
},
ticks: {
beginAtZero: true,
stepSize: .25,
},
beforeBuildTicks: function(axis) {
if (axis.max >= 17) {
axis.options.ticks.stepSize = 1;
} else if (axis.max >= 10) {
axis.options.ticks.stepSize = .5;
}
}
}
]
}
}
I solved this problem in the following way.
There was a callback function of afterBuildTicks in chart.js
※ chart.js documents link.
It becomes possible to customize the ticks.
//... middle code skip
const getChartMaxAndMin = (
maxValue,
minValue
): { max: number; min: number } => {
// Convert all decimal places to integers
let max = Math.ceil(maxValue);
let min = Math.floor(minValue);
// a multiple of 5
const MULTIPLES = 5;
const DIVIDED_REMAINING_VALUE_LIMIT = 3;
// Maximum to Minimum difference
const diff = max - min;
const diffDividedRemainingValue = diff % MULTIPLES;
const remainingValue =
MULTIPLES *
(diffDividedRemainingValue > DIVIDED_REMAINING_VALUE_LIMIT
? Math.floor(diff / MULTIPLES) + 2
: Math.floor(diff / MULTIPLES) + 1) -
diff;
if (remainingValue % 2 !== 0) {
max = max + Math.floor(remainingValue / 2) * 2;
min = min - Math.floor(remainingValue % 2);
return { max, min };
}
max = max + remainingValue / 2;
min = min - remainingValue / 2;
return { max, min };
};
const customizedAxesTicks = (axis) => {
const EQUAL_PARTS = 5; // set 5 parts
const max = axis.max;
const min = axis.min;
const steps = (max - min) / EQUAL_PARTS;
const ticks = [];
for (let i = min; i <= max; i += steps) {
ticks.push(i);
}
axis.ticks = ticks;
return;
};
const {max, min} = getChartMaxAndMin(68,57);
const chartOptions = {
//... code skip
scales: {
yAxes: [
{
//... code skip
ticks: {
max: max,
min: min
},
afterBuildTicks: customizedAxesTicks,
//... code skip
};
I would appreciate it if you could let me know if there is a better way😀

Highcharts yAxis.max manage tick intervals dynamically

I'm trying to set the max and min of y value dynamically based on the data but it is having some troubles for some values. I think the highchart couldn't set values that doesn't have a proper tick.
For eg: min: 3 and max 10. Then, the highchart won't set these values instead of that it will set a value ranging from 0...14. This is just an example value, sometimes I get 36000.14 as min and 454533.18 as max.
So my logic isn't working in that case.
This is the part of code which I currently have:
data = [3.43, 3.58, 4.86, 8.55, 8.77, 4.44, 9.67]
maximum_val = Math.ceil(maximum_val) eg: 10
minimum_val = Math.floor(minimum_val) eg: 3
evolution_options.yAxis[$('#div_count_'+div).find('#y_axis_lbl').text()] = {
min: minimum_val,
max: maximum_val,
title: false,
labels: {
style: {
color: 'black'
}
}
}
Update
Fiddle : http://jsfiddle.net/e3fy1vu9/
Further Brainstorming
I think it is because the min value isn't a multiple of the max value so Highchart couldn't calculate how to split the tick. If there was any way so I could set the max value as the multiple of the min value.
Here is my advice how to calculate the max and min for yAxis from the defined data.
Demo: https://jsfiddle.net/BlackLabel/0qwt1kx7/
yAxis: {
min: Math.floor(Math.min(...data)),
max: Math.round(Math.max(...data)),
tickAmount: Math.round(Math.max(...data)) - Math.floor(Math.min(...data)) + 1 //1 count the min or max as itself
},
Please test it and let me know if it fits to your requirements. Because the tickAmount value depends on how many values is included in the data array and probably some modifications are needed for larger data.
EDIT:
Try to use this custom solution to calculate the yAxis positions:
Demo: http://jsfiddle.net/BlackLabel/ztaj6Lkd/
var positions = [],
tickNumbers = 5,
tick = Math.floor(Math.min(...data));
for(let i = 0; i < tickNumbers; i++) {
positions.push((Math.round(tick * 100) / 100));
tick += Math.round(Math.max(...data)) / tickNumbers
}
//add the max
positions.push(Math.round(Math.max(...data)))
Hi I have fixed it by setting this alignTicks:false option.
evolution_options.yAxis[$('#div_count_'+div).find('#y_axis_lbl').text()] = {
min: minimum_val,
max: maximum_val,
title: false,
labels: {
style: {
color: 'black'
}
},
alignTicks: false
}

How to get the current price of custom chart with Javascript lightweight-chart API?

How can I get the price shown in the chart at the right side of my chart marked in blue.
This is my code so far:
const chart = LightweightCharts.createChart(document.body, { width: 1500, height: 700 });
const lineSeries = chart.addLineSeries();
const log = console.log;
lineSeries.setData([
{ time: '2019-04-11', value: 80.01 },
{ time: '2019-04-12', value: 96.63 },
{ time: '2019-04-13', value: 76.64 },
{ time: '2019-04-14', value: 81.89 },
{ time: '2019-04-15', value: 74.43 },
{ time: '2019-04-16', value: 80.01 },
{ time: '2019-04-17', value: 96.63 },
{ time: '2019-04-18', value: 76.64 },
{ time: '2019-04-19', value: 81.89 },
{ time: '2019-04-20', value: 74.43 },
]);
function randomIntFromInterval(min, max) {
return Math.round((Math.random() * (max - min + 1) + min) * 100) / 100;
}
var startDate = new Date();
var endDate = new Date(2020, 5, 1);
log(lineSeries);
// lineSeries.applyOptions({
// priceFormat: {
// type: 'custom',
// minMove: 0.02,
// formatter: function(price) {
// log(price); //Gives me the price in a very bad way. Also gives it when i hover over chart.
// return '$' + price;
// },
// }
// });
/**
* Updates the chart its lines randomly.
*/
function updateChartStatic() {
setTimeout(() => {
//For updating the date.
let newDate = new Date(startDate);
//Creates a random int.
let randomInt = randomIntFromInterval(randomIntFromInterval(50, 100), randomIntFromInterval(75, 125));
// log(randomInt);
log(lineSeries._series._priceScale.rn.ct);
//Updates the line of the chart.
lineSeries.update({
time: newDate.getFullYear() + '-' + (newDate.getMonth() + 1) + '-' + newDate.getDate(),
value: randomInt,
});
//Makes sure the loop can actually end by adding a day to the startDate.
startDate.setDate(startDate.getDate() + 1);
//Make sure the function will be called again if startDate and endDate date not matches with each other. If they do, the loop will end and a console log will be shown.
startDate <= endDate ? updateChartStatic() : log("END LOOP");
}, 1000);
}
updateChartStatic();
Atm I update the lines randomly between some numbers. I need to know the price to make sure the lines update based on the current price. So a new line would be for example 50 dollar/euro in price higher or lower then the current price. This would make it less pointy :) In pseudo code:
let randomInt = randomIntFromInterval((currentPrice - 50), (currentprice + 50));
An alternative to get the last value added to your lineSeries data is by Saving the data before doing another line update with your setTimeout. E.g.,
/**
* Updates the chart its lines randomly.
*/
function updateChartStatic() {
// Array where we store all our added prices.
var oldPrices = [];
setTimeout(() => {
// Creates a random int.
let randomInt = randomIntFromInterval(randomIntFromInterval(50, 100), randomIntFromInterval(75, 125));
// Logs OLD price. First time will be empty in this case
log(oldPrices[oldPrices.length - 1]);
// Updates the line of the chart.
lineSeries.update({
time: newDate.getFullYear() + '-' + (newDate.getMonth() + 1) + '-' + newDate.getDate(),
value: randomInt,
});
// Add your currently set price to the array of prices.
oldPrices.push(randomInt);
}, 1000);
}
Old prices are stored in var oldPrices.
Here's another example from tradingview.com. https://jsfiddle.net/TradingView/8a29s0qj/

jqxChart with relative values

I was playing around with the waterfall series of the jqxChart.
According to its API, the following piece of code defines the values of the axis, in this case it's the y-axis:
valueAxis:
{
title: {text: 'Population<br>'},
unitInterval: 1000000,
labels:
{
formatFunction: function (value) {
return value / 1000000 + ' M';
}
}
}
Is it possible to define the intervals not with absolute values, but with relative values. So that the interval are e.g. 10% and the overall value is 100%?
Simply doing unitInterval: '10%' doesn't work.
This is how it should look like:
Here is a fiddle.
I think you're looking for these options :
logarithmicScale: true,
logarithmicScaleBase: 1.10,
Example:
valueAxis:
{
title: {text: 'Population<br>'},
logarithmicScale: true,
logarithmicScaleBase: 1.10,
labels:
{
formatFunction: function (value) {
return value / 1000000 + ' M';
}
}
},
Edit:
var accuracy = 2;
var first = data[0].population;
var last = data[data.length - 2].population;
var unit = (100 / last);
// convert raw data to differences
for (var i = 0; i < data.length - 2; i++)
data[i].population = (data[i].population * unit).toFixed(accuracy);

How to create scales between min and max value using ranges in javascript?

I need to create a dynamic scales something like this
Range 1 = 0 to 100
Range 2 = 100 to 200
Range 3 = 200 to 300
Range 4 = 300 to 400
Range 5 = 400 to 500
Range 6 = 600 to 700
Range 7 = 700 to 800
Range 8 = 800 to 900
Range 9 = 900 to 1000
Here, ranges are 1 to 9 and minimum value is 0 and maximum value is 1000. These ranges, minimum and maximum values are dynamic.
So, I required a function to return the scales.
For example:-
function getScales(minRage, maxRange, minValue, maxValue){
var scales={};
..........
............
return scales;
}
//Output:
[
{
range :1
min :0,
max :100
},
{
range :2
min :100,
max :200
},
{
range :3
min :200,
max :300
},
....
....
{
range :9,
min :900,
max :1000
}
]
To get above result , I need to call the function like this getScales(1, 9, 0, 1000).
This is what my actual requirement: if I call getScales(1, 5, 4000, 418500);
Have a look at this:
function getScales(minRange, maxRange, min, max){
var scales = [], // Prepare some variables
ranges = maxRange+1 - minRange, // Amount of elements to be returned.
range = (max-min)/ranges; // Difference between min and max
for(var i = 0; i < ranges; i++){
scales.push({
range: i+minRange, // Current range number
min: min + range * i,
max: min + range * (i+1)
});
}
return scales;
}
You can call the function like this:
getScales(0, 9, 0, 1000);
Output:
[
{
"range": 0,
"min": 0,
"max": 100
},
{
"range": 1,
"min": 100,
"max": 200
},
.......
{
"range": 8,
"min": 800,
"max": 900
},
{
"range": 9,
"min": 900,
"max": 1000
}
]
To get rid of the floating point errors in the output, you can replace:
min: range * i,
max: range * (i+1)
With:
min: (range * i).toFixed(2),
max: (range * (i+1)).toFixed(2)
Replace the 2 with the desired amount of digits behind the decimal point.
Something like that:
var factory = function(start, end, minV, maxV){
var result = [],
st = (maxV - minV) / (end - start + 1),
buffer = minV;
for(var i = 0; i <= end - start; i++){
buffer = st * i + minV;
result.push({
range: i,
minValue: buffer.toFixed(2),
maxValue: (buffer + st).toFixed(2)
});
}
return result;
}
console.log(JSON.stringify(factory(0, 4, 253, 467)))
Some explanation: #start and #end describe number of ranges, #minV - first range starts with this value, #maxV - last range ends with this
Output
[{"range":0,"minValue":"253.00","maxValue":"295.80"},{"range":1,"minValue":"295.80","maxValue":"338.60"},{"range":2,"minValue":"338.60","maxValue":"381.40"},{"range":3,"minValue":"381.40","maxValue":"424.20"},{"range":4,"minValue":"424.20","maxValue":"467.00"}]
Play with demo

Categories

Resources