ohlcv_chart 2.0.0
ohlcv_chart: ^2.0.0 copied to clipboard
Candlestick and market-depth charts for Flutter, with MA, BOLL and SAR overlays, MACD, KDJ, RSI, WR and CCI sub-charts, signal markers and interactive drawing tools.
2.0.0 #
Drawing tools #
- Placing a line now follows the flow of the big charting apps. Horizontal and vertical lines land with a single tap; a trend line takes one tap per end, with the far end rubber-banding along with the pointer in between. Press and drag still draws a line in one gesture, and a press that only wandered a pixel no longer throws the anchor away — the next tap finishes that line.
- With a mouse, an armed horizontal or vertical tool previews where its line would land as the pointer moves.
- Escape cancels a line that is half-placed, as does switching to another tool.
- The line editor no longer opens over a line that is still being placed.
- New
KChartWidget.magnetMode, which snaps points being placed to the nearest open, high, low or close, within the newDrawingStyle.magnetSnapDistance. - Six new things to draw, on the same tap-tap placement:
DrawingTool.rayand.extendedLinefor a line that carries on past one or both of its anchors,.arrowfor one with an arrowhead,.horizontalRayfor a level that only applies from its own candle rightwards,.rectanglefor a price range box, and.fibRetracementfor a labelled, banded retracement of a swing. - New
LineExtensionandTrendLine.extendand.arrowcarry the three line variants, so trend lines saved by an earlier version still load. NewHorizontalLine.startTimeturns a level into a ray. - New
RectangleDrawingandFibRetracement, drawn fromKChartWidget's newrectanglesandfibRetracementsand reported throughonAddRectangle,onRemoveRectangle,onAddFibRetracementandonRemoveFibRetracement. - New
TwoPointDrawingbase, shared by every drawing with two anchors. Its anchors can be dragged one at a time or the shape moved as a whole, whichever the tap landed on. - New
DrawingStyle.arrowHeadLength,.rectangleFillOpacity,.fibLevelsand.fibFillOpacity. - The editor's label field now also names a rectangle, and a retracement's level labels are stacked so they no longer print on top of each other when the levels bunch up.
- Nine more things to draw:
DrawingTool.measurefor a ruler that reads out the move in price, in percent, in candles and in time;.channelfor a parallel channel;.positionfor a planned trade with its risk-to-reward;.ellipseand.triangle;.textfor a note pinned to a point; and.brushfor a freehand stroke. - New
MeasureDrawing,ParallelChannel,PositionDrawing,EllipseDrawing,TriangleDrawing,TextAnnotationandFreehandDrawing, plus theThreePointDrawingbase the three-point shapes share. - New
LabelledDrawingandFilledDrawing, which is how the editor's label field and its new fill slider reach every drawing that has one. - New
DrawingStyle.shapeFillOpacity,.measureFillOpacity,.channelFillOpacityand.positionFillOpacityfor the new shapes' washes, plus.showFillControland.showAlertControlfor the two new buttons.
Persisting what is drawn #
- Every drawing now serialises.
ChartLine.toJsonand the top-leveldrawingFromJsonare a matched pair, so a layout survives a restart:jsonEncode(drawings.toJson())on the way out,ChartDrawings.fromJsonon the way back. A drawing of a kind this version does not know is skipped rather than throwing, so a layout written by a newer release still opens. - New
ChartDrawings: an ordered set of drawings with typed views —horizontalLines,trendLines,positionsand the rest — andcopyDrawing, which deep-copies one through its own JSON. - New
KChartWidget.drawings, which takes drawings of any kind, andonAddDrawing/onRemoveDrawing, which report every kind. The per-kind lists and callbacks are unchanged.
Undo and redo #
- New
ChartDrawingController, handed toKChartWidget.drawingController. It owns the drawings: everything the user places, restyles, drags or deletes goes through it, which is what makesundoandredopossible. An edit is a step, so restyling a line and undoing gets the old style back. - ⌘Z, ⇧⌘Z (Ctrl and Ctrl+Y elsewhere) and Delete now work on the chart itself,
and Escape still abandons a drawing being placed.
enableKeyboardShortcutsturns the lot off. - The controller also holds the selection, so a panel outside the chart and the chart itself always agree on what is selected.
- New
KChartWidget.selectAfterDrawing, so the editor need not open over each drawing as it lands — which is what makes drawing several in a row bearable.
The drawing manager #
- New
DrawingManager, a widget over aChartDrawingController: every drawing by name, with show/hide, lock, delete, undo, redo and clear. Tapping a row selects that drawing on the chart. - New
ChartLine.hidden, which leaves a drawing in the layout but off the chart. DrawingTranslationsnow covers the manager and the names of all seventeen kinds, throughnameOf.
Alerts #
- New
HorizontalLine.alertandKChartWidget.onAlertCrossed: a level with an alert reports when the newest candle closes on the other side of it, once per crossing. The editor's bell button arms one.
Chart types #
- New
KChartWidget.chartType:ChartType.candles,.barsfor OHLC bars,.line,.areaand.baseline— the close line washed towardsbaselinePrice, or towards the oldest close in view.isLine: truestill means an area chart. - New
CandleTransforms.heikinAshiand.renko, which rewrite the candles rather than the way they are drawn, plus.atrBrickSizeto size a Renko brick from the market's own range.
Price axis #
- New
KChartWidget.priceAxisScale:PriceAxisScale.logarithmicgives equal ratios equal space, which is what makes a long history readable, and.percentagereads the axis out as the move away from the oldest candle in view. A window whose low is zero or negative falls back to a linear axis rather than drawing nothing. ChartPainter.calculatePriceand the crosshair's price now come from the renderer's own inverse mapping, so a price and its pixel agree exactly whatever the axis is spaced by. That also fixes the crosshair reading a price a few pixels off on a linear axis.
Reading the chart on a desktop #
- The crosshair now follows a resting mouse, without waiting for a press — new
KChartWidget.crosshairOnHover, which touch devices never see. - New
KChartWidget.showOhlcLegend, which reads the candle out above the chart — date, open, high, low, close, the move over it and its volume — on a legend row of its own, worded byChartTranslations. - Fixed a repaint loop: the info dialog was told about the candle under the crosshair on every paint, which rebuilt the dialog, which painted again. It is only told when something has actually changed.
- Fixed the info dialog throwing when the crosshair sat on the oldest candle, which has nothing before it to compare against.
Driving the chart from your own code #
- New
KChartController:zoomIn,zoomOut,zoomTo,scrollToNow,isAtRightEdgeandcapture, which hands back the chart as PNG bytes without the editor or any other control floating over it. - The chart now shows a button back to the live candle whenever it is scrolled
away from one —
showScrollToNowButton, with its tooltip inChartTranslations.jumpToNow.
Panes, sessions and time zones #
- An indicator pane can be dragged taller or shorter by its lower edge
(
resizablePanes) and up or down the stack by its legend row (reorderablePanesandonReorderPane, which reports the move and leaves it to the host, since the indicators own their order). NewChartStyle.paneResizeTolerance,.paneGrabHeight,.minPaneHeightand.maxPaneHeight. - New
ChartStyle.showSessionDividersandChartColors.sessionDividerColor, which mark the first candle of each day. - New
KChartWidget.timeZoneOffset, added to every candle's time before it is shown — on the axis, in the crosshair, in the legend and when working out where a day starts. It never touches the data. - New
ChartStyle.copyWith. - Fixed raw pointer events never reaching the chart's own
Listener, which sat outside aMouseRegionthat swallowed them. That is what a press has to be read from to tell a pane's edge from its body, since a drag is only recognised once it has moved on.
The demo #
- The example now drives all of it: every tool and chart type, the three price axes, Heikin-Ashi and Renko, the drawing manager beside the chart, undo and redo, saving the layout as JSON and restoring it, capturing the chart as a PNG, resizable and reorderable panes, day dividers and a display time zone.
- Its control panel lays every option list out as wrapping chips, so the panel no longer overflows at its narrowest.
Tests #
- Golden tests over the painters: the five chart types, Heikin-Ashi and Renko, a logarithmic axis, the legend and day dividers, and every drawing at once.
- New suites for serialisation, the drawing controller and its shortcuts, the drawing manager, the new shapes and alerts, the price axes, the chart types and transforms, and the chart surface — the controller, panes, sessions and hover.
1.1.0 #
Drawing tools #
- Reworked the line editor. Selecting a drawn line now opens a floating,
draggable toolbar with a colour swatch grid and opacity slider, thickness
presets plus a fine slider, solid/dashed/dotted stroke previews, an inline
label field, and lock, delete and done buttons. It replaces the two bare
SimpleDialogpickers, and its panels are hosted in the app overlay, so their sliders and text field no longer compete with the chart's pan and zoom. - New
DrawingStyle, passed asKChartWidget.drawingStyle: the colours, thicknesses and stroke styles on offer, which controls appear, the toolbar's colours, radius, padding, axis, icon size and start position, the drawn lines' handle and label geometry, dash lengths, and how close to a line a tap has to land to select it. - New
DrawingTranslations, reachable asChartTranslations.drawing, covering every label and tooltip in the editor. LineStyle-solid,dashedordotted- onChartLine, alongside aChartLine.opacityaccessor backed by the colour's alpha channel.isDashedstill reads and writes as before.- Editing a line now reports it: restyling, renaming or dragging one fires the
matching
onAdd*callback, which previously only fired when a line was first placed, so those changes could not be persisted. - A trend line can be selected by its stroke rather than only its two ends, and dragging it there moves the whole line.
DepthChartStyleandDepthChartColorsare exported, so the depth chart can actually be themed.
Fixed:
- The long-press readout no longer overflows. Its rows shrink and ellipsise, and
the card sizes itself to its content between the new
infoDialogWidthandinfoDialogMaxWidth, capped by the chart's own width. Long translations and intraday timestamps used to run past its fixed 130 pixels. - Drawn lines keep the thickness they were given at every zoom level, and their drag handles stay circular. Both were painted inside the chart's horizontal scale, which stretched them.
- A vertical line's label is painted once, and only when
showLabelis set. It was drawn twice, and the first pass ignored the flag. - A vertical line is no longer overlaid by a hard-coded 1-pixel solid line that ignored its colour, thickness and stroke style.
- Line labels are padded evenly; the right side had twice the padding of the left.
Indicators #
Indicators are now configured instances rather than enum flags, so the same kind can be on the chart several times with different settings and colours.
- Breaking:
mainStateLi,secondaryStateLiandmaDayListare replaced by a singleindicatorslist ofIndicatorinstances —MaIndicator(period: 20),AtrIndicator(period: 8),MacdIndicator(fast: 5, slow: 34, signal: 5)and so on.MainStateandSecondaryStateare gone. Overlays draw over the candles; the rest each take a pane, stacked in the order given. - Several of one kind is the point:
ATR(8),ATR(14)andATR(20)are three panes, and three moving averages take three theme colours without being told. - Every instance takes a
color— orcolors, one per line, forBOLL,MACD,KDJandDMI— which overrides theChartColorspalette for that instance alone. - An indicator is identified by its type and settings, colours deliberately
excluded, so
indicators.upsert(...)restyles the matching one already on the chart instead of stacking a duplicate.toggleandremoveIndicatorround out the list editing, and the chart itself keeps the last of any equal pair it is given. - New
indicatorCatalogdescribes every indicator — its settings with their ranges and defaults, and its colour slots — so an "add indicator" dialog can be built from data.IndicatorType.createbuilds an instance from a values map,valuesOfreads an existing one back into the form,lineLabelsanddefaultColorslabel and seed the colour pickers, andindicatorTypeOffinds the entry describing an indicator. The example app's indicator sheet is built entirely from it. - Indicator maths moved into pure series functions that take candles and return
values, shared by the indicators and by
DataUtil, which still fills in the fields on eachKLineEntityfor the long-press readout. - Custom indicators: subclass
Indicator, give it alabel,lines,settingsand acompute, and the chart draws, scales, legends and labels it like any built-in one.
Twelve new indicators, all of them configurable and repeatable like the rest:
- Overlays:
SupertrendIndicator(an ATR stop that changes colour when it flips),KeltnerIndicator,DonchianIndicatorandIchimokuIndicator, whose cloud is shaded between its two spans and whose spans and lagging line carry the usual displacement. - Swing readers, all driven by one
depth— the percentage move that ends a swing:ZigZagIndicatordraws the legs,FibonacciIndicatorretraces the last one so the levels follow the market instead of being placed by hand, andElliottWaveIndicatorlabels the pivots1-5thenA-C. The wave count is a reading of the swings rather than a rules-checked Elliott count. - Panes:
StochRsiIndicator(with 20/80 guides),RocIndicator,TrixIndicator,VolumeMaIndicatorandAwesomeIndicator, whose bars take the up and down colours by whether momentum grew. - Three new line shapes behind them, available to any indicator:
IndicatorShape.pivotLinestrokes straight across the candles that have no value,IndicatorShape.markersdraws a dot with the indicator's own text beside it throughmarkerLabel, andfillsshades the area between two lines withfillColordeciding its colour from which line is on top. - The swing readers size their threshold from the candles by default, rather
than a fixed percentage:
depth: 0— now the default — aims for roughly eight legs across the data, so a zigzag reads the same on a quiet intraday chart as on a volatile daily one. A fixed 5% drew nothing at all on a market that never moved 5%. Pass any positivedepthto set it yourself; the label saysautowhen it is worked out. - New
ChartColorsentries for each of them:keltnerColor,donchianColor,conversionColor,baseColor,spanAColor,spanBColor,laggingColor,stochRsiColor,rocColor,trixColor,volumeMaColor,awesomeColor,zigzagColor,fibonacciColorandwaveColor.
Depth chart #
The depth chart draws the same book four ways, and can say what is resting on each rung rather than only the running total.
- New
mode, aDepthChartMode:cumulative— the curves it has always drawn and still the default —histogram, one bar per level sized by what rests on that rung alone,combinedfor both at once, andladder, a numeric table of price, size and running total with a bar behind each row. - New
DepthLadder, the widget behind that last mode, usable on its own to put the numbers beside a chart rather than instead of it.levelssets how many rungs a side it lists andbarsShowTotalwhether its bars follow the running total or each rung's own size. - New
scale, aDepthScale:linear,logfor a book whose far side dwarfs the near one, orpercentto label the axis as a share of the deepest total. - New
zoom, which keeps only the levels within that fraction of the mid price. A zoom so tight that nothing would be left falls back to the whole book rather than to an empty chart. - New
DepthBookandDepthLevel: each rung's own size recovered from the cumulative curves by differencing, so nothing extra has to be passed in.DepthBook.fromCurvesis public for callers who want the levels themselves. - The long-press readout names the size resting on the rung under the finger as well as the running total out to it, and its dot follows whatever the mode draws.
- New
DepthChartTranslationsentries —size,total,bids,asksandspread— andDepthChartStyle.barWidthFactor,ladderRowHeightandladderFontSize.
Rendering #
Six new indicators, a reworked look, and a demo that exercises all of it.
- New main-chart overlays:
EMA— exponential moving averages over the same periods asMA, sharing its palette — andVWAP, accumulated over the candles you pass. - New sub-charts:
ATR(14),OBV,MFI(14, with 20/80 guides) andDMI(+DI, −DI and ADX, with the 20 guide). Each has its ownChartColorsentry, andDataUtil.calculatefills them in alongside the existing indicators;calcEMA,calcVWAP,calcATR,calcOBV,calcMFIandcalcDMIare public if you want a subset. - The main chart's price range now stretches to hold
EMAandVWAP, the way it already did forBOLLandSAR, so a lagging average is never clipped. mBaseHeightis optional. Left unset, the candle area takes whatever height the panes below it do not need, so the chart fills its box instead of painting past it; in a box with no height to divide it falls back to 360. Pane heights are available asBaseDimension.volumeHeight,secondaryPaneHeightandlegendRowHeight.- Rendering polish, all of it configurable: pane separators in their own colour, price-axis labels padded and set on a pill so they stay readable over candles, indicator legends on rounded translucent pills, optional hollow rising candles, a dashed "now price" line in the up/down colours with its tag on the side the axis labels are not using, high/low markers drawn with a leader line, a crosshair with configurable dash lengths, and a watermark placed by alignment and tinted rather than pinned to a fixed offset.
- New
ChartStylefields:hollowUpCandles,gridStrokeWidth,separatorWidth,axisLabelBackground,axisLabelPadding,labelCornerRadius,legendPadding,legendSpacing,crossDashLength,crossDashGap,nowPriceDashed,watermarkAlignment,watermarkScale. NewChartColorsfields:separatorColor,axisLabelBgColor,legendBgColor,watermarkColor, plus the new indicators' colours. DepthEntity.bidsandDepthEntity.asksbuild cumulative depth curves from raw order-book rungs, sorting by price and accumulating outwards from the mid.VerticalTextAlignmentis exported, soverticalTextAlignmentcan be named.- The example is now a full tour: every overlay and pane, drawing tools with two
editor styles, live ticks that roll the candle over,
onLoadMorepagination, signal markers, both readout styles plus a custom builder, light and dark palettes, a German localisation, filled and hollow candles, and the depth chart — laid out side by side on a wide window and stacked on a narrow one.
Fixed:
- A pivot line — a zigzag, and anything else defined only at its corners — draws the leg that crosses the visible window. The painter walked only the candles in view, so a swing whose two ends sat either side of the window drew nothing at all, and the line vanished as soon as it was zoomed into.
- An indicator with no values in view no longer hands an empty path to the canvas.
isTapShowInfoDialogdoes something. The tap flag it depends on was never set, so the readout only ever opened on a long press; a tap now opens it, moves it, and closes it again.- The crosshair's price and date labels no longer appear without the crosshair itself. Both are shown together, and both are suppressed while a line is being drawn or dragged, instead of the labels being drawn whenever a long press happened and the lines being hidden for good as soon as the drawing tools were enabled.
- The line above the volume pane is no longer amber: the separator paint had a
hard-coded
Colors.amberthat no theme could reach. - The vertical grid draws the number of columns asked for. Both the main chart and the volume pane looped over a pixel distance instead of the column count, drawing around 120 lines per frame, nearly all of them off screen.
- The "now price" line uses
nowPriceUpColorandnowPriceDnColor, which existed for it but went unused — it was drawn in the high/low marker colours, near-black by default. - The watermark is centred in the candle area rather than pinned to a hard-coded offset that put it off screen on small charts.
- The candle area no longer collapses in a box shorter than the panes ask for; the panes shrink to fit instead of overlapping the candles.
- The bottom price-axis label is left out when a pane sits below the main chart, where it used to be drawn on top of that pane's legend.
NumberUtil.formatCompactkeeps the sign of negative values, which OBV needs.
1.0.0 #
- Initial release, extracted from an internal application module.
KChartWidget: candlestick and line rendering, pinch zoom, fling scroll, long-press crosshair and info dialog, "now price" line with candle countdown, and an SVG watermark.- Main-chart overlays
MA,BOLLandSAR, selectable as a set. - Secondary charts
MACD,KDJ,RSI,WRandCCI, stacked. - Drawing tools for trend, horizontal and vertical lines, with selection, dragging, colour and thickness editing, and add/remove callbacks.
- Buy/sell
SignalEntitymarkers. DepthChartfor bid/ask cumulative market depth with a long-press readout.ChartStyle,ChartColorsandChartTranslationsfor full visual and text customisation;DepthChartStyle,DepthChartColorsandDepthChartTranslationsfor the depth chart.DataUtil.calculatecomputes every indicator in place over a candle list.- Runs on iOS, Android, web, Windows, macOS and Linux. The zoom slider now appears only where there is no pinch gesture — web and desktop — where before a always-true platform check rendered it on mobile as well.
Fixed while extracting the module:
DataUtil.calculateno longer throws on an empty candle list, so the chart can be built before the first candles arrive.- Secondary charts scale to their true maximum when an indicator stays below
zero.
MACDandCCIin a sustained decline previously scaled against zero, because the running maximum was seeded withdouble.minPositive— a tiny positive number rather than a lower bound. SARresets its acceleration factor identically on both trend reversals; the up-to-down reversal previously restarted one step too fast.- The "now price" countdown timer starts and stops when
showNowPricechanges, instead of only being read once when the chart is first built.