os-js / osjs-widgets

OS.js Widgets Module
https://manual.os-js.org/v3/
2 stars 4 forks source link

Using chart in widget. #7

Closed miladhashemi closed 4 years ago

miladhashemi commented 4 years ago

How can I use chart in widget? like amCharts.

andersevenrud commented 4 years ago

You have direct access to the widget root DOM element. Just make sure to disable the canvas option so the render method is only called once.

  render() {
    createChartInside(this.$element);
  }

I haven't used this chart libraray before, but looking at https://www.amcharts.com/docs/v4/chart-types/pie-chart/ it seems like you might be able to do:

let chart = am4core.create(this.$element, am4charts.PieChart);
miladhashemi commented 4 years ago

Hi, Finally I tested amchart in as osjs-widget: image

But already I have some issue:

  1. In fact the dimension in constructor hasn't effect on widget size. for example if i set as bellow, it doesn't make widget with defined width and height. and I must style this->$element separately.

    constructor(core, options) {
    super(core, options, {
      canvas: false,
      // Our default dimension
      dimension: {
        width: 400,
        height: 200
      }
    }, {
      // Custom options that can be saved
      // fontFamily: 'Monospace',
      // fontColor: '#ffffff'
    });
    }
    this.$element.setAttribute('id', 'chartdiv');
    this.$element.setAttribute('style', 'width:700px; height:300px;');
  2. According to src/widget.js, I expect to have resize functionality as canvas but I don't have resize on the right bottom corner widget.

andersevenrud commented 4 years ago

In fact the dimension in constructor hasn't effect on widget size.

Hm. If you look at the updateDimension method on a Widget, you can see that it applies the dimension to both the canvas and the outer $element. You should see this when you inspect the DOM with devtools.

I don't have resize on the right bottom corner widget.

My guess is that the chart blocks pointer events. The resize handle only appears when you hover a widget. You could try setting pointer-events: none CSS value on the chart.

andersevenrud commented 4 years ago

Also, using IDs on elements is not recommended.

miladhashemi commented 4 years ago

Hm. If you look at the updateDimension method on a Widget, you can see that it applies the dimension to both the canvas and the outer $element. You should see this when you inspect the DOM with devtools.

It was my mistake at testing. I was changing dimension attribute, after that I was using npm run build. At last I just was refreshing the page with current launched widget, without launching new widget on my osjs!!! Here was my mistake. :/

miladhashemi commented 4 years ago

My guess is that the chart blocks pointer events. The resize handle only appears when you hover a widget. You could try setting pointer-events: none CSS value on the chart.

Why should I set pointer-events:none? If I do it then I think I don't have hover, but now I have hover and I can move widget. Just the resize handler doesn't exist right now. Not only for chart, but also for simple text in element: this.$element.innerText = 'test';

miladhashemi commented 4 years ago

Also, using IDs on elements is not recommended.

Why is it not recommended?

andersevenrud commented 4 years ago

Not only for chart, but also for simple text in element:

Aha. The chart library probably clears the this.$element ! To get around that just create a wrapper container :)

Why is it not recommended?

Because IDs are ment to be unique and very easy to have duplicates of. For example if another application create a DOM element with the same ID, then your script would put the chart in the wrong container.

This is why IDs are not used anywhere, but rather element references.

miladhashemi commented 4 years ago

Aha. The chart library probably clears the this.$element ! To get around that just create a wrapper container :)

It seems I didn't explain issue correctly. please put amChart away. The issue is about this->$element. I have resize option just in canvas.

import {Widget} from '@osjs/widgets';

export default class AmChartWidget extends Widget {

  constructor(core, options) {
    super(core, options, {
      canvas: false,
      // fbs:1,
      // Our default dimension
      dimension: {
        width: 700,
        height: 300
      }
    }, {
      // Custom options that can be saved
      // fontFamily: 'Monospace',
      // fontColor: '#ffffff'
    });
  }

  // Every rendering tick (or just once if no canvas)
  render() {
    this.$element.innerText = 'test';
  }
}

I haven't resize option in this simple scenario. "@osjs/widgets": "^3.0.6"

andersevenrud commented 4 years ago

The resize handle is inside this.$element. So if you do `this.$element.innerText = 'something', the handle will disappear.

This is probably what the chart library does (or similar). So you can just create a new element and reference that in your code to eliminate this issue.

constructor() {
  // ...
  this.$mycontainer = document.createElement('div'); // might need to set the width/height etc
  this.$element.appendChild(this.$myelement);
}
miladhashemi commented 4 years ago

Exactly I wanted this. Thanks.