How to get specific bar or line color applied to its data series in subscribeCrosshairMove event - lightweight-charts

i want to create a tooltip with specific color for example todays date have red color then tooltip text going to be red and next line or bar is green then tooltip color will change to green
i am able to get the current price of each series and its static option but as you see in the data first two data set have color green and rest have default color red from options.enter image description here
below is my basic code for creating line chart for example
const chart = LightweightCharts.createChart(document.getElementById("chartContainer2"), {
width: jQuery('#chartContainer2').width(),
height: jQuery('#chartContainer2').height(),
layout: {
background: {
type: LightweightCharts.ColorType.Solid,
color: '#212529'
},
textColor: '#FFFFFF'
},
crosshair: {
mode: 0
},
grid: {
vertLines: {
visible: false
},
horzLines: {
visible: false
}
}
});
seriesList = [];
seriesList['SMA-10'] = chart.addLineSeries({
customTitle: 'SMA-10',
lastValueVisible: false,
priceLineVisible: false,
color: 'red',
lineStyle: 0,
lineWidth: 1, //in px
crosshairMarkerVisible: false
});
seriesList['SMA-10'].setData([{
time: '2019-04-11',
value: 80.01,
color: 'green'
},
{
time: '2019-04-12',
value: 96.63,
color: 'green'
},
{
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
},
]);
chart.subscribeCrosshairMove((param) => {
if (param.time) {
for (var key in seriesList) {
console.log(seriesList[key].options(), param.seriesPrices.get(seriesList[key]));
}
}
});

Related

Why does my chart plot extra x-axis width?

I am using antd Charts in my project to plot timeseries data. My data has datapoints only till 18:30 pm but antd Line Chart plots extra x-axis width which makes it look like the data is missing.
This is my config:
const config = {
width: window.innerWidth - 100,
data: res,
xField: 'time',
yField: 'value',
seriesField: 'key',
yAxis: {
title: { position: 'center', text: labelText, autoRotate: true },
grid: {
line: {
style: {
stroke: '#ddd',
},
},
},
},
xAxis: {
type: 'time',
mask: 'HH:mm Z',
label: {
formatter: (value) => {
if (timezone === 'utc') {
return moment(value, 'HH:mm ZZ').utc().format('HH:mm Z');
}
return moment(value, 'HH:mm').format('HH:mm Z');
},
},
grid: {
line: {
style: {
stroke: '#ddd',
},
},
},
},
tooltip: {
customItems: (originalItems) => {
return originalItems.sort(function (a, b) {
return b.value - a.value;
});
},
},
};
How do I remove the extra x-axis part between 18:30 and 18:47

How to do a visual map on the X axis in eCharts?

I'm trying to highlight a specific part in a graph by date. The graph is dates in X axis and value in Y axis. I tried doing like this example but I get the error TypeError: Cannot read properties of undefined (reading 'coord')
This is my graph's code:
{
xAxis: {
type: "category",
data: xaxis,
show: true,
axisLabel: {
formatter: function(params:any){
return (new Date(params)).toLocaleString('pt-BR')
}
}
},
yAxis: {
type: "value",
name: 'Eficiência de Consumo (Nm³/ton)',
axisLabel: {
formatter: '{value}'
}
},
dataZoom: [
{
type: 'inside'
}
],
tooltip: {
trigger: "axis",
formatter: function(params:any){
const seriesName = params[0].seriesName
const timeStamp = (new Date(params[0].axisValue)).toLocaleString('pt-BR')
const eficiencia = params[0].value
return `${seriesName} <br/> ${timeStamp}: ${eficiencia} Nm³/ton`
},
axisPointer: {
label: {
backgroundColor: "#6a7985"
}
}
},
legend: {
orient: 'horizontal',
top: 'top'
},
visualMap: {
show: false,
pieces: [
{
min: startAlertTime,
max: endAlertTime,
color: '#FBDB0F'
}
]
},
series: [{
data: yaxis,
name: 'Eficiência de Consumo',
type: "line",
}]}
startAlertTime and endAlertTime are ISO timestamps like so '2022-06-13T10:42:22.772Z'. I'd like to highlight the graph between those two points. This is my graph with no VisualMap:
Graph with no visualmap
This is what I'd like to do based on the timestamps on the X axis:
Desired output
visualMap is going to color the line. If you want to color an area (like in your desired output), you'll have to use series.markArea. Both are used on the example you gave.

custom ticks based on selected range from rangeSelector in Highstock

