Set axis max to image size

Comments

2 comments

  • Avatar
    Elvin Luff

    The above script is a snippet of my full script - the rest of the script executes a JAQL query as the URL of the image file is also stored in the dataset.

    In a different widget I created I also had the dimensions of the image itself stored in the dataset, and then it was easy - I just fetched that too, and applied it to the x and y axis.

    I'd prefer to avoid having to do that again.

    0
    Comment actions Permalink
  • Avatar
    Elvin Luff (Edited )

    Update on this - after much trial and error, I found a way. I don't think it's perfect but it's better than nothing.

    I found that you can't just set the x and y axis of a graph to anything - if it can't be cleanly divided into an interval, then it won't be accepted. So instead I take a different approach - I read the current axis limits, create a scaling multiplier, and then change the x and y coordinates of the dataset to scale correctly within the given limits.

    To tackle the reading of the image dimensions, instead of trying to wait for the image to load, I let the widget load as normal, then do a widget.redraw() as soon as the dimensions are available.

    let refresh = true;

    const setDimensions = (url) => {
    return new Promise((resolve, reject) => {
    var img = new Image();
    img.src = url;
    img.onload = () => {
    const scale = {
    x: (widget.style.xAxis.max - widget.style.xAxis.min) / img.naturalWidth,
    y: (widget.style.yAxis.max - widget.style.yAxis.min) / img.naturalHeight
    };
    widget.rawQueryResult.values.forEach((item) => {
    item[0].data = item[0].data * scale.x + widget.style.xAxis.min;
    item[0].text = item[0].data.toString();
    item[1].data = item[1].data * scale.y + widget.style.yAxis.min;
    item[1].text = item[1].data.toString();
    });
    widget.redraw();
    resolve();
    };
    });
    };

    widget.on("queryend", (scope, result) => {
    refresh = result.reason != "widgetredraw";
    });

    widget.on("beforeviewloaded", (scope, args) => {
    args.options.chart.plotBackgroundImage = URL_TO_IMAGE;
    if (refresh) {
    setDimensions(URL_TO_IMAGE);
    }
    });

    The "refresh" variable is there to break an infinite loop - if we redraw the widget to change the scaling multiplier, then "beforeviewloaded" is triggered again. Essentially I just look for the reason that the widget is being refreshed, and set refresh to false if the reason is a redraw.

    Would like to hear if anyone has a cleaner solution. I don't like the refresh global variable method, it feels very hacky.

    0
    Comment actions Permalink

Please sign in to leave a comment.