You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@echarts.apache.org by an...@icloud.com.INVALID on 2022/11/28 14:30:14 UTC

Area Stack Chart

Hello there fellow colleagues developers.

Since I have troubles finding out the proper way to implement stack on area stack chart or bar stack chart I am writing to you guys for some guidance or tip as I have not found what I need on your GH page, neither in API reference. So my goal is to make a stack chart either area chart or bar chart. The problem I am getting is that for xAxis I need type: ‘time’. To be precise I need to show FROM and TO from a date and then the value. If the from and to were to be the same then I should stack it on the top, if not then show properly  with barWidth changed due to different timestamps. So, for example I need to stack it on the top if the value is to be 100, the second is 300, then my chart should show first 100, then additional 300(400 in total), if the from and to dates are the same..
As shown on bellow picture, there is stacked data on bar charts, but not the ones that I need. It does so that if I have values around timestamp as in this case, first element in array is 11:30AM then the values are 130 and 230, instead of me wanted to show (130 and then 360) it shows initial values.. Is there any was I could get around over this. What would you recommend for date from and to intervals? I would be more then thankful for any help or guidance..


Part of the code initialising values..


    this.chartSeries = [
      {
        name: this.translateService.instant('ASSETS.RESERVATIONS.POSITIVE_VALUE'),
        type: 'bar',
        emphasis: {
          focus: 'series'
        },
        stack: 'Total',
        itemStyle: {
          color: 'rgba(255, 0, 0, 0.2)'
        },
        data: this.positiveValues,
      },
      {
        name: this.translateService.instant('ASSETS.RESERVATIONS.NEGATIVE_VALUE'),
        type: 'bar',
        itemStyle: {
          color: 'rgba(0, 255, 0, 0.25)'
        },
        stack: 'Total',
        emphasis: {
          focus: 'series'
        },
        data: this.negativeValues,
      }
    ];
    this.chartOptions = {
      grid: {
        top: 50,
        bottom: 90,
        right: 5,
        left: 80
      },
      legend: {
        data: [
          this.translateService.instant('ASSETS.RESERVATIONS.POSITIVE_VALUE'),
          this.translateService.instant('ASSETS.RESERVATIONS.NEGATIVE_VALUE'),
        ]
      },
      toolbox: {
        orient: 'vertical',
        top: 0,
        left: 50,
        feature: {
          restore: {
            show: false
          },
          dataZoom: {
            yAxisIndex: false,
            icon: {
              zoom: "path://",
              back: "path://"
            }
          }
        }
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'cross',
          label: {
            backgroundColor: '#6a7985'
          }
        },
        formatter: (val) => {
          console.log('value on formatter toggle: ',val);
          if (!Array.isArray(val) || val.length === 0) {
            return "";
          }
          let template = "";
          let templateUpdatedAt = "";
          if (Array.isArray(val[0].data) && val[0].data.length > 0) {
            template += `<div>${time.format(val[0].data[0], "{dd}.{MM}.{yyyy} {HH}:{mm}:{ss}", false)} - </div>`;
            // template += `<div>${time.format(this.chartDataTo[val["dataIndex"]], "{dd}.{MM}.{yyyy} {HH}:{mm}:{ss}", false)}</div>`;
            // use this.chartDataTo to find element of arraz bz index...
            // template += this.chartDataTo.forEach((item) => {console.log(item);`<div>${time.format(item, "{dd}.{MM}.{yyyy} {HH}:{mm}:{ss}", false)}</div>`});
            // templateUpdatedAt += `<div class="mt-1">${
            //   this.translateService.instant("SHARED.UPDATED_AT")
            // }: <span class="ps-2 float-end">${time.format(
            //   this.chartDataUpdatedAt[val[0].data[0]],
            //   "{dd}.{MM}.{yyyy} {HH}:{mm}:{ss}",
            //   false
            // )}</span></div>`;
          }
          template += val.map((params) =>
          Array.isArray(params.data) && params.data.length > 1 ?
            `<div>${params.marker ?? ""} ${params.seriesName ?? ""}
              <span style="float:right"> \u00A0 ${params.data[1]} EUR/MWh</span>
             </div>` : ""
          )
          .join("");
          template += this.chartLegendValues.map((value, index) =>
            index < 4 ?
              `<div>${this.chartLegendTranslations[index] ?? ""}
                <span style="float:right"> \u00A0 ${value[index] ?? ""} EUR/MWh</span>
               </div>` : 
              `<div>${this.chartLegendTranslations[index] ?? ""}
                <span style="float:right"> \u00A0 ${value[index] ?? ""}</span>
               </div>`
            )
            .join("");
          return template + templateUpdatedAt;
        }
      },
      xAxis: {
        type: 'time',
        name: this.translateService.instant('IOT.TIME'),
        nameGap: 75,
        boundaryGap: false,
        nameLocation: 'middle',
        axisLabel: {
          rotate: 40,
          formatter: (val) => time.format(val, '{HH}:{mm}', false)
        }
      },
      yAxis: {
        type: 'value',
        name: this.translateService.instant('ASSETS.RESERVATIONS.Y_AXIS'),
        nameLocation: 'middle',
        nameGap: 50,
        scale: false,
        boundaryGap: ['2%', '2%'],
        splitArea: {
          show: true
        }
      },
      series: []
    };

