amcharts3 icon indicating copy to clipboard operation
amcharts3 copied to clipboard

How can I mix automatic ValueAxes with custom ones

Open jimmykane opened this issue 6 years ago • 18 comments

Hi there,

I have the following issue/problem:

I am using Amcharts Serial Chart to parse several categories of data.

At the moment I only define the graphs for the charts as follows:

{
      id: data.getType() + activity.getID(),
      activity: activity,
      lineColor: data.getType() !== DataHeartRate.type ? false : this.eventColorService.getActivityColor(this.event, activity),
      bulletBorderThickness: 3,
      hideBulletsCount: 1,
      title: data.getType() + ' (' + activity.creator.name + ')',
      valueField: data.getType() + activity.getID(),
      balloonText: data.getType() + '<br><b><span>[[value]] ' + data.getDisplayUnit() + '</span></b></br>' + activity.creator.name,
      legendValueText: '[[value]] ' + data.getDisplayUnit(),
      fillAlphas: 0.05,
      lineThickness: 1.5,
      useLineColorForBulletBorder: true,
      type: 'line',
      hidden: data.getType() !== DataHeartRate.type,
    }

However one of my data is in duration of seconds. I understand that for that I need a ValueAxes that will have set it's properties to Duration.

But If I assign that valueAxes to the chart or tha graph object like above then the rest of the ValueAxes are broken and do not get their properties automatically.

Any tips or help on how to proceed with this?

I am willing to support/pay/contribute for the solution of my above problem.

jimmykane avatar May 21 '18 08:05 jimmykane

Just to mention:

I am not defining any ValueAxes because according to the docs and Automatic ValueAxis is created and that works like charm atm.

jimmykane avatar May 21 '18 09:05 jimmykane

New comment from Zendesk by Anthony Piris on ticket 34272. (replying here will automatically notify amCharts support agent)

Hi there,

In your scenario you have to define both value axes, however an automatically generated value axis is simply one default values assigned. All you have to do is simply create an empty object for your default axis and then a custom one for your duration:

valueAxes: [{
  // leave it empty. you can optionally set an id if you want to differentiate the two. 
  // the rest of the properties are filled in automatically, just as the automatic one would.
}, {
  // set up your duration axis 
  "id": "durationAxis",
  "duration": "...",
  "durationUnits": {
    // ...
  },
  // ...
}],

From there, just assign the duration graph's valueAxis property to the duration value axis' id property and leave the other graphs' valueAxis properties blank (or set to the empy axis object's id if you defined one).

I hope this helps.

Best,

Anthony Piris amCharts

amcharts avatar May 21 '18 10:05 amcharts

Hi @amcharts Antony,

I had tried the above approach but the moment another graph is visible the whole charts stops working with no error or what so ever:

Here is how I create for example the graph:

private getGraph(activity: ActivityInterface, data: DataInterface) {

    const graph:any = {
      id: data.getType() + activity.getID(),
      activity: activity,
      dataType: data.getType(),
      lineColor: data.getType() !== DataHeartRate.type ? false : this.eventColorService.getActivityColor(this.event, activity),
      bulletBorderThickness: 3,
      hideBulletsCount: 1,
      title: data.getType() + ' (' + activity.creator.name + ')',
      valueField: data.getType() + activity.getID(),
      balloonText: data.getType() + '<br><b><span>[[value]] ' + data.getDisplayUnit() + '</span></b></br>' + activity.creator.name,
      legendValueText: '[[value]] ' + data.getDisplayUnit(),
      fillAlphas: 0.05,
      lineThickness: 1.5,
      useLineColorForBulletBorder: true,
      type: 'line',
      hidden: data.getType() !== DataHeartRate.type,
    };
    if (data.getType() === DataPace.type) { // See here
      graph.valueAxis = graph.id;
    }
    return graph;
  }

And on the valueAxes of the chart:

valueAxes: graphs.reduce((array, graph) => {
        const valueAxis: any = {};
        if (graph.dataType === DataPace.type){
          valueAxis.id = graph.id;
          valueAxis.duration = 'ss';
        }
        array.push(valueAxis);
        return array;
      }, []),

The problems are 2:

  1. The Amchart gets stuck if the first graph/Axis is not the duration on (see attached video)
  2. The duration Axis persists onTop of another one if more than one category is selected.

I am attaching a video starting from issue n1 to n2. Link: https://drive.google.com/file/d/1Qu4NPe16zt4DGNzpNiUiJ-Z7zhQpPSP3/view

If you watch carefully:

In the first time I directly hover on the chart and it freezes. In the second time I relead the data (via the checkbox) and then I do not hover until I first select the pace which has the duration axis. After that all is working fine, except that the duration axis is on top of the other one but I suppose I can work around it.

I am stuck a bit here: https://github.com/jimmykane/quantified-self/commit/429a74a5e4084e70ca4286ef580f8e8d9b35ee57

As also said before, I would like to contribute in way for your time, I somehow feel bad taking your time if this is not trivial.

Thanks and may you have the will to solve this :-)

jimmykane avatar May 21 '18 15:05 jimmykane

From what I understand as well if I provide a valueAxis id and link that to the graph then there is not only one ValueAxis visisble, like it is with automode, thus the ValueAxis with id's stack up on the valueAxis area

jimmykane avatar May 21 '18 18:05 jimmykane

What I need to achieve in the end is to have a automatic ValueAxis based on the data that is of duration so I can depict the Pace and other Duration related data.

jimmykane avatar May 21 '18 18:05 jimmykane

New comment from Zendesk by Anthony Piris on ticket 34272. (replying here will automatically notify amCharts support agent)

Hi there,

So to clarify, are you just looking to set a single value duration value axis when you have duration values or do you need to have one numeric/auto and one duration axis? I'm not quite sure I'm following based on your code and latest comment.

