gevgeny / angular2-highcharts

:bar_chart: :chart_with_upwards_trend: Highcharts for your Angular project
MIT License
380 stars 113 forks source link

using .highcharts() to assign options #38

Closed cnlane closed 8 years ago

cnlane commented 8 years ago

I wanted to do something like http://www.highcharts.com/demo/synchronized-charts. While I had my npm compiler running and listening for file changes (npm start which is “npm run tsc:w” and “npm run lite”), everything works well (with following errors ... but works great). However, when I restart my “npm start” and it goes through the compiler again, I get

[0] app/station-dashboard.component.ts(249,10): error TS2345: Argument of type ' { chart: { marginLeft: number; zoomType: string; spacingTop: number; spacingBott om: number; }; ti...' is not assignable to parameter of type 'HighchartsOptions' . [0] Types of property 'series' are incompatible. [0] Type '{ data: any; name: any; color: any; fillOpacity: number; tooltip: { valueSuffix: string; }; }[]' is not assignable to type 'HighchartsIndividualSe riesOptions[]'. [0] Type '{ data: any; name: any; color: any; fillOpacity: number; tooltip : { valueSuffix: string; }; }' is not assignable to type 'HighchartsIndividualSe riesOptions'. [0] Object literal may only specify known properties, and 'color' does n ot exist in type 'HighchartsIndividualSeriesOptions'.

It’s not liking where I say :