Re: Area Stack Chart

Posted by Ovilia <ov...@gmail.com>.
Hi, here is a demo:

https://echarts.apache.org/examples/zh/editor.html?c=line-simple&code=DYUwLgBGCWC2IBECGYkQLwQNoCgLYDsQB3CZMEACgHIAmABltoFp6BGVtie-gLh_71qASgA0ENgF1ReQiTIoqdRi3adubQYJHipM_FiKlyShk06ta3PgJ46J02YfkmaZ1R3oBmbrS12xCFpHSQBuHBwAYwB7AgBnSAAjaHiMCABvAF9wnAAzaIAnCEpQSGg0-lCIcoAeKDhEFCQAOlACAHMwAAsqgGpe6GEM2Rj4yAATNJh4ciQsaDCR2ISIccU08ax6SWb28AAxAFdgYABNECQCyiHeiGpmaghbyk3t3fAAWVju66eJG7uDz-rx2ezArmE4Xw0FyxWS8SwawokggAEJMARjsAhulZPh4XFEYoUb1MJspFCIJlZCBgHEQMN8PiUoSkSAUWSsBTZNTqVFlhMmmksItRitIihhYt8kUSuBqtUCBACTiRihmgAHQ5xLqUQaUpEtLU6ygE-aSSE4PnRDUwWJpXH4AAeAEEndA4rxGUywABPDUgL3UCUUdqFX3UfRMw1ekM8qO-t0er2On3-wN3ABuSGAhxA1HjsnpBWgIE92Dx3qZqyaUerfoDQeAKXzlep-EkVtCQA

Thanks

*Ovilia*


On Thu, Dec 1, 2022 at 6:15 PM <an...@icloud.com> wrote:

> Hello Olivia,
>
> Thank you for your answer. I managed to do it somehow with xAxis set on
> time, but I had to make a separate chartSeries for each object in an array
> of object and then to tweak settings. I am interested could you send me
> some example with a real usage of xAxis: category and data into bins as I
> couldn’t make it happen and therefore decided to stick with time on axis.
> Though now we cannot do overlapping time interval as we are needing it for
> price forecast of energy prices, which is our app. So, I would be more then
> grateful if you could link me to some example or part of documentation as I
> cannot find part of you mentioned, data from bins and tape: category for
> the logic to be fully controlled by the programmer.
>
> Thank You for your assistance,
>
> Andrej
>
> On 30 Nov 2022, at 04:51, Ovilia <ov...@gmail.com> wrote:
>
> Hi,
>
> I would suggest not using 'time' or 'value' type for xAxis because for
> value-like axes, the stack logic may not work as you may expect.
> You should use a 'category' xAxis and make the data into bins so the logic
> is fully controlled by yourself.
>
> Thanks
>
> *Ovilia*
>
>
> On Tue, Nov 29, 2022 at 6:53 AM <an...@icloud.com.invalid> wrote:
>
>> Hello there fellow colleagues developers.
>>
>> Since I have troubles finding out the proper way to implement stack on
>> area stack chart or bar stack chart I am writing to you guys for some
>> guidance or tip as I have not found what I need on your GH page, neither in
>> API reference. So my goal is to make a stack chart either area chart or bar
>> chart. The problem I am getting is that for xAxis I need type: ‘time’. To
>> be precise I need to show FROM and TO from a date and then the value. If
>> the from and to were to be the same then I should stack it on the top, if
>> not then show properly  with barWidth changed due to different timestamps.
>> So, for example I need to stack it on the top if the value is to be 100,
>> the second is 300, then my chart should show first 100, then additional
>> 300(400 in total), if the from and to dates are the same..
>> As shown on bellow picture, there is stacked data on bar charts, but not
>> the ones that I need. It does so that if I have values around timestamp as
>> in this case, first element in array is 11:30AM then the values are 130 and
>> 230, instead of me wanted to show (130 and then 360) it shows initial
>> values.. Is there any was I could get around over this. What would you
>> recommend for date from and to intervals? I would be more then thankful for
>> any help or guidance..
>> <Screenshot 2022-11-28 at 15.23.28.png>
>>
>> Part of the code initialising values..
>>
>>
>> this.chartSeries = [
>> {
>> name: this.translateService.instant('ASSETS.RESERVATIONS.POSITIVE_VALUE'
>> ),
>> type: 'bar',
>> emphasis: {
>> focus: 'series'
>> },
>> stack: 'Total',
>> itemStyle: {
>> color: 'rgba(255, 0, 0, 0.2)'
>> },
>> data: this.positiveValues,
>> },
>> {
>> name: this.translateService.instant('ASSETS.RESERVATIONS.NEGATIVE_VALUE'
>> ),
>> type: 'bar',
>> itemStyle: {
>> color: 'rgba(0, 255, 0, 0.25)'
>> },
>> stack: 'Total',
>> emphasis: {
>> focus: 'series'
>> },
>> data: this.negativeValues,
>> }
>> ];
>> this.chartOptions = {
>> grid: {
>> top: 50,
>> bottom: 90,
>> right: 5,
>> left: 80
>> },
>> legend: {
>> data: [
>> this.translateService.instant('ASSETS.RESERVATIONS.POSITIVE_VALUE'),
>> this.translateService.instant('ASSETS.RESERVATIONS.NEGATIVE_VALUE'),
>> ]
>> },
>> toolbox: {
>> orient: 'vertical',
>> top: 0,
>> left: 50,
>> feature: {
>> restore: {
>> show: false
>> },
>> dataZoom: {
>> yAxisIndex: false,
>> icon: {
>> zoom: "path://",
>> back: "path://"
>> }
>> }
>> }
>> },
>> tooltip: {
>> trigger: 'axis',
>> axisPointer: {
>> type: 'cross',
>> label: {
>> backgroundColor: '#6a7985'
>> }
>> },
>> formatter: (val) => {
>> console.log('value on formatter toggle: ',val);
>> if (!Array.isArray(val) || val.length === 0) {
>> return "";
>> }
>> let template = "";
>> let templateUpdatedAt = "";
>> if (Array.isArray(val[0].data) && val[0].data.length > 0) {
>> template += `<div>${time.format(val[0].data[0], "{dd}.{MM}.{yyyy}
>> {HH}:{mm}:{ss}", false)} - </div>`;
>> // template += `<div>${time.format(this.chartDataTo[val["dataIndex"]],
>> "{dd}.{MM}.{yyyy} {HH}:{mm}:{ss}", false)}</div>`;
>> // use this.chartDataTo to find element of arraz bz index...
>> // template += this.chartDataTo.forEach((item) =>
>> {console.log(item);`<div>${time.format(item, "{dd}.{MM}.{yyyy}
>> {HH}:{mm}:{ss}", false)}</div>`});
>> // templateUpdatedAt += `<div class="mt-1">${
>> // this.translateService.instant("SHARED.UPDATED_AT")
>> // }: <span class="ps-2 float-end">${time.format(
>> // this.chartDataUpdatedAt[val[0].data[0]],
>> // "{dd}.{MM}.{yyyy} {HH}:{mm}:{ss}",
>> // false
>> // )}</span></div>`;
>> }
>> template += val.map((params) =>
>> Array.isArray(params.data) && params.data.length > 1 ?
>> `<div>${params.marker ?? ""} ${params.seriesName ?? ""}
>> <span style="float:right"> \u00A0 ${params.data[1]} EUR/MWh</span>
>> </div>` : ""
>> )
>> .join("");
>> template += this.chartLegendValues.map((value, index) =>
>> index < 4 ?
>> `<div>${this.chartLegendTranslations[index] ?? ""}
>> <span style="float:right"> \u00A0 ${value[index] ?? ""} EUR/MWh</span>
>> </div>` :
>> `<div>${this.chartLegendTranslations[index] ?? ""}
>> <span style="float:right"> \u00A0 ${value[index] ?? ""}</span>
>> </div>`
>> )
>> .join("");
>> return template + templateUpdatedAt;
>> }
>> },
>> xAxis: {
>> type: 'time',
>> name: this.translateService.instant('IOT.TIME'),
>> nameGap: 75,
>> boundaryGap: false,
>> nameLocation: 'middle',
>> axisLabel: {
>> rotate: 40,
>> formatter: (val) => time.format(val, '{HH}:{mm}', false)
>> }
>> },
>> yAxis: {
>> type: 'value',
>> name: this.translateService.instant('ASSETS.RESERVATIONS.Y_AXIS'),
>> nameLocation: 'middle',
>> nameGap: 50,
>> scale: false,
>> boundaryGap: ['2%', '2%'],
>> splitArea: {
>> show: true
>> }
>> },
>> series: []
>> };
>>
>
>