To clarify right off, you can't have an automatic axis for duration. You have to explicitly define an axis with the duration properties set.

If you only need one axis, simply change your code to find a duration dataset then just create a single element valueAxes array and all of the graphs will use it without specifying it directly in their valueAxis property:

valueAxes: (graphs.some((graph) => { return graph.dataType === DataPace.type; }) ? [{duration: 'ss'}] : [])

If you need a single regular axis and a single duration axis, just modify your code to generate a two element valueAxes array - one empty for the automatic values and one with the duration and a constant string that every graph will use so that you're not stacking all the axes on top of each other:

let valueAxes = [{}];
if (graphs.some((graph) => { return graph.dataType === DataPace.type; })) {
  valueAxes.push({
    id: "duration",
    duration: "ss",
    //consider setting position: "right" or an offset to avoid overlap
  })
}

Pardon any syntax errors as I wasn't able to build your repo to test.

Best,

Anthony Piris amCharts

amcharts avatar May 21 '18 20:05 amcharts

@amcharts Hi there (again) and good morning.

My issue at the moment is that I follow your advice but, when I add the duration axis as seen in the video the chart freezes.

I will later on deploy a version with this issue so you can perhaps take a better look

jimmykane avatar May 22 '18 07:05 jimmykane

Give me a few as I need to present a good candidate that demostrates the issue.

jimmykane avatar May 22 '18 07:05 jimmykane

@amcharts I tried your solution, it works and sounds logical but when I start with displaying a non duration graph the Amcharts freezes as seen in the video. If I set the duration graph as the first visible all is fine

jimmykane avatar May 22 '18 09:05 jimmykane

Also if I display all graphs from start there is no problem. It only occurs when a non duration graph is shown first.

jimmykane avatar May 22 '18 09:05 jimmykane

Here is the config and now I load the graphs and value axes https://github.com/jimmykane/quantified-self/blob/dec7314f9965d6400c151b3414cf24290efbd72c/src/app/components/cards/event/chart/event.card.chart.component.ts

And here is the video of the above observation: https://drive.google.com/file/d/1P3Heeh2QG_7xh3JWq5V5ZXJNw7Y0dTkj/view

Just in case you need to run the project you can do npm install and then ng-serve and load a sample file from the samples folder (it's an GPX, TCx or fit file)

Make sure you are on the https://github.com/jimmykane/quantified-self/tree/amcharts/bug branch

jimmykane avatar May 22 '18 09:05 jimmykane

So I do believe there is a bug somewhere in the formating in regards to duration. For example if I remove all my dataset that have a duration the above setup works but of course I have no duration data displayed. Even if I stub the data and pass a constant value of 200 (duration in s) lets say the same things happens. All graphs and Amcharts freezes if the duration graph/axis is not shown at start.

jimmykane avatar May 22 '18 10:05 jimmykane

New comment from Zendesk by Anthony Piris on ticket 34272. (replying here will automatically notify amCharts support agent)

Hi there,

Can you please provide a working build? I tried running the steps listed and I'm getting the following error:

ERROR in ./node_modules/quantified-self-lib/lib/events/adapters/importers/fit/importer.fit.js
Module not found: Error: Can't resolve 'easy-fit' in '/<snip>/quantified-self/node_modules/quantified-self-lib/lib/events/adapters/importers/fit'

Visiting localhost:4200 afterward gives me an error.

Best,

Anthony Piris amCharts

amcharts avatar May 22 '18 10:05 amcharts

@amcharts

Zipped built (uncopress and use a webserver to serve index.html etc) https://drive.google.com/file/d/1YUoNg0Z_V2A2nwNGCZTZQcYnMvROPGZ5/view?usp=sharing

JSON file with data to load (uncompress first): https://drive.google.com/file/d/1c2qB3vQHIIgxR9WlGD4rclTLZY7IYpI0/view?usp=sharing

How to use the UI: https://drive.google.com/file/d/1lK8ICFSv-Obp7B3VvN7FDJLeDICqwrNM/view

I have added a debug point at the moment graphs and ValueAxes are about to be added to the Chart object

jimmykane avatar May 22 '18 11:05 jimmykane

New comment from Zendesk by Anthony Piris on ticket 34272. (replying here will automatically notify amCharts support agent)

Hi there,

Thanks for the zip.

I seem to have narrowed it down to the legend having trouble with displaying your duration graph value when it is hidden by default. If the duration (Pace) graph is made visible by default, you won't run into the problem. Alternatively, if you disable the legend's valueText by setting it to an empty string, it will also work.

I'll file an internal bug ticket on this and we'll follow up when we have an update.

Best,

Anthony Piris amCharts

amcharts avatar May 22 '18 13:05 amcharts

@amcharts you are the BEEEEEESSSTTTT! I knew there was something buggy that is why I went into the effort guys!

I hope I have somehow contributed to making Amcharts better.

Ouf that was a hard one.

Thanks again from the heart Anthony, I can now sleep without nightmares.

jimmykane avatar May 22 '18 14:05 jimmykane

@amcharts Sorry to "nag" but just trying to extract some info.

Will this be fixed soonish. Its ok if you say it will take time, I can maybe then perhaps check for a workarround.

jimmykane avatar Jun 07 '18 10:06 jimmykane

New comment from Zendesk by Anthony Piris on ticket 34272. (replying here will automatically notify amCharts support agent)

Hi there.

My apologies for the delayed response. A basic fix was rolled into our latest release 3.21.13 to prevent the error from occuring, however the legend won't format the duration graph value correctly until the graph is toggled back on for the first time.

Again, my apologies for the delay. Let me know if you're still having trouble after upgrading.

Best,

Anthony Piris amCharts

amcharts avatar Jun 07 '18 10:06 amcharts