I am trying to get my Highcharts/Highstock chart to display a custom tick when the rangeSelector is set to All, I have it setup this way, but is throwing me errors when I try to use the interactive portion of the graph
Received below answer from Highstock Change tick interval on range selector change
componentDidMount() {
// Timezone Offset for PST standard is UTC timezone
Highcharts.setOptions({
global: {
timezoneOffset: 8 * 60
},
lang: {
thousandsSep: ','
}
});
Highcharts.stockChart('chart', {
chart: {
backgroundColor:'rgba(255, 255, 255, 0.0)',
height: 400,
zoomType: 'xy'
},
title: {
text: 'Bitcoin Chart',
style: {
color: 'white'
}
},
navigator: {
trigger: "navigator",
triggerOp: "navigator-drag",
rangeSelectorButton: undefined,
handles: {
backgroundColor: 'white',
borderColor: 'black'
}
},
scrollbar: {
enabled: false
},
rangeSelector: {
buttons: [{
type: 'day',
count: 1,
text: '1d'
}, {
type: 'day',
count: 7,
text: '7d'
}, {
type: 'month',
count: 1,
text: '1m'
}, {
type: 'month',
count: 3,
text: '3m'
}, {
type: 'year',
count: 1,
text: '1y'
}, {
type: 'all',
text: 'All'
}],
selected: 6,
// styles for the buttons
buttonTheme: {
fill: 'black',
// stroke: 'none',
'stroke-width': 0,
r: 8,
style: {
color: 'white',
fontWeight: 'bold'
},
states: {
hover: {
},
select: {
fill: 'white',
style: {
color: 'black'
}
}
}
},
// Date Selector box
inputBoxBorderColor: 'black',
inputBoxWidth: 120,
inputBoxHeight: 18,
inputStyle: {
color: 'black',
fontWeight: 'bold'
},
labelStyle: {
color: 'silver',
fontWeight: 'bold'
},
},
series: [{
name: 'Bitcoin Price',
color: 'black',
data: this.props.data.all_price_values,
type: 'area',
threshold: null,
tooltip: {
valuePrefix: '$',
valueSuffix: ' USD',
valueDecimals: 2
}
}],
plotOptions: {
series: {
fillColor: {
linearGradient: [0, 0, 0, 0],
stops: [
[0, '#FF9900'],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
}
}
},
xAxis: {
events: {
setExtremes: function(e) {
if (e.trigger === "rangeSelectorButton" && e.rangeSelectorButton.text === "All") {
var range = e.max - e.min;
// ticks spaced by one day or one hour
var ticksSpacing = range >= 86400 * 1000 ? 86400 : 3600;
this.update({
tickPositioner: function() {
var positions = [],
info = this.tickPositions.info;
for (var x = this.dataMin; x <= this.dataMax; x += ticksSpacing * 1000) { // Seconds * 1000 for ticks
positions.push(x);
};
positions.info = info;
return positions;
}
}, false);
}
}
},
title: {
enabled: true,
text: 'Date (Timezone: PST)',
style: {
color: 'white'
}
},
labels: {
style: {
color: 'white'
}
},
type: 'datetime',
dateTimeLabelFormats: {
day: '%b %e, %Y'
},
tickInterval: 1
},
yAxis: {
floor: 0,
labels: {
formatter: function () {
return '$' + this.axis.defaultLabelFormatter.call(this);
},
format: '{value:,.0f}',
align: 'left',
style: {
color: 'white'
},
},
},
// Mobile Design
responsive: {
rules: [{
condition: {
maxWidth: 600
},
chartOptions: {
chart: {
height: 400
},
subtitle: {
text: null
},
navigator: {
enabled: false
}
}
}]
}
});
}
I am talking about the blue highlighted section, when I move it, it throws an error
I am trying to get the charts to have 2 plots per day on ALL rangeSelector, displaying the first point in the day and the last point in a day. What am I doing wrong?
EDIT 1 : Updated to full config, X Axis is now being disrupted by the original answer, ticks on custom range selector is still in works. Added images to show what's going on
The setExtremes event is raised each time you change the range to be displayed on the graph. It can have several origins:
A button click in the range selector
An handle drag in the navigator
etc..
The actual properties of the event depend on its origin. If you output the event with console.log(e), you'll see that it's not the same for these two origins:
Button click in the range selector
{
trigger: "rangeSelectorButton",
rangeSelectorButton: {
text: "2Hour",
type: "hour",
count: 2,
},
...
}
Handle drag in the navigator
{
trigger: "navigator",
triggerOp: "navigator-drag",
rangeSelectorButton: undefined
}
If you drag the handle in the navigator, there's no rangeSelectorButton attached to the event, because it doesn't make sense: in that case, no button is pressed.
To fix your error, you can add a check on the trigger property:
xAxis: {
events: {
setExtremes: function(e) {
if (e.trigger === "rangeSelectorButton" && e.rangeSelectorButton.text === "All") {
...
}
}
}
How to solved the actual issue
Now, the REAL issue. You want to change the ticks based on what is displayed: either the beginning and end of each day, or hours if not a complete day. You can do that with e.min and e.max, that represent the selected time range.
Like so:
setExtremes: function(e) {
var range = e.max - e.min;
// ticks spaced by one day or one hour
var ticksSpacing = range >= 86400 * 1000 ? 86400 : 3600;
this.update({
tickPositioner: function() {
var positions = [],
info = this.tickPositions.info;
for (var x = this.dataMin; x <= this.dataMax; x += ticksSpacing * 1000) { // Seconds * 1000 for ticks
positions.push(x);
};
positions.info = info;
return positions;
}
}, false);
}

Cannot read property 'lineWidth' of undefined , chat type is columnrange highcharts

i am getting Cannot read property 'lineWidth' of undefined, when using columnrange chart highcharts, this chart i am trying in reactJS
Below is the sample code
import React from 'react';
import Highcharts from 'highcharts';
import ReactHighcharts from 'react-highcharts';
// import ReactHighstock from 'react-highstock';
import HighchartsMore from 'highcharts-more';
import HighchartsExporting from 'highcharts-exporting';
export default class MainChartRange extends React.Component {
componentWillMount(){
this.setState({
type:"column"
})
}
componentDidMount(){
setTimeout(function(e){
HighchartsMore(ReactHighcharts.Highcharts);
HighchartsExporting(ReactHighcharts.Highcharts);
},5000);
}
render() {
HighchartsMore(ReactHighcharts.Highcharts);
HighchartsExporting(ReactHighcharts.Highcharts);
var config = {
chart: {
type: 'columnrange',
inverted: true
},
title: {
text: null
},
subTitle: {
text: null
},
legend: {
enabled: false,
},
plotOptions: {
series: {
pointWidth: 30
}
},
plotOptions: {
series: {
pointWidth: 30
}
},
xAxis: {
categories: ['Woring time'],
title: {
text: null
},
gridLineWidth: 0
},
yAxis: {
type: 'datetime'
},
series: [{
data: [
[1,1483337940000,1483337950000],
[1,1483337970000,1483337990000],
[0,1483338000000,1483338010000],
[0,1483338030000,1483338070000]
]
}]
}
return (
<div className="graph-container">
<ReactHighcharts config={ config } style={{"min-width": "310px", "height": "400px", "margin": "0 auto"}}>
</ReactHighcharts>
</div>
)
}
}
this sample code working for the other chart types but it is giving an error for "columnrange"
highcharts.js:299 -> Uncaught TypeError: Cannot read property 'lineWidth' of undefined
Please help me find some work around for the "columnrange"
I was getting the same error and was able to solve it by explicitly providing 'marker' configuration with labelWidth value in plotOptions object of my chart config.
Following is a sample chart config that I have tested both in my application using react-highcharts as well as using locally running instance of react-highcharts demo:
chart: {
type: 'columnrange',
inverted: true,
height: 300,
width: 400
},
xAxis: {
visible: false
},
yAxis: {
title: {
text: null
},
plotLines: [{
color: '#303030',
width: 2,
value: 67,
zIndex: 5
}, {
color: '#303030',
width: 2,
value: 77.5,
zIndex: 5
}]
},
plotOptions: {
columnrange: {
dataLabels: {
enabled: true,
formatter() {
return `${this.y}°F`;
}
},
marker: {
enabled: false,
lineWidth: 0
},
states: {
hover: {
enabled: false
}
}
}
},
legend: {
enabled: false
},
series: [{
type: 'columnrange',
color: '#4AA013',
data: [
[70, 75]
]
}]
Note: I did not have to make any code changes to highcharts or modify its implementation like previous answer (which did not work for me when tested using react-highcharts).
here is workaround that is got above columnrange to work
in render function add the below code
Highcharts.seriesTypes.line.prototype.pointAttribs = function (point, state) {
var seriesMarkerOptions = this.options.marker,
seriesStateOptions,
pointOptions = point && point.options,
pointMarkerOptions = (pointOptions && pointOptions.marker) || {},
pointStateOptions,
strokeWidth = 1,
color = this.color,
pointColorOption = pointOptions && pointOptions.color,
pointColor = point && point.color,
zoneColor,
fill,
stroke,
zone;
if (point && this.zones.length) {
zone = point.getZone();
if (zone && zone.color) {
zoneColor = zone.color;
}
}
color = pointColorOption || zoneColor || pointColor || color;
fill = pointMarkerOptions.fillColor || point.color || color ;
stroke = pointMarkerOptions.lineColor || point.color || color;
/*// Handle hover and select states
if (state) {
seriesStateOptions = seriesMarkerOptions.states[state];
pointStateOptions = (pointMarkerOptions.states && pointMarkerOptions.states[state]) || {};
strokeWidth = pointStateOptions.lineWidth || seriesStateOptions.lineWidth || strokeWidth + seriesStateOptions.lineWidthPlus;
fill = pointStateOptions.fillColor || seriesStateOptions.fillColor || fill;
stroke = pointStateOptions.lineColor || seriesStateOptions.lineColor || stroke;
}*/
return {
'stroke': stroke,
'stroke-width': strokeWidth,
'fill': fill
};
};
HighchartsMore(ReactHighcharts.Highcharts);
HighchartsExporting(ReactHighcharts.Highcharts);

Flot Chart - Graphic data as an object array with multiple attributes

I would like to have an array object instead of the following json format;
[1409558400000, 7.45],[1409562000000, 5.71], [1409565600000, 7.50],
... .;
My purpose is to show all data on the graph based on their hh:mm parameter (which is done in the link already), and I ended up such json array;
[10, 7.45],[09, 5.71], [11, 7.50], ...
But I also would like to keep their timestamp in order to have more information about each data point so that I can provide the timestamp when user clicks on a point.
I simply need to have something like this [10, 7.45,1409562000000] ; hour value, age, and timestamp respectively.
How can I have such data array for flot chart ?
var d = [
[1409558400000, 7.45],
[1409562000000, 5.71],
[1409565600000, 7.50],
[1409569200000, 7.63],
[1409576400000, 3.14],
[1409644800000, 7.45],
[1409648400000, 5.71],
[1409652000000, 7.50],
[1409655600000, 7.63],
[1409662800000, 3.14],
[1409731200000, 7.45],
[1409734800000, 5.71],
[1409738400000, 7.50],
[1409742000000, 7.63],
[1409749200000, 3.14]
];
$.each(d, function (index, datapoint) {
datapoint[0] = (new Date(datapoint[0])).getHours();
});
$.plot("#placeholder", [d], {
series: {
lines: {
show: true
},
points: {
show: true
}
},
grid: {
hoverable: true,
clickable: true,
markings: [{
yaxis: {
from: 0,
to: 4
},
color: "#F2CDEA"
}, {
yaxis: {
from: 4,
to: 7
},
color: "#D7EEE1"
}, {
yaxis: {
from: 7,
to: 12
},
color: "#F2CDEA"
}]
},
xaxis: {
},
yaxis: {
min: 0,
max: 12
}
});
$("#placeholder").bind("plotclick", function(event, pos, item) {
var x = item.datapoint[0].toFixed(2),
y = item.datapoint[1].toFixed(2);
if (item) {
//window.location="pagex.html";
alert("x: " + x);
//plot.highlight(item.series, item.datapoint);
}
});
<!-- basic time series flot chart -->
<h>Create a custom green range</h>
<div style="height: 400px; width: 600px;" id="placeholder"></div>
http://jsfiddle.net/shamaleyte/wzLaqzf5/1/
Basically I adapt the answer given in the following link for my scenario.
Link for Referenced answer
Link : displaying custom tooltip when hovering over a point in flot
My Code:
var data = [
[1409558400000, 7.45],
[1409562000033, 5.71],
];
$.each(data, function (index, datapoint) {
datapoint[2] = datapoint[0]; // copy the timestamp and paste it as the 3rd object
datapoint[0] = (new Date(datapoint[0])).getHours(); // to put hours on y axis
});
$.plot("#placeholder", [d2], {
series: {
lines: {
show: true
},
points: {
show: true
}
},
grid: {
hoverable: true,
clickable: true,
markings: [{
yaxis: {
from: 0,
to: 4
},
color: "#F2CDEA"
}, {
yaxis: {
from: 4,
to: 7
},
color: "#D7EEE1"
}, {
yaxis: {
from: 7,
to: 12
},
color: "#F2CDEA"
}]
},
xaxis: {
},
yaxis: {
min: 0,
max: 12
}
});
$("#placeholder").bind("plotclick", function(event, pos, item) {
var x = item.datapoint[0].toFixed(2),
y = item.datapoint[1].toFixed(2);
var tooltip = item.series.data[item.dataIndex][2];
if (item) {
//window.location="pagex.html";
alert("x: " + tooltip);
//plot.highlight(item.series, item.datapoint);
}
});
My Fiddle : http://jsfiddle.net/shamaleyte/wzLaqzf5/2/

Resources