$('<chart class="stationChart col-md-12">') .appendTo('#container') .highcharts({ chart: { marginLeft: 80, // Keep all charts left aligned zoomType: 'x', spacingTop: 20, spacingBottom: 20 },

How can I make it so I can call .highcharts ( ) and pass in options there?

LithMage commented 8 years ago

EDIT: Nevermind... it was enough to restart VS Code (serves me right for not restarting in a long while).

Now as for @cnlane . Have you tried to see if any of examples works in your project? As this seems like a problem with not loading Highcharts typings

cnlane commented 8 years ago

When I follow the examples from angular2-highcharts, they do work. But I'm trying to assign the options using .highcharts({ ... and that is where I get errors.

LithMage commented 8 years ago

Hmm but why are you doing it that way? Its not the angular way. Can you make some example? So we can atleast have idea what you trying to achieve.

cnlane commented 8 years ago

I'm trying to create multiple charts using the same subroutine so I can't just say options={ chart: ...} because each chart has it's own set of options created using parameters passed into my subroutine.

LithMage commented 8 years ago

So you make a option class ;) and use it in your app as optionA = new HCOptions({whatever you need});

Once i get home i will share some code i am using for similar purpose.

cnlane commented 8 years ago

Thank you!

gevgeny commented 8 years ago

@cnlane Btw, there is easier approach that can help achieve similar behaviour but with one HC instance. You can set in options multiple Y-axes placed with different Y offset and bind different series to the necessary axe. See an example http://jsfiddle.net/VgCQV/

cnlane commented 8 years ago

That looks awesome and very much like what I want to do ... but can I say chart = new Highcharts.StockChart({ in an angular2 app? I thought that wasn't the "angular way"?

gevgeny commented 8 years ago

You don't need to create a chart like in the example. Just look how the options is specified.

LithMage commented 8 years ago

He showed you how to make it without angular :) just plain JavaScript, Highcharts and jQuery for that json call :)

cnlane commented 8 years ago

I understand. I appreciate seeing how the options are specified for multiple charts. So thank you for that.

I am really struggling with how to use high charts in an angular way.

cnlane commented 8 years ago

Do I really need to create an options class and include every option I wish to specify?

gevgeny commented 8 years ago

http://plnkr.co/edit/dyXMsYg5go4pHOlYPPcv?p=preview

LithMage commented 8 years ago

this is how i do stuff (albeit its heavily simplified from my original code).

http://plnkr.co/edit/FBsPL08iykaPDeP7Ml7j?p=preview

hc.options.ts has default Highcharts options and constructor just adds any modifications i might send its way.

hope its not too cluttered to be of no use :)

cnlane commented 8 years ago

All your examples are super helpful. Thank you so much! Part of what is complicating my life is my data is being read in through http service and data is not immediately available (takes 1 second). That's why I was trying to use the .highcharts() method to create that chart. I would have data by then...

LithMage commented 8 years ago

for that you use Observables https://angular.io/docs/ts/latest/guide/server-communication.html#!#rxjs

and once data arives use Highcharts api to set data. http://api.highcharts.com/highcharts#Chart i personally like to delete all series and create them anew with fresh data (but its mostly because i am synchronizing meteorogical data from diferent sources and one chart has 3 different series). If you have 1 serie just use http://api.highcharts.com/highcharts#Series.setData (if you saved chart instance onto chart variable it will be this.chart.series[0].setData(new data array);

cnlane commented 8 years ago

I can't tell you how may hours I have spent reading about Observables, that exact page you mentioned. I really did have this all working ... just not in a compiler happy way.

LithMage commented 8 years ago

in your service file have

public getData(dataUrl: string) { // returns Observable
    return this.http.get(dataUrl)
      .map((response) => response.json() || {})
      .catch(this.handleError);
  }
private handleError(error: any) {
    let errMsg = (error.message) ? error.message :
      error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    console.error(errMsg); // log to console instead
    return Observable.throw(errMsg);
  }

its passive until something subscribes to it

this.chart.showLoading();
      this.getData('url to data').subscribe(
        data => {
          this.chart.setTitle({ text: 'OH lookie here is data' });
          this.chart.hideLoading();
// this here can be altered to whatever you need to do with data
// like parsing to fit your needs and stuff
          this.removeAllSeries(this.chart, false); // as i said i have complex series so i need to remove em all
          this.chart.addSeries(
            {
      id: 'dataID',
      name: 'Data1',
      data: someDataArray, // this here goes my parsed data from http,
      type: 'spline',
      zIndex: 1,
      color: '#FF3333',
      negativeColor: '#48AFE8'
    }
          );
          // redraw after all changes has been done
          this.chart.redraw();
        },
        error => { console.log(error);
 this.chart.showLoading(error.message || 'UNKNOWN ERROR');
 }
      );
cnlane commented 8 years ago

That is basically what I am doing, except I'm not calling this.chart.addSeries, I'm trying to add it to my options:

this.combinedChartOptions = { chart: { marginLeft: 80, // Keep all charts left aligned zoomType: 'x', spacingTop: 20, spacingBottom: 20 }, title: { text: "Station Information", align: 'left', margin: 0, x: 30 }, credits: { enabled: false }, legend: { enabled: false }, xAxis: { crosshair: true, events: { //setExtremes: this.syncExtremes } }, labels: { formatter: function() { var d = new Date(this.value); return d.toLocaleDateString(); // d.toUTCString() }, rotation: -45 }, yAxis: [], tooltip: { borderWidth: 0, pointFormat: '{point.y}', headerFormat: '{point.x:%l:%M%p}
', style: { fontSize: '18px' }, }, series: [] }

and then within subscribe: this.combinedChartOptions.yAxis.push( { title: { text: station.properties["point_type_units_plural"] }, height: 200, lineWidth: 2 }); this.combinedChartOptions.series.push( { data: tsData, color: dataLayer.color, fillOpacity: 0.3, tooltip: { valueSuffix: ' ' + station.properties["point_type_units_plural"] } });

So instead I should call this.chart.addSeries and ? for adding yAxis specs?

cnlane commented 8 years ago

It's working!!! Thank you so much. One small problem: I called chart.addAxis( { title: { text: station.properties["point_type_units_plural"] }, height: 200, lineWidth: 2 }, false, false);

and I'm getting an error: [0] app/station-dashboard.component.ts(266,9): error TS2345: Argument of type '{ title: { text: any; }; height: number; lineWidth: number; }' is not assignable to parameter of type 'HighchartsAxisOptions'. [0] Object literal may only specify known properties, and 'height' does not ex ist in type 'HighchartsAxisOptions'.

cnlane commented 8 years ago

And my labels formatter is being ignored... ;-(

LithMage commented 8 years ago

well there is no such variable height in Highcharts Axis object, you sure its not something else you need?

cnlane commented 8 years ago

I see that. But in Eugene's example http://jsfiddle.net/VgCQV/, it is used.

LithMage commented 8 years ago

ahh its Highstocks thing http://api.highcharts.com/highstock#yAxis.height sorry i dont have experience with that one.

cnlane commented 8 years ago

Oh! That slipped by me! Thank you! Right now my charts are stacked but not pretty. I think it is related to the height of each chart. I'll keep looking for the right option combinations. Thank you both so much for all your help!!!!

cnlane commented 8 years ago

Sorry ... one more question then ... can Highcharts (rather than Highstocks) have 2 or 3 charts with 1 XAxis like the previous example?

LithMage commented 8 years ago

you mean like synchronized charts? yea they can, http://www.highcharts.com/demo/synchronized-charts

cnlane commented 8 years ago

No. I had that and wanted a shared x axis... like http://plnkr.co/edit/dyXMsYg5go4pHOlYPPcv?p=preview but that seems to use height and top to separate the 2 charts. Right now, mine are on top of each other with both y axes side by side. I have feet (blue) and a second data type (inches) cyan. I want them with blue on its own y axis with cyan below with its own y axis and 1 shared x axis (date).

image

cnlane commented 8 years ago

Eugene - you shared http://plnkr.co/edit/dyXMsYg5go4pHOlYPPcv?p=preview. How are you able to specify "height" and "top" in your yAxis? When I do that, I get an error:

[0] app/station-dashboard.component.ts(260,9): error TS2345: Argument of type '{ title: { text: any; }; top: number; lineWidth: number; }' is not assignable to parameter of type 'HighchartsAxisOptions'. [0] Object literal may only specify known properties, and 'top' does not exist in type 'HighchartsAxisOptions'.

If I try height, I get the same error.

gevgeny commented 8 years ago

@sspilleman Try to set options: Object; rather than options: HighchartsOptions;

cnlane commented 8 years ago

I am defining options: Object; and then calling chart.addAxis( { title: { text: station.properties["point_type_units_plural"] }, //height: 100, //top: top_value, lineWidth: 2 }, false, false);

cnlane commented 8 years ago

If I define it initially, it's ok: this.combinedChartOptions = { chart: { marginLeft: 80, // Keep all charts left aligned zoomType: 'x', spacingTop: 20, spacingBottom: 20 }, title: { text: "Station Information", align: 'left', margin: 0, x: 30 },
xAxis: { crosshair: true, events: { //setExtremes: this.syncExtremes }, labels: { formatter: function() { var d = new Date(this.value); return d.toLocaleDateString(); // d.toUTCString() }, rotation: -45 }, offset: 10 }, yAxis: [ { title: { text: "feet" }, height: 100,
lineWidth: 2 }, { title: { text: "inches" }, height: 100, top: 300, lineWidth: 2 } ], etc...

But I don't know what my data might read in so I want to define it on the fly ... like previous comment. Any ideas? Thank you again for your ideas!!!!

mantukar commented 5 years ago

Hi, have any one done multiple series for high stock chart(high chart) . Data is reading from database with multiple columns. don't need any hard code . for series values.Please help .

huntxiao commented 3 years ago

image I want to create a stacked column chart, but I don't know why there is a redline below param renderTo,