Comments (2)
The multiplatform management of the sizes is complicated and gives me nightmares ;-).
Each platform has its way of managing it. For example, on iOs, the UIKit API manages the pixel density transparently. So you deal with sizes that are not the actual sizes on the screen, but logical size (see https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html).
On Android, the developer has to use actual pixels when drawing on a canvas.
To provide visualizations that appear the same on each platform, we provided an abstraction over these sizes. We decided to use the iOS way, using logical sizes corresponding to the CSS Pixel sizes. So, for example, when you choose to draw a text of size 14, it will be readable on all the devices and have the same angle size no matter the pixel density.
This abstraction is why you cannot set the size on a VizContainer. Instead, data2viz gives you the logical size of the container (equals the actual size divided by the pixel density).
So now, how can you manage your sizes in Data2viz?
First, you can use fixed sizes for a few elements: text and graphical elements that should appear constant (a cross representing a position).
Next, you should use scales for all elements that take the Viz size into account.
val widthScale = Scales.Continuous.linear {
domain = listOf(.0, 100.0)
range = listOf (.0, viz.width)
}
viz.onResize {
widthScale.range = listOf (.0, it.width)
}
The elements that depend on the scales don’t have to be cleared and recreated. On every rendering
I hope this helps.
Example:
var count = 0
class ScaleView(context: Context) : VizContainerView(context) {
val group: GroupNode
val text: TextNode
init {
val scale = Scales.Continuous.linear {
domain = listOf(.0, 1000.0)
}
val viz = newViz {}
addResizeListener { it ->
scale.range = listOf(.0, it.width)
viz.startAnimations()
}
group = viz.group {
circle {
radius = 20.0
fill = Colors.Web.red
}
}
text = group.text {
y = 30.0
}
viz.animation {
group.transform {
translate(x = scale(count++.toDouble()))
}
text.textContent = count.toString()
}
}
}
from data2viz.
Thank you for the response.
In your explanation, you use both viz.onResize()
and container.addResizeListener()
. Could you clarify which of these the scales should be updated in?
Assuming the latter is the correct one: Unfortunately, the calculation of sizes within my viz is a bit complicated (taking paddings into account, and scaling elements relative to others, etc.), which would make it relatively cumbersome to re-do all those calculations outside the viz so that all scales can be updated. Besides that, I feel like it shouldn't really be the responsibility of a platform-specific listener to modify viz-internal scales. In your example, the viz is part of the View, but in my case I use a platform-independent viz that should only be wrapped thinly with a platform-specific View.
This abstraction is why you cannot set the size on a VizContainer. Instead, data2viz gives you the logical size of the container (equals the actual size divided by the pixel density).
I don't quite get how not being able to set the size follows from the abstraction. The different units of measurement make it necessary to convert between units, sure. But setting the size in one unit should just automatically set the size in the other too, right...?
I think the crucial question is in what direction measurements are propagated.
In the example you gave, there is a top-down propagation: Android specifies a size of the container, the container converts that into a logical size and draws the viz using that. When Android changes the container size, the viz should adapt its scales to the new size. So far so good. However, one of the issues I raised was that the viz doesn't get informed about container resizes. container.addResizeListener
gets called, but not viz.onResize
.
I believe it's necessary to also support bottom-up propagation. In my case, I want a chart to take up as much vertical space as it needs to fully render some customized bars (the size of the bars is determined by the data and a fixed unit vector length). I believe the correct propagation order would be:
- Android informs the container that it has a
wrap_content
size. - The container tells the viz that there are no measurements imposed from the outside and that it needs to specify its own logical dimensions.
- The viz specifies its measurements, which the container converts. The container sets its own size accordingly.
- Android makes space for however much room the container requested.
from data2viz.
Related Issues (20)
- Runtime exception due to wrong casting
- Add a copy() function to all scales
- [VIZ] Stroke properties should be called strokeColor ?
- Handling changing and/or real-time data HOT 4
- Use the latest KotlinX DateTime version HOT 1
- Android version does not support the dashedLine property of the HasStroke interface HOT 1
- Share Meta keys on KEvent
- [Feature request] Export as SVG HOT 8
- Upgrade JavaFX to version 11 HOT 1
- Manage multi line rich text
- Wrong measure text on Android and JS when the text starts or ends with whitespaces HOT 1
- Viz appears blurry on a HDPI screen, using Kotlin/JS IR compiler
- Introduce HeadlessVizContainer
- Wrong height of TextNode.measureText()
- Force Directed Graphs
- Scaling transformation is missing HOT 1
- chart in loop ? HOT 2
- Fatal Exception: java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/Instant; HOT 3
- Add Kotlin's wasm-js target
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from data2viz.