-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Setting the crosshair programmatically #438
Comments
@gkaindl That would be great! Also is it possible to share codes of the events that you made in the gif (synthesizing events) ? |
Related to #376. |
It looks like we need to add something like CrossHair API (or kind of). Let's wait more feedback. |
@lejyoner-ds My current way of doing it with synthetic events is really more of a hack and works possibly only for my use-case, since I also synchronize the visible range between charts, but I've written some details together in a gist, so that we're not cluttering up this issue thread. I hope you find it useful! @timocov So regarding how the crosshair API could work, it would be ideal for my use-case(s) to have the following API additions to chart-api:
Optionally, these three methods could be added for some use-cases, e.g. those where people want to implement their own handling of the crosshair (for all three of these, I’m unsure about the best naming):
Of course, one could think of allowing multiple crosshairs within the same chart, so that there’s the library-controlled one, and one or more user-controlled one, but I personally don’t think that’s needed. So that would be my idea – Maybe the others who would be interested in a crosshair API have some feedback/requirements, too! |
It would be useful in many cases to support moving the cross-hair smoothly across candles using interpolation (or extrapolation?) when two charts have different time frames. For example: if one chart uses hourly time scale (hourly candles) and another chart uses daily time scale (daily candles), then ideally syncing crosshairs between these two charts would allow showing or moving the crosshairs smoothly in both charts (if not snapped to center of the candle) as the user moves moves the mouse in one chart. If user moves mouse in the hourly chart from left to right, it would also move the crosshair in the daily chart as well by the corresponding time scale interval in the daily chart. At the moment, I do not have access to any example gif or animation of what I am describing, but hope the meaning is clear enough! |
Also we need to worry about #50 (crosshair might be on several panes, has different prices/coordinates and so on).
Yeah, we have the same feature on charting library/trading terminal/tradingview's chart itself. |
Oh, good point! I wasn't aware that a public pane API is in the works, I've only seen the concept of a pane used internally so far – Is there a branch that already has a work-in-progress public pane API to look at? Maybe it would be sufficient then to put the proposed methods on the pane-api, rather than the chart-api then (I suppose the subscriptions for clicks and crosshair updates would also move there).
I think it's also a question of how the "lightweight" in lightweight-charts is interpreted: For use-cases like interpolating the crosshair position from a shorter-timeframe chart/pane over a longer-timeframe chart/pane, one valid approach would be to only provide the most basic primitives and let users implement the actual interpolation behavior themselves, or to provide more "convenience methods" and treat the "lightweight" aspect as "If a representative amount of users need/want the behavior, it gets added to the library natively". So as an example, if there was only the Even if there are more "powerful" methods available, having the primitives around is still great, because people might want to customize certain aspects to fit their particular use-case, which would either require these methods to be rather complex and customizable (like, say, for the interpolation use-case, somebody needed a different interpolation method than linear). Anyway, since there are already quite a few issues related to crosshair features, we can check them to see if there are use-cases that can't be built using the proposed primitives, and maybe extend/amend them accordingly. PS: I'm not arguing that there shouldn't be more advanced/powerful methods available that implement entire behaviors, I'm rather just describing my viewpoint/feedback. I'm always a bit afraid to come across as demanding/opinionated in threads like this. |
Not so far, but we need to keep it in mind to avoid huge breaking changes or even API conflicts. Also, some converters (like from time/price to coordinate and vice versa) should be done in price/time scale API (actually some of them are already done there - see #435 for instance, but it looks like for price scale we have converters in series but I don't remember exactly reason for that). Anyway, we'll keep in mind this request, if anybody has additional/specific request for that, leave a comment. If you need it as it - just put your 👍 at the topic message. |
any update? possible to use crosshair programatically? |
We have a specific use case in mobile devices where we need to close the crosshair when user released their touch from the screen. Apparently some users dislike the the way crosshair sticks and need another tab to close it. Therefore able to close the crosshair manually/programmatically will come in handy as we can just bind it with onTouchEnd event. Would be even better if we could introduce another mode (stick/non-stick) for crosshair that could achieve to above use case. |
Here is my hack/solution/workaround to sync the crosshair between two charts that involve modification of the source code. setCrossHairXY(x: number,y: number,visible: boolean): void; here lightweight-charts/src/api/ichart-api.ts Line 114 in faa3295 And this public setCrossHairXY(x: number,y: number,visible: boolean): void{
this._chartWidget.paneWidgets()[0].setCrossHair(x,y,visible);
} here lightweight-charts/src/api/chart-api.ts Line 176 in faa3295 And this public setCrossHair(xx: number,yy: number,visible: boolean): void {
if (!this._state) {
return;
}
if (visible){
const x = xx as Coordinate;
const y = yy as Coordinate;
if (!mobileTouch) {
this._setCrosshairPositionNoFire(x, y);
}
}else{
this._state.model().setHoveredSource(null);
if (!isMobile) {
this._clearCrosshairPosition();
}
}
}
private _setCrosshairPositionNoFire(x: Coordinate, y: Coordinate): void {
this._model().setAndSaveCurrentPositionFire(this._correctXCoord(x), this._correctYCoord(y), false, ensureNotNull(this._state));
} here lightweight-charts/src/gui/pane-widget.ts Line 693 in faa3295 And this public setAndSaveCurrentPositionFire(x: Coordinate, y: Coordinate, fire: boolean, pane: Pane): void {
this._crosshair.saveOriginCoord(x, y);
let price = NaN;
let index = this._timeScale.coordinateToIndex(x);
const visibleBars = this._timeScale.visibleStrictRange();
if (visibleBars !== null) {
index = Math.min(Math.max(visibleBars.left(), index), visibleBars.right()) as TimePointIndex;
}
const priceScale = pane.defaultPriceScale();
const firstValue = priceScale.firstValue();
if (firstValue !== null) {
price = priceScale.coordinateToPrice(y, firstValue);
}
price = this._magnet.align(price, index, pane);
this._crosshair.setPosition(index, price, pane);
this._cursorUpdate();
if (fire) {
this._crosshairMoved.fire(this._crosshair.appliedIndex(), { x, y });
}
} here lightweight-charts/src/model/chart-model.ts Line 446 in faa3295 And now you can do something like this . chart.subscribeCrosshairMove(crosssyncHandler);
function crosssyncHandler(e) {
if (e.time !== undefined) {
var xx = chart2.timeScale().timeToCoordinate(e.time);
chart2.setCrossHairXY(xx,50,true);
} else if (e.point !== undefined){
chart2.setCrossHairXY(e.point.x,10,false);
}
}
chart2.subscribeCrosshairMove(crossSyncHandler2);
function crossSyncHandler2(e) {
if (e.time !== undefined) {
var xx = chart.timeScale().timeToCoordinate(e.time);
chart.setCrossHairXY(xx,200,true);
} else if (e.point !== undefined){
chart.setCrossHairXY(e.point.x,100,false);
}
} Here is a jsfiddle that shows the result Almost all the code listed above is just a refactored version of already existing code. |
@triorr Thank you very much for that suggestion and the code. You miss to post your custom function I added a public clearCrossHair(): void {
this._chartWidget.paneWidgets()[0].clearCrossHair();
} in And reister in as well under clearCrossHair(): void; in When using your code example it can be extend by: chart.subscribeCrosshairMove(crosssyncHandler);
let mouseOverChart = false;
function crosssyncHandler(e) {
if (e.time !== undefined) {
var xx = chart2.timeScale().timeToCoordinate(e.time);
chart2.setCrossHairXY(xx,50,true);
} else if (e.point !== undefined){
chart2.setCrossHairXY(e.point.x,10,false);
} else if(mouseOverChart) {
mouseOverChart = false;
chart.clearCrossHair();
}
}
chart2.subscribeCrosshairMove(crossSyncHandler2);
let mouseOverChart2 = false;
function crossSyncHandler2(e) {
if (e.time !== undefined) {
var xx = chart.timeScale().timeToCoordinate(e.time);
chart.setCrossHairXY(xx,200,true);
} else if (e.point !== undefined){
chart.setCrossHairXY(e.point.x,100,false);
} else if(mouseOverChart2) {
mouseOverChart2 = false;
chart.clearCrossHair();
}
} |
Thanks @florian-kittel, My solution is far from complete. |
I have a problem where I have 4 charts using same data, but deriving multiple timeframes for example: daily, weekly, monthly, and yearly. I want to sync the crosshair horizontal line to the price scale axis. @triorr what is the best way to do this? I was able to get the charts syncing on the timescale like you showed above. Thanks SOLVED
|
It's working well, that should be added into the library. |
Hi Everyone, I get a question & sorry if it's obvious, but what's the branch? where I can support for testing. |
Hi, my changes based on v3.4.0. I the later versions this._cursorUpdate() was renamed to this.cursorUpdate(). |
Patch source: tradingview#438 (comment)
Using trior's patch to sync crosshairs work in desktop-browsers as shown in the video. But it does not work inside a mobile-based browser. Can this limitation be bypassed? @triorr @florian-kittel screen-20220910-015331.mp4 |
I see, I went thru all the versions from the releases and none of them seem to be working for me. |
@0x0tyy If I had to guess. I think it's something to do with |
yeah that was the culprit. It is working perfectly in mobile now. |
how come this file is removed in 3.8.0? I forked the repo: made the changes then tried to npm install from my public repo on my account It failed saying git build tools. Any tips? Trying to import into vue 3 project
|
You can tested in https://topacio.trade
…On Mon, Nov 21, 2022, 12:26 PM Askar ***@***.***> wrote:
Thanks I was can tested It's nice, it would be add in some feature soon? [image:
image]
<https://user-images.githubusercontent.com/2575745/140875019-9f58cc17-4580-4182-935a-652189202f88.png>
Hi, I was wondering how you were able to get these technical analysis on
these charts?
—
Reply to this email directly, view it on GitHub
<#438 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AATU3AMNTHSNXTWL5SBSPZLWJOPEFANCNFSM4NCQWYKQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
@florian-kittel could you please share your @triorr and @0x0tyy - I'm looking to implement this solution/hackaround on lightweight-charts 3.8. Could you share what you used to set these variables: |
Hi all, I was able to get @triorr's code to work with some slight modifications. See below:
here: lightweight-charts/src/api/ichart-api.ts Line 212 in e263d72 (it is line 209 in version 3.8.0) this:
here: lightweight-charts/src/api/chart-api.ts Line 147 in e263d72 (line 193 in version 3.8.0) this:
here: lightweight-charts/src/gui/pane-widget.ts Line 659 in e263d72 (line 644 in 3.8.0) and finally this:
here: lightweight-charts/src/model/chart-model.ts Line 659 in e263d72 (line 658 in 3.8.0) With the following implementation:
You can see i made the trivial change renaming Also, I removed Thank you everyone for your help. Hopefully this can assist anyone else looking for this functionality. |
Thanks so much for posting your changes, I implemented them and it achieved exactly what I needed! You saved me so much time figuring the changes out myself! Hopefully this api (or something similar) gets merged into the official lib |
Thank you for the method you provided. I am using version 4.0, and I cannot use your code of version 3.8. I don’t understand the internal principle of lightweight, and I don’t know how to modify it. Is there a corresponding repair method in version 4.0? |
Below is how I'm using this in the js file. It assumes an object
|
Version 4.1 includes a method for setting the crosshair position. https://tradingview.github.io/lightweight-charts/tutorials/how_to/set-crosshair-position |
@SlicedSilver - jumping off this as to not create extra noise and extra issues. Can setCrosshairPosition be used to persist a crosshair even after user unhovers/ineracts with chart? I need crosshair to persist for a number of seconds. |
Yes, this would be possible. It allows you to set the crosshair location independently from any touch or mouse event. |
@SlicedSilver I've tried syncing two charts with 'Set crosshair position,' but it seems that it's not synchronizing properly. Screen.Recording.2023-12-14.at.10.32.03.AM.mp4 |
It appears to be syncing correctly. The date and time within the timescale labels (for the crosshair) are showing very similar times. It may not be identical times if the two series / charts don't have the exact same timestamps present within their datasets. I assume that you many concern is that the crosshair line doesn't appear to be continuous across both charts. I would suggest that you try match the visible time range in both charts (using If this doesn't help or answer your query then could you describe the issue in a bit more detail, and if possible provide a code sample? |
@SlicedSilver - I have multiple charts and each chart has multi lines From this, https://tradingview.github.io/lightweight-charts/tutorials/how_to/set-crosshair-position I can able to sync only 2 charts. Actual: I can able to sync two charts as per doc. But not able to sync tooltip. And not able to zoom once its sync Expected: I wants to sync cross hair and tooltip more than 2 charts dynamically. Expected like below |
The example only shows 2 charts but the concept can be extended to any number of charts. Also it is possible to use zoom and scrolling when using this example. Did you add this code? chart1.timeScale().subscribeVisibleLogicalRangeChange(timeRange => {
chart2.timeScale().setVisibleLogicalRange(timeRange);
});
chart2.timeScale().subscribeVisibleLogicalRangeChange(timeRange => {
chart1.timeScale().setVisibleLogicalRange(timeRange);
}); For all of this to work nicely it is recommended that both charts have the same number of data points (and the same timestamps). |
yes, I have used same concept, and able to sync it. but after syncing zoom is not working (scroll works fine). But my concern here how to handle it dynamically? if tmrw Have to add 4th chart means then we want to manually add it and sync it here. instead if we based on dataset have to create multi charts like that reusuable component am trying. import { ASIA_KOLKATA_UTC, DATE_FORMAT_1, NUMERICAL_CONVERSION } from "utils/constants"; interface MultichartsProps { const MultiCharts = (props: MultichartsProps) => {
}; export default MultiCharts; |
Could you please create an example on an online code editor like JSfiddle / Codepen / CodeSandbox / ...? |
@SlicedSilver - Any update on this? as suggested have created a codesandbox, plz provide a solution. |
Here is an example with multiple charts which are synced together. You can adjust the number of charts in the code. Since your code is using React, could you check that you are only creating the expected number of charts, and that you are removing charts when they are no longer needed with the |
@SlicedSilver - I would like to thank you for your support. I have Observed in the above example, each chart have only one series. But our case is multiple charts and each charts has multple series (may the series has any type(line, area, grouped bar charts)). Please provide example for tooltip functionality for multi charts multi series data. As per the example I have tried to create multi series but am not able to get expected solution. #1589 this ticket also I have raised for the inclusion of grouped bar charts in multi series charts. For this case only. Unfortunately unable to create grouped Bar charts which has positive and negative bars. We have used TradingView and Light weight charts in our projects, we were already integrated couple of screens. But we got stucked multi charts with multi series where the series has grouped Bar charts. It is showstopper for a long time. So, requesting you to please provide all solutions at one place if posible. Thanks for an advance. |
Having multiple series on the chart shouldn't make any difference. I've updated the example to have a second series on each chart.
We have some tutorials on adding tooltips. Besides what is shown in the documentation, we wouldn't create an custom example for just a single request.
If the plugin doesn't support negative bars then I would suggest that you take the source code of the plugin as a starting point and develop an updated plugin. The example plugin is only an example instead of a full-featured official plugin.
We don't build example implementations as that would be consultation work and we don't offer paid services. For this open source project, we are happy to assist with bug reports and general queries, and consider feature requests but not to develop full solutions or perform code review on large files (beyond minimal bug reproductions). |
Hello @dc-thanh Did you managed this out? Have a similar issue with multiple charts with different timestamps on each, which leads to different |
Describe the solution you'd like
Setting the crosshair programmatically would be useful in some circumstances. Right now, the crosshair can only be controlled via mouse or touch interactions, but not programmatically, I think (excluding the solution of synthesizing events).
Other user interactions, such as scrolling/panning and changing the scales (once #416 is merged), are already enabled to be controlled programmatically, but control of the crosshair is missing to fully manage the erverything in the UI via client code.
Additional context
Ideally, methods to move the crosshair to a given (canvas) coordinate set or to hide it would be good. If #435 gets implemented too, moving it to a specific time point would also be doable then.
Some areas where this might be useful:
This is already doable to certain extent by synthesizing events (see the gif below), but it doesn't work on touch devices (due to the way events are handled in this case), and deriving the coordinates reliably (if the charts involved aren't sized the same) requires a lot of code, using your dataset, the visible time- and logical ranges, and so on. A proper API would make this way easier.
The text was updated successfully, but these errors were encountered: