Is there a documentation site I can visit to see what properties come with the tree
chart type without installing the module? I looked on the Chart.js docs site, but didn't see any chart of that type in the core or base Chart.js library. Is this an implementation of a 3rd party Tree library (e.g. sgratzl
's chartjs-chart-graph)?
Yup, that’s exactly what it is. It looks like it’s missing from the list of included plugins, I’ll make sure it gets added. I believe most of his plugins are included; if there’s something extra you’d like to see included let me know.
Wow, that's awesome - I can't wait to give it a try! I have some ideas for the Tree chart type, so if I can get those implemented, I'll be testing using this module for a few production systems, to start at least.
Just a heads up, the designer schema currently doesn’t have any support for plugins (my focus has been on the main Chart.js properties), but any contributions are welcome if you’re able/interested.
Version 1.3.4:
- Updated Chart.js to version 4.4.4.
Maybe I am missing it in the other replies, but I have a non-issue I have run into.
I have specific colors for pie slices and I am using the backgroundColor property as an array. This works as expected in rendering, but the designer is quite unhappy with me for it. I imagine you may need to add array as an option in your component.props.json.
Or is there a better way for me color my pie slices?
Unfortunately, if I do that we’ll lose the color picker for the single backgroundColor
option . I don’t know of a way to get the color picker for the property as both a string and an array.
The current state of the designer component property validator is kinda lame, it’s definitely in a “minimum viable product” state. There’s many parts of the Chart.js
schema that push the boundaries of what the designer property validation can handle.
Totally makes sense! Just passing along what I encountered. Overall still great to use. I make the designer props tree angry often so no worries here! Thanks for giving the community an awesome tool!
I really do appreciate it, and if you come across anything else weird throw it in this thread or on GitHub issues.
I figure that the designer validator will eventually be improved, and when it does it’ll be nice to have these issues documented.
Maybe sometime in 8.3 land the validator will be better. A guy can hope anyways!
would it be possible to release an example config for dendogram/forceDirectedGraph/tree/treemap ?
I can't seem to get these working properly
According to sgratzl/chartjs-chart-graph: Chart.js Graph-like Charts (tree, force directed) (github.com) I should be able to use the parent tag to configure how points are connected but I can't get it working:
I'd like to get to a point where I can show PLC connections to Ignition, show the Slave's below those PLC's and show inter PLC connectivity
Idealy I'd use the forceDirectedGraph and just define the connections and whether or not a node is online or not.
Yup. I’m out of office the rest of this week, but I’ll put something together next Monday/Tuesday.
I’m on mobile, so excuse the poor explanation lol.
The chart type in your screenshot is wrong; either at the top of the props (props.type
) or in the dataset (props.data.datasets[i].type
) set the type to either graph
, forceDirectedGraph
, dendrogram
, or tree
.
treemap
is something entirely different, and the type: line
configured in your dataset is overwriting the top level property. In your screenshot the chart is rendering as a line chart.
hmmm..
I'm matching those type's now to dendogram but that results in a singlepoint for the first dataset and nothing for the other.
Looking forward to your working example when you have time
same with forceDirectedGraph:
Alright, good news and bad news.
Bad News
There is a bug in the chartjs-chart-graph
plugin. The chart only renders once, and any subsequent renders throw errors. I've submitted an issue to the library author, you can track it here. I believe it's a simple fix.
Good News
- The issue can be side-stepped by enabling the newly added
redraw
property. Whenredraw
is enabled, the chart will be completely destroyed/recreated on each render. Bad for performance but useful for debugging. - This issue pointed out some extra re-rendering that was happening, it's been solved with some memoization. There should be a performance boost here.
- The components for the
tree
chart weren't registered, so those were never working.TreeChart
andTreeController
are now registered correctly.
I will publish a new version once a fix is available.
No news on the chartjs-chart-graph
plugin, and I don't have time to make the fix myself .
But, here's a new Embr-Charts release that includes properly registered TreeChart
components. If you use the new redraw
property you can sidestep the issue in the chartjs-chart-graph
plugin at the cost of performance/animations.
@embr-modules/charts@1.4.0
Minor Changes
- 60d382e: (Web) Memoize property transforms.
- 60d382e: Add optional
updateMode
andredraw
component properties.
Patch Changes
Any tips on options>plugins>crosshair? I get an error when changing to true.
java.util.concurrent.ExecutionException: java.lang.Exception: Unable to get the view config: View config is undefined.
Thank you for this module btw.
For sure.
- The crosshair plugin doesn’t like to be partially configured, and when it crashes, it crashes catastrophically. The best way I’ve found is to configure it as
crosshair2
, then once you get it set up change the key tocrosshair
. - The crosshair plugin seems to have its own zoom implementation that fights with the normal zoom plugin. I think I remember needing to disable the base zoom plugin.
Thank you for building this module. I'm finding it very useful.
Is there some way to utilize the event handlers, such as plugins.zoom.zoom.onZoom/onPan? Or to access the min/max x-axis values being shown as the user pans/zooms?
I have a time series chart where I'd like to make API requests based on the timeframe being shown as the user zooms/pans, but I'm unable to find a way to achieve that. Even just a means of accessing the min/max values being shown in the x-axis would suffice, but the scale properties don't appear to get updated as the user pans/zooms.
Yup, you can do this by using the Scriptable Options feature.
I've intentionally not turned these into component events, because I don't want to limit the possibilities.
Here's an example that will write the min/mix X-axis values to a custom property on the component:
Example View JSON
{
"custom": {},
"params": {},
"props": {},
"root": {
"children": [
{
"custom": {
"xAxis": {
"end": 63.29596760742342,
"start": -16.704032392576583
}
},
"meta": {
"name": "Chartjs"
},
"position": {
"height": 300,
"width": 633,
"x": 69,
"y": 242
},
"props": {
"data": {
"datasets": [
{
"data": [
{
"x": 0,
"y": 20.790464349448122
},
{
"x": 1,
"y": 27.541905413990484
},
{
"x": 2,
"y": 9.044548907913263
},
{
"x": 3,
"y": 63.58544584440057
},
{
"x": 4,
"y": 40.57122042169531
},
{
"x": 5,
"y": 46.17945691520222
},
{
"x": 6,
"y": 5.272367698783542
},
{
"x": 7,
"y": 78.62029735550435
},
{
"x": 8,
"y": 1.384758302338518
},
{
"x": 9,
"y": 8.094105544748587
},
{
"x": 10,
"y": 93.29711393437752
},
{
"x": 11,
"y": 78.54999817500953
},
{
"x": 12,
"y": 30.022085778849018
},
{
"x": 13,
"y": 68.38927062938775
},
{
"x": 14,
"y": 93.84973459203651
},
{
"x": 15,
"y": 85.15266831524416
},
{
"x": 16,
"y": 3.3272574045278946
},
{
"x": 17,
"y": 3.4738230710669837
},
{
"x": 18,
"y": 76.78237778113568
},
{
"x": 19,
"y": 76.13468451530511
},
{
"x": 20,
"y": 88.63284915490885
},
{
"x": 21,
"y": 92.74877419440537
},
{
"x": 22,
"y": 94.12886888152015
},
{
"x": 23,
"y": 97.06398992204936
},
{
"x": 24,
"y": 46.71625167184086
},
{
"x": 25,
"y": 13.224799335767212
},
{
"x": 26,
"y": 35.052260048430696
},
{
"x": 27,
"y": 29.46821488097423
},
{
"x": 28,
"y": 90.27395392440542
},
{
"x": 29,
"y": 7.832816289114186
},
{
"x": 30,
"y": 15.799390058813623
},
{
"x": 31,
"y": 80.66585380750348
},
{
"x": 32,
"y": 4.629220116475031
},
{
"x": 33,
"y": 24.00958904699422
},
{
"x": 34,
"y": 8.133906226255029
},
{
"x": 35,
"y": 81.93116748921958
},
{
"x": 36,
"y": 82.82333811028309
},
{
"x": 37,
"y": 95.37635776015469
},
{
"x": 38,
"y": 74.00252644137744
},
{
"x": 39,
"y": 27.90694570663671
},
{
"x": 40,
"y": 30.569029278167793
},
{
"x": 41,
"y": 11.104072480586257
},
{
"x": 42,
"y": 68.15581447149303
},
{
"x": 43,
"y": 27.051454957054943
},
{
"x": 44,
"y": 48.477001171626725
},
{
"x": 45,
"y": 73.62917163080661
},
{
"x": 46,
"y": 7.528701180738118
},
{
"x": 47,
"y": 21.794180888547032
},
{
"x": 48,
"y": 17.0019331614802
},
{
"x": 49,
"y": 80.4420964468141
}
],
"label": "Dataset 1"
},
{
"data": [
{
"x": 25,
"y": 99.00283352088223
},
{
"x": 26,
"y": 36.743648170189644
},
{
"x": 27,
"y": 33.58269158236888
},
{
"x": 28,
"y": 70.52608530981715
},
{
"x": 29,
"y": 78.48664561425423
},
{
"x": 30,
"y": 99.80258881269653
},
{
"x": 31,
"y": 23.56577175483505
},
{
"x": 32,
"y": 27.6260054014127
},
{
"x": 33,
"y": 11.84780583914382
},
{
"x": 34,
"y": 78.95435294680595
},
{
"x": 35,
"y": 89.0983947949238
},
{
"x": 36,
"y": 87.63589420154018
},
{
"x": 37,
"y": 82.4714423791225
},
{
"x": 38,
"y": 46.29407127415893
},
{
"x": 39,
"y": 12.463880984334686
},
{
"x": 40,
"y": 91.82293604614682
},
{
"x": 41,
"y": 9.645637547490315
},
{
"x": 42,
"y": 23.87358763050218
},
{
"x": 43,
"y": 64.35308758482624
},
{
"x": 44,
"y": 61.30614039090162
},
{
"x": 45,
"y": 60.123113026673906
},
{
"x": 46,
"y": 11.262924017594045
},
{
"x": 47,
"y": 36.72684549715057
},
{
"x": 48,
"y": 19.144808134626057
},
{
"x": 49,
"y": 11.499648689135334
},
{
"x": 50,
"y": 48.862954644422615
},
{
"x": 51,
"y": 44.0188922198424
},
{
"x": 52,
"y": 1.4731641405698048
},
{
"x": 53,
"y": 76.62654204425371
},
{
"x": 54,
"y": 97.09498548555429
},
{
"x": 55,
"y": 68.88623969428103
},
{
"x": 56,
"y": 9.347347267187478
},
{
"x": 57,
"y": 27.59945299037486
},
{
"x": 58,
"y": 38.62680310622668
},
{
"x": 59,
"y": 64.48467246665813
},
{
"x": 60,
"y": 99.50148874944306
},
{
"x": 61,
"y": 59.35003045509352
},
{
"x": 62,
"y": 7.407803152895475
},
{
"x": 63,
"y": 62.077958133975066
},
{
"x": 64,
"y": 19.550924069869623
},
{
"x": 65,
"y": 59.290461562229346
},
{
"x": 66,
"y": 15.46272365498117
},
{
"x": 67,
"y": 27.411246578970218
},
{
"x": 68,
"y": 59.515203740704415
},
{
"x": 69,
"y": 76.39871363134311
},
{
"x": 70,
"y": 20.255435491968
},
{
"x": 71,
"y": 57.26165130029921
},
{
"x": 72,
"y": 73.41996375745644
},
{
"x": 73,
"y": 68.57751118650746
},
{
"x": 74,
"y": 25.40840081665815
}
],
"label": "Dataset 2"
}
]
},
"options": {
"plugins": {
"zoom": {
"pan": {
"modifierKey": null,
"onPan": "(context) \u003d\u003e { \n\nconst xAxis \u003d context.chart.scales.x\nconst customProps \u003d self.store.custom\n\ncustomProps.write(\u0027xAxis.start\u0027, xAxis.start)\ncustomProps.write(\u0027xAxis.end\u0027, xAxis.end)\n}"
},
"zoom": {
"onZoom": "(context) \u003d\u003e { \n\nconst xAxis \u003d context.chart.scales.x\nconst customProps \u003d self.store.custom\n\ncustomProps.write(\u0027xAxis.start\u0027, xAxis.start)\ncustomProps.write(\u0027xAxis.end\u0027, xAxis.end)\n}"
}
}
},
"scales": {
"x": {
"type": "linear"
},
"y": {
"type": "linear"
}
}
}
},
"type": "embr.chart.chart-js"
}
],
"meta": {
"name": "root"
},
"type": "ia.container.coord"
}
}
The key part is this:
# options.plugsin.zoom.pan.onPan
# options.plugsin.zoom.zoom.onZoom
(context) => {
const xAxis = context.chart.scales.x
const customProps = self.store.custom
customProps.write('xAxis.start', xAxis.start)
customProps.write('xAxis.end', xAxis.end)
}
You can always use onPanComplete
or onZoomComplete
if that's more useful for you.
I'd also recommend slapping in a console.log(context)
or a console.log(self)
to see what you're working with. You have access to every part of the chart through the context
parameter, and self
is the Perspective component itself.