terezka / elm-charts Goto Github PK
View Code? Open in Web Editor NEWCreate SVG charts in Elm.
Home Page: https://www.elm-charts.org
License: BSD 3-Clause "New" or "Revised" License
Create SVG charts in Elm.
Home Page: https://www.elm-charts.org
License: BSD 3-Clause "New" or "Revised" License
The calculation of positions doesn't always return the right amount. For a graph with a height set to 100 (with Y values ranging from 1 to 100), this results in the ticks/labels being all bunched up too close to each other.
This seems to be related to the Plot.decentPositions
function. Testing it out in the REPL, I get:
> import Plot
> summary = Plot.AxisSummary 1 98 1 98 20 20 100 []
{ min = 1, max = 98, dataMin = 1, dataMax = 98, marginLower = 20, marginUpper = 20, length = 100, all = [] }
: Plot.AxisSummary
> Plot.decentPositions summary
[10,20,30,40,50,60,70,80,90,100,110] : List Float
Based on the implementation of decentPositions
, I'd expect to get 5 positions back, not 10. Digging further, I found that decentPositions
calls out to niceInterval
with the number of desired positions as an argument.
In my case, decentPositions
correctly asks niceInterval
to calculate an interval for 5 positions but niceInterval
incorrectly returns an interval that results in 10 positions. By removing the magMsdFinal
coercion, I was able to make it work with my particular data set but there are a bunch of edge cases it still can't handle.
I think the algorithm of niceInterval
needs to be tweeked such that range / interval
equals the desired total
passed in +/- 1. It might be worth adding a fuzz test around this?
I'm opening this issue in case someone else has run into the same issue and to get help from the community improving the niceInterval
algorithm. If I find a good implementation, I will open a PR.
Let me know if there's anything else I can do π
We at Humio are really anxious to replace our Hacky Highcharts-in-Elm chart implementation.
We were going to build our own, but I think Elm-Plot is so promising that we would prefer to use it. (Good Work)
Only problem is that it seems to be in a big transition phase. Is it ready to start hacking on, or is it too unstable.
We would love to help out ( It is after all to our own benefit :) ), but we would need you to point us in the direction where we can be the most helpful.
Is there any way to define custom colours for the charts?
In our application we need a lot of timecharts. I was wondering if there are any plans on supporting them out of the box, or if you are interested in getting pull requests for tick positions and label formatting specifically for DateTime Axis?
Chart.Events.getNearestX
(and Chart.Events.getNearest
) seems to assume that the chart (with margins taken into account) start at the same coordinates as it's container. This becomes a problem if you let the chart overflow the container and then scroll in order to see the rest of the chart. As demostrated in this ellie example https://ellie-app.com/fjWqwCtT3PLa1, after scrolling to the right, the getNearestX
function is no longer able to find the nearest point reliably.
By decreasing the size of the chart as the screen/window gets narrower, details in chart get less clear and the axis labels become hard to read. On the other hand, tooltips and legends keep their original size on narrow screens and do not match the shrunken chart. The use of overflow preserv the original sizes.
It seems like the assumption stems from the Internal.Svg.decoder
function, but I'm not sure how to change it.
It seems that axes are drawn up to the last value. I think it should be drawn until the last tick instead. It's the same thing for the grid.
Here is an Ellie link:
https://ellie-app.com/jYZgjfykTa1/0
I this case it's not that bad but in some other cases it makes the plot feel a bit buggy.
For a plot with only one series whose y value does not change, the plot crashes.
Should plot a straight horizontal line
e.g. the following crashes
let
test =
List.range 1 60
|> List.map (\value -> (toFloat value, 10))
in
plot
[
]
[ line
[
]
test
, xAxis
[ Axis.line [ ]
]
]
This is caused by the getRange
function on line 21 in the package Internal.Stuff
Additionally to inline-styles there should be the possibility to use css-classes instead.
My intention here was to have a graph centered around 1.0, but have the ranges go from 0.5 to 1.5 to begin, which works.
The issue is that when I've got a datapoint, say 1.8, the linechart is off-screen. I'd expect the chart to expand to include 1.8, instead of stopping at 1.5.
CA.domain
[ CA.lowest 0.5 CA.orLower
, CA.highest 1.5 CA.orHigher
, CA.centerAt 1.0
]
The behaviour seems to be more like it's starting the initial bounds of the range, but not updating the bounds of the new data, after the data changes.
A line can't be drawn if the data has some digits (many 0?) after the floating point.
Ellie: https://ellie-app.com/fDHQ7myzw7Ba1. Check out the data declaration.
Zack K from Elm Slack found a workaround. Quote:
May have found a workaround. The clip-path style on your second g is invalid when both of the values are the same, which is why it displays properly. Setting clip-path: none seems to resolve the issue
path {
clip-path: none !important;
}
https://ellie-app.com/fDJVSfx6FnGa1
Don't have a great explanation why, but this might help you workaround for now
End quote.
A chart printed to PDF can show a phantom line when viewed in Chrome. Here is a close-up view near the origin, note the faint line:
This snapshot is taken from the second page of the attached PDF file.
I believe this is actually due to a known bug in Chrome -- https://bugs.chromium.org/p/chromium/issues/detail?id=1201141&q=svg%20pdf&can=2
The line does not appear when I view the PDF in Mac preview, or in Safari, or in Firefox.
Given the ubiquity of Chrome, I am wondering: might the workaround suggested in the bug report might be usable in elm-charts, specifically "replacing "stroke: transparent" with "stroke: none" as a workaround"?
Finally, thank you for elm-charts, it makes my life better!
When describing medical trials, boxplots are used all over the place, they look like this:
https://discourse.elm-lang.org/t/looking-for-all-the-charts/7137/18
Wikipedia has a nice article about boxplots with good examples.
First of all, I really really like this library, thank you @terezka for all the time and effort and thought you put into it.
I have been struggling to understand how to use hints from the documentation, so I thought I would play around with the example code in https://terezka.github.io/elm-plot/ .
However, after cloning the repo, I couldn't find any way to build Docs.elm, there is no Readme nor Makefile, so I tried elm-make Docs.elm
and a few more variations of that.
Eventually, it seems like the code uses an outdated version of elm-plot, because Docs.elm is trying to import a PlotComposed
module that is not declared anywhere.
Thank you for your time and please let me know if I can help.
With the new API you seem to be forced to overlap plots if you want to render multiple data series on the same axes, for instance:
This works okay except the onHover
of PlotCustomizations
seems to only trigger on the top-most plot, which I'd think would not be a limitation of the DOM unless stopPropagation
was being used, but seems to be what I'm experiencing.
I can't see anything in the docs for horizontally oriented bar charts, so I guess this isn't implemented. If there is a way to do horizontal bar charts, consider this an issue about improving the documentation :P
Hi,
first of all, great tool ;)
I was wandering if it is possible to assign labels/titles to the axis? The problem is, that these axes are not static and might change over time, due to changes in the x and y ranges ...
Do you have any suggestions?
Regards,
AndrΓ©
Hello,
First, thank you so much for this great library π
I've stumbled upon what I think is a bug when using stacked bar charts and legends combined, as demoed in the short code sample below:
import Chart as C
import Chart.Attributes as CA
import Html exposing (Html)
chart : Html msg
chart =
C.chart
[ CA.height 500, CA.width 500 ]
[ C.legendsAt .min .max [] []
, [ { x = 1, y = 2, z = 3 }
, { x = 4, y = 5, z = 6 }
, { x = 7, y = 8, z = 9 }
]
|> C.bars []
[ C.stacked
[ C.bar .x []
|> C.named "X"
, C.bar .y []
|> C.named "Y"
, C.bar .z []
|> C.named "Z"
]
]
, C.barLabels [ CA.moveDown 16, CA.color "white" ]
]
This gives this:
As you can see, the legends don't match the data and their graphical representation. It seems to me that the legend colors are reversed. Or am I missing a piece of understanding on how stacked barcharts and legends should work together?
Thanks again for your amazing library!
Hi, I am no SVG expert. But for our application we need charts that can be resized based on the parent container. When the window resizes or a number of other event occur that impact the space available for the chart, it should size-to-fit.
Currently we have to set the width and height in the configuration of the chart. Now understand why that is, but at the same time, SVG also has support for different kinds of scaling, e.g. preserveAspectRatio
.
I don't know if it is possible to preserve text scale and stroke width while spacing out ticks etc based on the space available. We would love to say { width: 100%, height: 100% } to avoid all the bookkeeping we have to do now.
Hello,
I was wondering what is the plan for this library. I see that it says that it will be deprecated in the future, is it safe to use? Will the line package be similar enough to allow for an easy port? Why did you decide to separate the features in the library?
By the way thank you for making it available. I was about to dive into elm-visualization but then someone in elm slack suggested this and I was able to get something working (not perfect yet) very quickly.
xTick
and yTick
have different signatures, with yTick
taking an extra Float
:
xTick : List (Attribute Tick) -> Element data msg
yTick : List (Attribute Tick) -> Float -> Element data msg
From a quick scan of the source code, it looks like the Float
argument is not used in yTick
.
According to https://github.com/debois/elm-dom, debois/elm-dom is deprecated, but a forked and maintained version is available as K-Adam/elm-dom (https://github.com/K-Adam/elm-dom/).
Would it be possible for elm-charts to depend on the maintained version?
I wish elm-charts allowed for using Html.lazy
/ Svg.lazy
for particular parts of the chart, so that you could only pay the rendering work once for the actual chart and then compute only the interactive stuff as your hovering : List ...
changed.
Right now it seems we're paying the whole view
cost at all times. Wrapping C.chart
in Html.Lazy
helps shield it from unrelated Msgs, but still, for the actual interactivity of the chart, it feels like it should be possible to factor rendering the actual SVG chart away from the rendering of the interactive stuff (lines, tooltips, ...).
Hi, I am creating a timeline with the ability to select a time range on a histogram.
I need to be able to size the selection area based on the start and end dates.
I ended up making a copy of toSVGX
to handle the conversion. Maybe I am missing
something (I just started using elm-plot).
timelineJunk : PlotSummary -> Float -> Float -> List (Plot.JunkCustomizations Msg)
timelineJunk summary pointAX pointBX =
let
start =
Basics.min pointAX pointBX
end =
Basics.max pointAX pointBX
areaWidth =
-- We add 1.5 to include both the start and
-- end bar in the area. The coordinates
-- represent the middle of the bar, hence the
-- 0.5s.
end - start + 1.5
areaPxWidth =
(ElmPlotUtils.toSVGX summary areaWidth) - summary.x.marginLower
toDate index =
-- barData is a list of (date, yValue) tuples.
Array.get (round index - 1) barData
|> Maybe.map Tuple.first
|> Maybe.withDefault 0
range =
( toDate start, toDate end )
selectedRangeArea =
junk
(Svg.rect
[ opacity "0.1"
, fill "purple"
, width <| toString areaPxWidth
, style "height: 45px"
]
[]
)
(start - 0.5)
summary.y.max
-- Since we need something to detect the mouse
-- up event, we cover the chart with an overlay.
mouseUpOverlay =
junk
(Svg.rect
[ E.onMouseUp (EndRangeSelection range)
, fill "transparent"
, width "100%"
, height "100%"
]
[]
)
0
summary.y.max
in
[ selectedRangeArea
, mouseUpOverlay
]
I've attached the project. Ideas of how to do it in another way is welcome.
As far as I can tell it seems like it's not possible to create our own implementation of functions of type:
customFunc : Remodel (One data Any) (Item result) -> Decoder data (List (Item result))
which is what CE.onMouseMove
expects for its 2nd parameter, because both Remodel
and Decoder
don't have their constructors exposed.
So if I want to write a custom implementation of CE.getNearest
, e.g. one that can return the n nearest items instead of just the single nearest one, how would I do that?
Hey there,
First off, thanks for the super rad package!
When using bar stacks with roundTop
, I've come across two kind of obscure display issues when using CA.roundTop
on C.bars
within a stack
The code is roughly:
C.bars [ CA.roundTop 0.3 ]
[ C.stacked [ ... ]
]
data
If it'd be helpful, I can also re-create these issues in an Ellie.
Lines of the form [(a,0),(b,0)] do not plot as expected. [(0,0)] also does not plot as expected.
This may be partly due to a div by zero here:
scaleValue : Scale -> Value -> Value
scaleValue { length, range, offset } v =
(v * length / range) + offset.lower
A potential workaround is plotting a background-color vertical line.
The old Elm-plot looks more intuitive/human to me, and Chart.Attributes.amount
is not working for me.
Is there any way we could get an upgrade to 0.19.1?
Looking at the new implementation of Histograms there seems to be a direct relation between the labels/ticks on the X-axis and the bars. In my opinion this should not always be the case.
Take time series or datasets with very large numbers in the X-range. Here you want to find humanly readable/reference-able values like "Jan 2017" or "5M" instead of "Jan 3rd 2017" and "5.010.014".
This can mean that the tick will end up in the middle of a bar and not the edges and we must be able to control that.
This does not seem to be possible with the new implementation. Or am I wrong?
It can be difficult or impossible to display hints for a particular scatter plot point by default, which may be an artifact of how the mouse pixel position resolves to plot coordinates.
Some kind of tolerance may need to be applied to capture points near the mouse position, though this could be confusing if the X coordinate of the hint is not the same as the actual X coordinate location of the mouse, for instance if the hint for a line is also being display. Since it's up to the user code to display to the hint anyway maybe it's more appropriate for the user code to handle this situation, which should be possible since HintInfo
provides the xValue
.
The relevant code is here: https://github.com/terezka/elm-plot/blob/master/src/Plot.elm#L700
When using Chart.Attributes.domain
, I expect the x-axis to be affected, and when using Chart.Attributes.range
, I expect the y-axis to be affected. However, the opposite seems to be true. The following example shows three basic charts, one unmodified, one with an increased domain, and another with an increased range, on elm-charts 3.0.0
.
module Main exposing (main)
import Browser
import Chart as C
import Chart.Attributes as CA
import Html exposing (Html, div, span, text)
import Html.Attributes exposing (style)
main : Program () () a
main =
Browser.sandbox { init = (), view = view, update = \_ _ -> () }
basicStyle : List (Html.Attribute msg)
basicStyle =
[ style "height" "300px", style "width" "300px", style "margin" "50px" ]
chartData : List { x : Float, y : Float }
chartData =
List.range 1 10
|> List.map (\x -> { x = toFloat x, y = toFloat x })
chartElements : List (C.Element { x : Float, y : Float } msg)
chartElements =
[ C.xAxis []
, C.xTicks []
, C.xLabels []
, C.yAxis []
, C.yLabels []
, C.series .x [ C.interpolated .y [] [] ] chartData
]
view : () -> Html msg
view _ =
div []
[ span [] [ text "Unmodified" ]
, div basicStyle
[ C.chart
[]
chartElements
]
, span [] [ text "Increased domain" ]
, div basicStyle
[ C.chart
[ CA.domain
[ CA.lowest 3 CA.less
, CA.highest 3 CA.more
]
]
chartElements
]
, span [] [ text "Increased range" ]
, div basicStyle
[ C.chart
[ CA.range
[ CA.lowest 3 CA.less
, CA.highest 3 CA.more
]
]
chartElements
]
]
I was unable to get the sizing to work correctly in IE.
In chrome the attached elm appears to work well, but in IE, not so much. I will probably not be using your tool due to this problem, but if you wanted some things to look at, here is is a sample that worked differently in two different browsers (I used chrome vs. IE 11)
iesucks.txt
Hey,
nice job π
And I've got some improvements:
viewBox
in the Svg and to remove the height and width Attributes.viewPlot : MetaConfig -> List (Svg.Svg msg) -> Svg.Svg msg
viewPlot { size, style } children =
let
( width, height ) =
size
in
Svg.svg
[ Svg.Attributes.viewBox
("0 0 "
++ (toString width)
++ " "
++ (toString height)
)
, Svg.Attributes.style (toStyle style)
]
children
main =
[ div [ style
[ ("display", "flex")
, ("height", "300px")
]
]
[ plot
-- ...
]
]
viewBox
-Attribute.viewBox
always to e.g. "0 0 300 200" would be responisve (100%)(toString width) ++ " " ++ (toString height) ++ "300 200"
would be the provided measurementsWhat do you think?
I think you should archive the repo since it's already deprecated.
This would also make it possible to filter it out in searches (archived:false
).
After poking around the code a bit, it looks like it might be possible to extend the viewActualBars
function to allow for stacked bars instead of clustering them adjacent to one another on the x-axis. Does this make sense to add as an option in the Bars
type alias?
Sorry I don't have much context about this project but I'm curious and interested. If that's a sensible API idea I'd happily hack on it a bit.
Thanks, and great work!
Here: https://package.elm-lang.org/packages/terezka/elm-plot/latest
It point to https://terezka.github.io/elm-plot which results in a 404.
Thanks for making this library @terezka. A common chart in the finance world is the candlestick chart. Are there any plans to support candlestick charts on the roadmap?
Companies using candlestick charts in the wild:
We currently have a dependency to elm-plot
"terezka/elm-plot": "5.1.0 <= v <= 5.1.0"
However, builds started failing today with the following error:
14:19:45 Error: The following HTTP request failed.
14:19:45 <https://github.com/terezka/elm-plot/zipball/5.1.0/>
Has this project been renamed/removed? Is there a workaround?
Thanks in advance for any help.
Edit: As background information, we saw a similar error with a rename of the elm-transducers project:
avh4-experimental/elm-transducers#8
I think it might make sense to have some more infos in the readme.
Especially cause you land directly on the readme when you use the package index.
Heya,
We depend on this package and was wondering is there plans to upgrade to Elm 0.19?
I can't find a way to display the x-axis labels without using padding
to my plot
call. The function seems to automatically make space for the y-axis labels, but have to explicitly account for the x-axis.
This isn't too bad, except that when I request padding I get an unnecessary extension of the y-axis down through the "0" of my x-axis.
For reference, here's how it looks without padding:
And here it is with padding:
Is there some more correct way to do properly display the x-axis labels?
If I clone the project and execute elm test, I get a compilation error due to the module Internal.Stuff not existing.
An example one: https://google-developers.appspot.com/chart/interactive/docs/gallery/timeline
I specifically would need to do something like this:
So the minimum features would be:
Advanced features I would need too are:
The use case is to show jenkins builds.
Btw I'm totally up to opening a PR for it.
Is it possible to create a custom axes with a custom, fixed scale? The reason I need this is that I am adding data dynamically to my plot and if the range of data changes, so those the size of my axes. Thank in advance
Junks don't seem to be supported in viewBarsCustom
. Any good reason for this?
The default X position used by yTick
puts the tick in the middle of the range.
From the definition of yTick
at https://github.com/terezka/elm-charts/blob/master/src/Chart.elm#L1305
{ x = CA.middle p.x
, y = CA.zero p.y
I believe CA.middle and CA.zero should be switched -- as it is, they are identical to the corresponding lines in xTick
Hi,
I have been playing with your library for one of my side projects. I am far from being an Elm veteran but here are few things that I noticed when working with the Plot.Bars
module.
From my understanding, in order to get my data into the Data
type, I have to use the toBarData
function with a data transformer. This seem to be trivial when using a list of records. During my experimentation, I have been using a Dict
type to store my dataset and I have been plagued with type mismatches. So I am wondering if it wouldn't make the whole thing easier to directly expose your internal data type and let users handle the conversion. For example you could define
type alias BarDataSet =
List BarData
and
type alias BarData =
{ x : Float
, y : List Float
}
or even
type alias BarData =
( Float
, List Float
)
In an other hand, this is still inconsistent since all the other plots are using a list of Point
. So one last solution could be to reuse Point
for your bar chart but automagically stack points with the same x
value.
In any case, I can live with the current implementation and it won't stop me from using your awesome library. :simple_smile:
From new elm project. Just after the elm init
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.3"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}
$ C:\dev\trading-chart-helper-v2\node_modules\.bin\elm install terezka/elm-charts
Here is my plan:
Add:
danhandrea/elm-time-extra 1.1.0
debois/elm-dom 1.3.0
elm/parser 1.1.0
elm/svg 1.0.1
justinmimbs/date 4.0.1
justinmimbs/time-extra 1.1.1
myrho/elm-round 1.0.4
ryannhg/date-format 2.3.0
terezka/elm-charts 3.0.0
terezka/intervals 2.0.1
Would you like me to update your elm.json accordingly? [Y/n]: y
-- PROBLEM BUILDING DEPENDENCIES -----------------------------------------------
I ran into a compilation error when trying to build the following package:
elm/svg 1.0.1
This probably means it has package constraints that are too wide. It may be
possible to tweak your elm.json to avoid the root problem as a stopgap. Head
over to https://elm-lang.org/community to get help figuring out how to take this
path!
Note: To help with the root problem, please report this to the package author
along with the following information:
elm/core 1.0.5
elm/html 1.0.0
elm/json 1.1.3
elm/virtual-dom 1.0.3
If you want to help out even more, try building the package locally. That should
give you much more specific information about why this package is failing to
build, which will in turn make it easier for the package author to fix it!
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
When reaching the end of the x-axis I get an hint box that is squeezed horizontally:
It should be wider as everywhere else in the chart:
To reproduce the issue:
https://ellie-app.com/jYZgjfykTa1/2
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.