Re: Area Stack Chart

Posted by Ovilia <ov...@gmail.com>.
Hi,

I would suggest not using 'time' or 'value' type for xAxis because for
value-like axes, the stack logic may not work as you may expect.
You should use a 'category' xAxis and make the data into bins so the logic
is fully controlled by yourself.

Thanks

*Ovilia*


On Tue, Nov 29, 2022 at 6:53 AM <an...@icloud.com.invalid> wrote:

> Hello there fellow colleagues developers.
>
> Since I have troubles finding out the proper way to implement stack on
> area stack chart or bar stack chart I am writing to you guys for some
> guidance or tip as I have not found what I need on your GH page, neither in
> API reference. So my goal is to make a stack chart either area chart or bar
> chart. The problem I am getting is that for xAxis I need type: ‘time’. To
> be precise I need to show FROM and TO from a date and then the value. If
> the from and to were to be the same then I should stack it on the top, if
> not then show properly  with barWidth changed due to different timestamps.
> So, for example I need to stack it on the top if the value is to be 100,
> the second is 300, then my chart should show first 100, then additional
> 300(400 in total), if the from and to dates are the same..
> As shown on bellow picture, there is stacked data on bar charts, but not
> the ones that I need. It does so that if I have values around timestamp as
> in this case, first element in array is 11:30AM then the values are 130 and
> 230, instead of me wanted to show (130 and then 360) it shows initial
> values.. Is there any was I could get around over this. What would you
> recommend for date from and to intervals? I would be more then thankful for
> any help or guidance..
> [image: Screenshot 2022-11-28 at 15.23.28.png]
>
> Part of the code initialising values..
>
>
> this.chartSeries = [
> {
> name: this.translateService.instant('ASSETS.RESERVATIONS.POSITIVE_VALUE'),
> type: 'bar',
> emphasis: {
> focus: 'series'
> },
> stack: 'Total',
> itemStyle: {
> color: 'rgba(255, 0, 0, 0.2)'
> },
> data: this.positiveValues,
> },
> {
> name: this.translateService.instant('ASSETS.RESERVATIONS.NEGATIVE_VALUE'),
> type: 'bar',
> itemStyle: {
> color: 'rgba(0, 255, 0, 0.25)'
> },
> stack: 'Total',
> emphasis: {
> focus: 'series'
> },
> data: this.negativeValues,
> }
> ];
> this.chartOptions = {
> grid: {
> top: 50,
> bottom: 90,
> right: 5,
> left: 80
> },
> legend: {
> data: [
> this.translateService.instant('ASSETS.RESERVATIONS.POSITIVE_VALUE'),
> this.translateService.instant('ASSETS.RESERVATIONS.NEGATIVE_VALUE'),
> ]
> },
> toolbox: {
> orient: 'vertical',
> top: 0,
> left: 50,
> feature: {
> restore: {
> show: false
> },
> dataZoom: {
> yAxisIndex: false,
> icon: {
> zoom: "path://",
> back: "path://"
> }
> }
> }
> },
> tooltip: {
> trigger: 'axis',
> axisPointer: {
> type: 'cross',
> label: {
> backgroundColor: '#6a7985'
> }
> },
> formatter: (val) => {
> console.log('value on formatter toggle: ',val);
> if (!Array.isArray(val) || val.length === 0) {
> return "";
> }
> let template = "";
> let templateUpdatedAt = "";
> if (Array.isArray(val[0].data) && val[0].data.length > 0) {
> template += `<div>${time.format(val[0].data[0], "{dd}.{MM}.{yyyy}
> {HH}:{mm}:{ss}", false)} - </div>`;
> // template += `<div>${time.format(this.chartDataTo[val["dataIndex"]],
> "{dd}.{MM}.{yyyy} {HH}:{mm}:{ss}", false)}</div>`;
> // use this.chartDataTo to find element of arraz bz index...
> // template += this.chartDataTo.forEach((item) =>
> {console.log(item);`<div>${time.format(item, "{dd}.{MM}.{yyyy}
> {HH}:{mm}:{ss}", false)}</div>`});
> // templateUpdatedAt += `<div class="mt-1">${
> // this.translateService.instant("SHARED.UPDATED_AT")
> // }: <span class="ps-2 float-end">${time.format(
> // this.chartDataUpdatedAt[val[0].data[0]],
> // "{dd}.{MM}.{yyyy} {HH}:{mm}:{ss}",
> // false
> // )}</span></div>`;
> }
> template += val.map((params) =>
> Array.isArray(params.data) && params.data.length > 1 ?
> `<div>${params.marker ?? ""} ${params.seriesName ?? ""}
> <span style="float:right"> \u00A0 ${params.data[1]} EUR/MWh</span>
> </div>` : ""
> )
> .join("");
> template += this.chartLegendValues.map((value, index) =>
> index < 4 ?
> `<div>${this.chartLegendTranslations[index] ?? ""}
> <span style="float:right"> \u00A0 ${value[index] ?? ""} EUR/MWh</span>
> </div>` :
> `<div>${this.chartLegendTranslations[index] ?? ""}
> <span style="float:right"> \u00A0 ${value[index] ?? ""}</span>
> </div>`
> )
> .join("");
> return template + templateUpdatedAt;
> }
> },
> xAxis: {
> type: 'time',
> name: this.translateService.instant('IOT.TIME'),
> nameGap: 75,
> boundaryGap: false,
> nameLocation: 'middle',
> axisLabel: {
> rotate: 40,
> formatter: (val) => time.format(val, '{HH}:{mm}', false)
> }
> },
> yAxis: {
> type: 'value',
> name: this.translateService.instant('ASSETS.RESERVATIONS.Y_AXIS'),
> nameLocation: 'middle',
> nameGap: 50,
> scale: false,
> boundaryGap: ['2%', '2%'],
> splitArea: {
> show: true
> }
> },
> series: []
> };
>