apache / echarts

Apache ECharts is a powerful, interactive charting and data visualization library for browser
https://echarts.apache.org
Apache License 2.0
60.53k stars 19.61k forks source link

visualMap not working on chart but is in tooltip #18481

Open cscrum opened 1 year ago

cscrum commented 1 year ago

Version

4.9.0

Link to Minimal Reproduction

https://codepen.io/cscrum/pen/mdzdXNa

Steps to Reproduce

I'm creating a set of charts from an array of objects. Each chart has 5 series, 2 of which have an "Area" under them. I create a separate chart option for each object in the array. That all works, but I'm having difficulty getting the visual map to apply to the area under one of the series.

Current Behavior

I'm currently using echarts to create line graphs with 5 series, 2 of which have "areas" under them. I'm trying to create a visualMap on one of the series with the area and shade the area based on a third value (not x,y). If I remove the areaStyle, lineStyle, and itemStyles, I just get a red line for the series, but the tooltip shows a point with the visualMap applied. Code and sample images below.

`//profarray is an array of multiple sets of data to create several charts

let pcnt = 0; let xVals = []; profarray.forEach(function(profpt){ xVals.push(profpt.distance); terArr.push([profpt.distance,profpt.terrain,0]);

cltArr.push([profpt.distance,profpt.clutter,profpt.category]); fresArr.push([profpt.distance,profpt.freznel,0]); f60Arr.push([profpt.distance,profpt.freznel_60,0]); losArr.push([profpt.distance,profpt.los,0]); pcnt++; })

let echtopts: EChartsOption = { title: { show: true, text: ap.title, textStyle: {fontSize: 12} }, colors: ['#8B4513','#00ff00', '#0000ff', '#ff00ff', ap.color], tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985', } }, textStyle:{fontSize: 9} }, legend: { data: ['Terrain','Clutter', 'Fresnel', 'Fresnel60', 'LOS'], bottom: '3', testStyle: {fontSize: 9} }, grid: { left: 60, top: 20, right: 2, bottom: 90, containLabel: false }, xAxis: [ { type: 'category', name: 'Distance (km)', nameLocation: 'middle', nameGap: 25, //boundaryGap: false, //data: xVals } ], yAxis: [ { type: 'value', name: 'Elevation (ft)', nameLocation: 'middle', nameGap: 35, min: function(){ if (Math.min(...terArr) == 0){ return 0; }else{ return (Math.min(...terArr) - 10).toFixed(2); } } } ], visualMap: { type: 'piecewise', show: false, dimension: 2, seriesIndex: 0, pieces: [{ //trees gt:9, lte: 10, color: '#76A772' }, { //shrub gt:19, lte: 20, color: '#F6F598' }, { //grass gt:29, lte: 30, color: '#A0C731' }, { //crop gt: 39, lte: 40, color: '#E7F88E' }, { //built up gt:49, lte: 50, color: '#F37572' }, { //bare gt: 59, lte: 60, color: '#B4B4B4' }, { //snow gt: 69, lte: 70, color: '#F0F0F0' }, { //water gt: 79, lte: 80, color: '#0064C8' }, { //herbacious wet gt: 89, lte: 90, color: '#0096A0' }, { //mangrove gt: 94, lte: 95, color: '#5D9C58' }, { //moss gt: 99, lte: 100, color: '#F6D283' }

] }, series: [ { name: 'Clutter', type: 'line', lineStyle: {color: '#00ff00'}, areaStyle: {color:'#00ff00'}, itemStyle: {color:'#00ff00'}, showSymbol: false, data: cltArr }, { name: 'Terrain', type: 'line', lineStyle: {color: '#8B4513'}, areaStyle: {color:'#8B4513'}, itemStyle: {color:'#8B4513'}, colorBy: 'series', showSymbol: false, data: terArr }, { name: 'Fresnel', type: 'line', lineStyle: {color: '#0000ff'}, itemStyle: {color:'#0000ff'}, colorBy: 'series', showSymbol: false, data: fresArr }, { name: 'Fresnel60', type: 'line',

lineStyle: {color: '#ff00ff'}, itemStyle: {color:'#ff00ff'}, colorBy: 'series', showSymbol: false, data: f60Arr }, { name: 'LOS', type: 'line', lineStyle: {color: ap.color}, itemStyle: {color: ap.color}, colorBy: 'series', showSymbol: false, data: losArr } ] };

ap["echtdata"] = echtopts;

This is the chart I get when I specify the styles on the first series:

image

Here it is with the tooltip showing. Notice the color of the dot for the "Clutter" in the tooltip has the visualMap color in it. That is great, but I want them to show up in the area under the line as well.

image

If I comment all the styling from the first series (the Clutter series), this is what I get

image

Notice the line just goes to red, but the tooltip still shows the visualMap color. If I just add areaStyle: {} I get this:

image

Am I missing something that should apply the visualMap to the actual chart?

Expected Behavior

What I would like to see is the area under the series be shaded with the colors set in the visualMap. It appears they are being applied to the series at least in how they are displayed in the tool tip, but just not showing up on the chart.

Environment

- OS: Windows10
- Browser: Chrome
- Framework: Angular 12

Any additional comments?

No response

helgasoft commented 1 year ago

not-a-bug Aaah, visualMap.type.piecewise is complicated, hopefully Demo Code will clear things up. The major problem as stated is "getting the visual map to apply to the area under one of the series". I think the best solution is to change xAxis.type to 'value' and RLE the pieces definitions from your data cltArr. image

cscrum commented 1 year ago

Sadly that did not work either. In your example you are using the wrong dimension. I need the 3rd column or dimension: 2. I tried to use this and modify the values in your lt, gt table, but it did not work

On Fri, Apr 7, 2023 at 2:14 PM helgasoft @.***> wrote:

not-a-bug Aaah, visualMap.type.piecewise is complicated, hopefully Demo Code https://echarts.apache.org/examples/en/editor.html?c=line-simple&code=PTAEENQZwW3Abe0CuAjKBTALqAFAMwEsAnKHYjAYwHtiATKASlH2OplFsIHNCA7BKDrgs4AFCV4WAILFioALygA2mNAqADADoNARgA0oXQFYAHAE4txgGyndAZg33jAJnvmALPcOOAuvrVNHRdDE3N7LQ9rE2sAdj1dWNjTWJ8Nf0DlbSdQ43NYrVMzY1i3WNc81NAPdID1LJ0PXPNLF11rc1MPWOsNazim6trM7ONQ3t1Cl3KU_tjEkKGM-uzrcY0PHWdPe1NTDtKxpbqgjSr2jWNC63tEnftY_NNDGuXT56Neq57zDXyk3QuGqLV4nBp_daWLwuFzmQG_UzTD6gkZaAyfXSTYy6S52Io46yDFErNHo9qYrTWFxdPotG6mbzHVGA8aAqweOy2MrGP5rJkkhysiJndzhDRtBlVYlBXSDckRewPDxeZzGbGxRl-MHaExCrQwjyJLpeFJpN4Ndqsya9LqApzTQ5m7Vo87RFwujRnYzKrpuJ3Mj7taL67E8lx9exReyLHHmnXmcYlRouMy-vIuKmhYYkmPWGxWDWuIptE3nbNBNqJyazNoim3OLNx_W57qRDOE_oeNWymPlhp-z7KrTmOLU3QMy56OV97RA8YPYec8wwxx_SON50p-fuzEjyOHHaBmf6vntalWfaPdweTp2Deo6a5Oz6s6AxL9FOMnlN6m5Hovtw82ScUv3SMRfAAbjEMRqAABywQhqD4RRQAAb0CAAPaQMMIKAAC4VECdR0PUUjQBALAAE9YIwAiAHJKBEDBuFoSi6JOMiBBgWjQDogARXDRD4SgMDwABrGBGHYojSK4jAABlqEYhCkPomBCDoOh4AwaSyPUOSAHFwFggiUxkgBfQI3ko7DcII1QyJIvSqJo-iADcEGQHSONk8BuPogBRbSPJU5CCCwKSfP0vyFKUkREL4NSNK07yZOi7ijJM0BnAsqyTkwYhCAwfDCMctLQDk-iAGF4GQLAsAwYhdOc6ieLo-B-FSvTQA6vgMAAZSo7SCNQ0AaHgWh6IAYk9fB8E9OjQHMqKIAocBBso4a0OW8qoAAC2oAB3frKJgVBqHgAj8AQTAVuEUQCMkGQ5Fy9Q3jc3DkAQABZYyRpkly2tgoqRMO3CutI_ajqum6MB86g6oAeXwAAlcA-G4HjRvGybeJmjQADECYWpafOAAAqdQZJAUBDtoMSoBYWhoFO874EZ3BYOofgsCYTg-HgSi8JkuhCG4vgoAS0yfOBqhivs8rRo82qeMcQwceIabpA0KqNV0RblvIsBHCUbhiHAKAoEV0Bla8gianVi7cboqaAtiAm9gCg3DBpmolEoNhYJkt4qbImnDr2jBkKwnCoC0QHQFw3jlOY1j2NAWWRMZugMCIPq6BYNgOHuyB-BzjDipFsWo8l1TQA0QxQBkzP5dKvTRu4BqCIbnqsGlsanc1vHtd125vaN7KNFN83LetzueMWKQCMFAeJqHl23Y90wvdJie_bGwO567oxGSXowqg1rWdb18eQEcI-eMSQwz63VfnamnppCSFxb-AHEH9MkcF-F9B7TQJg8EoP9d4gB5MHGS5NgAyWpmACOUdQAx1wvHVqidGZ0Vtt5DOINipCFzp1AurB2BCBEKXZCKN5IBSZsQOAWAq7i1roleuMsiElQcu3XuPFsiMm6qRS-w9r5j2gcbKeoAzYWytt1Dufd65bGfkonUgxREb3dp7X-Qx_aHwUTItRaJBhnx1B8TRU0R430kffQxndu5og-GY_UIC17TU_t_A26gQD_zIr4QIllzIQSAA will clear things up. The major problem as stated is "getting the visual map to apply to the area under one of the series". I think the best solution is to change xAxis.type to 'value' and RLE https://en.wikipedia.org/wiki/Run-length_encoding the pieces definitions from your data cltArr. [image: image] https://user-images.githubusercontent.com/13038071/230663602-ff600acb-8673-4038-b6f6-de784c232ebd.png

— Reply to this email directly, view it on GitHub https://github.com/apache/echarts/issues/18481#issuecomment-1500563664, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHA4QZG2ST3T5JP3M62Z7TXABRQNANCNFSM6AAAAAAWVUP7L4 . You are receiving this because you authored the thread.Message ID: @.***>

helgasoft commented 1 year ago

oops, the Share button ate my /*...*/ comments, didn't know that "feature". Here they are again:

    // when xAxis.type is 'category', pieces are defined from data indexes
    dimension: 0,
    pieces: [
      { gte: 0, lt: 2,  color: '#A0C731' }, // 30= grass
      { gte: 2, lt: 13, color: '#E7F88E' }, // 40= crop
      { gt: 13, lt: 18, color: '#A0C731' }, //30
      { gt: 18, lt: 26, color: '#76A772' }  //10
    ],

    // when pieces defined by value, only line symbols (points) are styled
    // set "showSymbol: true"  to see
    dimension: 2,
    pieces: [
      { value: 30, color: '#A0C731' }, // 30= grass
      { value: 40, color: '#E7F88E' }, // 40= crop
      { value: 10, color: '#76A772' }  //10
    ],

I do not think there are other options of defining pieces in your case, so the one in Demo ought to be the best one.

helgasoft commented 1 year ago

Done with xAxis.type='category' after all, RLE is easier with data indexes. image

// ... add profarray here from https://codepen.io/cscrum/pen/mdzdXNa
//rcltArr = encode(cltArr);

color = ['0', '#76A772', '#F6F598', '#A0C731', '#E7F88E', '#F37572', '#B4B4B4', '#F0F0F0', '#0064C8', '#0096A0' ] 
// implement run length encoding (RLE)
prev = cltArr[0][2]; 
pc = [];
count = 1;
cltArr.map((m) => {
    // Count occurrences of dim 2
    if (m[2] == prev) {
      count++;
    } else {
      pc.push({ lt: count, color: color[prev/10] });
      prev = m[2];
    }
});
//console.log(pc);

var option = {
  title: {
    show: true,
    text: 'Test',
    textStyle: { fontSize: 12 }
  },
  colors: ['#00ff00', '#8B4513', '#0000ff', '#ff00ff', apcolor],
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross',
      label: {
        backgroundColor: '#6a7985'
      }
    },
    textStyle: { fontSize: 9 }
  },
  legend: {
    data: ['Terrain', 'Clutter', 'Fresnel', 'Fresnel60', 'LOS'],
    bottom: '3',
    testStyle: { fontSize: 9 }
  },
  grid: {
    left: 60,
    top: 20,
    right: 2,
    bottom: 90,
    containLabel: false
  },
  dataZoom: {type: 'inside' },
  xAxis: [
    {
      type: 'category', //'value',
      name: 'Distance (km)',
      nameLocation: 'middle',
      nameGap: 25
      //boundaryGap: false,
      //data: xVals
    }
  ],
  yAxis: [
    {
      type: 'value',
      name: 'Elevation (ft)',
      nameLocation: 'middle',
      nameGap: 35, 
      scale: true,
    }
  ],
  visualMap: {
    type: 'piecewise',
    show: false,
    dimension: 0,
    seriesIndex: 0,
    pieces: pc,
    outOfRange: { color: '#00FF00' }
  },
  series: [
    {
      name: 'Clutter',
      type: 'line',
      areaStyle: {},
      showSymbol: false,
      data: cltArr
    },
    {
      name: 'Terrain',
      type: 'line',
      lineStyle: { color: '#95743D' },
      areaStyle: { color: '#95743D', opacity: 100 },
      itemStyle: { color: '#95743D' },
      colorBy: 'series',
      showSymbol: false,
      data: terArr
    },
    {
      name: 'Fresnel',
      type: 'line',
      lineStyle: { color: '#0000ff' },
      itemStyle: { color: '#0000ff' },
      colorBy: 'series',
      showSymbol: false,
      data: fresArr
    },
    {
      name: 'Fresnel60',
      type: 'line',
      lineStyle: { color: '#ff00ff' },
      itemStyle: { color: '#ff00ff' },
      colorBy: 'series',
      showSymbol: false,
      data: f60Arr
    },
    {
      name: 'LOS',
      type: 'line',
      lineStyle: { color: apcolor },
      itemStyle: { color: 'apcolor' },
      colorBy: 'series',
      showSymbol: false,
      data: losArr
    }
  ]
};
cscrum commented 1 year ago

This looks great, except that it seems to stop shading near the end for some reason. In my example code, I added a switch case because the categories aren't necessarily equal divisions by 10, and it's working, but in my full example array, the colors stop working at 12.94 km even though there is no transition there. If I print the colors it is writing to the console, they are there, but not in the chart itself. See the code changes, and thanks for your help.

On Sun, Apr 9, 2023 at 3:37 PM helgasoft @.***> wrote:

Done with xAxis.type='category' after all, RLE is easier with data indexes. [image: image] https://user-images.githubusercontent.com/13038071/230794887-f5adb5e4-4462-44f3-9517-9e60bde3a3b8.png

// ... add profarray here from https://codepen.io/cscrum/pen/mdzdXNa //rcltArr = encode(cltArr);

color = ['0', '#76A772', '#F6F598', '#A0C731', '#E7F88E', '#F37572', '#B4B4B4', '#F0F0F0', '#0064C8', '#0096A0' ] // implement run length encoding (RLE) prev = cltArr[0][2]; pc = []; count = 1; cltArr.map((m) => { // Count occurrences of dim 2 if (m[2] == prev) { count++; } else { pc.push({ lt: count, color: color[prev/10] }); prev = m[2]; } }); //console.log(pc);

var option = { title: { show: true, text: 'Test', textStyle: { fontSize: 12 } }, colors: ['#00ff00', '#8B4513', '#0000ff', '#ff00ff', apcolor], tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } }, textStyle: { fontSize: 9 } }, legend: { data: ['Terrain', 'Clutter', 'Fresnel', 'Fresnel60', 'LOS'], bottom: '3', testStyle: { fontSize: 9 } }, grid: { left: 60, top: 20, right: 2, bottom: 90, containLabel: false }, dataZoom: {type: 'inside' }, xAxis: [ { type: 'category', //'value', name: 'Distance (km)', nameLocation: 'middle', nameGap: 25 //boundaryGap: false, //data: xVals } ], yAxis: [ { type: 'value', name: 'Elevation (ft)', nameLocation: 'middle', nameGap: 35, scale: true, } ], visualMap: { type: 'piecewise', show: false, dimension: 0, seriesIndex: 0, pieces: pc, outOfRange: { color: '#00FF00' } }, series: [ { name: 'Clutter', type: 'line', areaStyle: {}, showSymbol: false, data: cltArr }, { name: 'Terrain', type: 'line', lineStyle: { color: '#95743D' }, areaStyle: { color: '#95743D', opacity: 100 }, itemStyle: { color: '#95743D' }, colorBy: 'series', showSymbol: false, data: terArr }, { name: 'Fresnel', type: 'line', lineStyle: { color: '#0000ff' }, itemStyle: { color: '#0000ff' }, colorBy: 'series', showSymbol: false, data: fresArr }, { name: 'Fresnel60', type: 'line', lineStyle: { color: '#ff00ff' }, itemStyle: { color: '#ff00ff' }, colorBy: 'series', showSymbol: false, data: f60Arr }, { name: 'LOS', type: 'line', lineStyle: { color: apcolor }, itemStyle: { color: 'apcolor' }, colorBy: 'series', showSymbol: false, data: losArr } ] };

— Reply to this email directly, view it on GitHub https://github.com/apache/echarts/issues/18481#issuecomment-1501208432, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHA4Q7J4P4H7NBSWO2QKWTXAMM2JANCNFSM6AAAAAAWVUP7L4 . You are receiving this because you authored the thread.Message ID: @.***>

cscrum commented 1 year ago

Figured it out. You weren't incrementing the count when adding the color so it was coming up short. After I added the count there it looks better. Also, the color should have been the previous color, not the current one so I added a var to track the previous color as well. Thanks for all the help.

On Mon, Apr 10, 2023 at 9:25 AM Cameron Crum @.***> wrote:

This looks great, except that it seems to stop shading near the end for some reason. In my example code, I added a switch case because the categories aren't necessarily equal divisions by 10, and it's working, but in my full example array, the colors stop working at 12.94 km even though there is no transition there. If I print the colors it is writing to the console, they are there, but not in the chart itself. See the code changes, and thanks for your help.

On Sun, Apr 9, 2023 at 3:37 PM helgasoft @.***> wrote:

Done with xAxis.type='category' after all, RLE is easier with data indexes. [image: image] https://user-images.githubusercontent.com/13038071/230794887-f5adb5e4-4462-44f3-9517-9e60bde3a3b8.png

// ... add profarray here from https://codepen.io/cscrum/pen/mdzdXNa //rcltArr = encode(cltArr);

color = ['0', '#76A772', '#F6F598', '#A0C731', '#E7F88E', '#F37572', '#B4B4B4', '#F0F0F0', '#0064C8', '#0096A0' ] // implement run length encoding (RLE) prev = cltArr[0][2]; pc = []; count = 1; cltArr.map((m) => { // Count occurrences of dim 2 if (m[2] == prev) { count++; } else { pc.push({ lt: count, color: color[prev/10] }); prev = m[2]; } }); //console.log(pc);

var option = { title: { show: true, text: 'Test', textStyle: { fontSize: 12 } }, colors: ['#00ff00', '#8B4513', '#0000ff', '#ff00ff', apcolor], tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } }, textStyle: { fontSize: 9 } }, legend: { data: ['Terrain', 'Clutter', 'Fresnel', 'Fresnel60', 'LOS'], bottom: '3', testStyle: { fontSize: 9 } }, grid: { left: 60, top: 20, right: 2, bottom: 90, containLabel: false }, dataZoom: {type: 'inside' }, xAxis: [ { type: 'category', //'value', name: 'Distance (km)', nameLocation: 'middle', nameGap: 25 //boundaryGap: false, //data: xVals } ], yAxis: [ { type: 'value', name: 'Elevation (ft)', nameLocation: 'middle', nameGap: 35, scale: true, } ], visualMap: { type: 'piecewise', show: false, dimension: 0, seriesIndex: 0, pieces: pc, outOfRange: { color: '#00FF00' } }, series: [ { name: 'Clutter', type: 'line', areaStyle: {}, showSymbol: false, data: cltArr }, { name: 'Terrain', type: 'line', lineStyle: { color: '#95743D' }, areaStyle: { color: '#95743D', opacity: 100 }, itemStyle: { color: '#95743D' }, colorBy: 'series', showSymbol: false, data: terArr }, { name: 'Fresnel', type: 'line', lineStyle: { color: '#0000ff' }, itemStyle: { color: '#0000ff' }, colorBy: 'series', showSymbol: false, data: fresArr }, { name: 'Fresnel60', type: 'line', lineStyle: { color: '#ff00ff' }, itemStyle: { color: '#ff00ff' }, colorBy: 'series', showSymbol: false, data: f60Arr }, { name: 'LOS', type: 'line', lineStyle: { color: apcolor }, itemStyle: { color: 'apcolor' }, colorBy: 'series', showSymbol: false, data: losArr } ] };

— Reply to this email directly, view it on GitHub https://github.com/apache/echarts/issues/18481#issuecomment-1501208432, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHA4Q7J4P4H7NBSWO2QKWTXAMM2JANCNFSM6AAAAAAWVUP7L4 . You are receiving this because you authored the thread.Message ID: @.***>

helgasoft commented 1 year ago

oh, we were working simultaneously :-) Here is my final code:

// implement run length encoding (RLE)
function doColor(code) {
  switch (code) {
    case 10:
      color = '#76A772';
      break;
    case 20:
      color = '#F6F598';
      break;
    case 30:
      color = '#A0C731';
      break;
    case 40:
      color = '#E7F88E';
      break;
    case 50:
      color = '#F37572';
      break;
    case 60:
      color = '#B4B4B4';
      break;
    case 70:
      color = '#F0F0F0';
      break;
    case 80:
      color = '#0064C8';
      break;
    case 90:
      color = '#0096A0';
      break;
    case 95:
      color = '#5D9C58';
      break;
    case 100:
      color = '#F6D283';
      break;
  }
  return color;
}
prev = cltArr[0][2]; 
pc = [];
count = 0;
cltArr.map((m) => {
    // Count occurrences of dim 2
    if (m[2] != prev) {
      pc.push({ lt: count, color: doColor(prev) });
      prev = m[2];
    }
    count++;
});
// not forget the last stripe
pc.push({ lt: count, color: doColor(prev) });

NB: please close issue if problem solved.