ZK Zhao
ZK Zhao

Reputation: 21533

How to reuse part of a data structure?

For example, I need to define an option like this:

option = {
    series: [{
        name:'Others',
        type: 'line',
        data: [23.9627, 26.4315, 29.917, 27.5934, 26.8672],
        symbol: 'none',
        itemStyle: {
            normal: {
                color: 'rgb(165,165,165)'
            }
        },
        lineStyle: {
            normal: {
                width: 5,
            }
        }
    }, {
        name:'Apple',
        type: 'line',
        data: [18.1535, 18.5892, 13.9419, 22.9461, 23.9627],
        symbol: 'none',
        itemStyle: {
            normal: {
                color: 'rgb(165,165,165)'
            }
        },
        lineStyle: {
            normal: {
                width: 5,
            }
        }
    },{
        name:'HTC',
        type: 'line',
        data: [8.7137, 10.4564, 10.166, 6.2448, 4.6473],
        symbol: 'none',
        itemStyle: {
            normal: {
                color: 'rgb(165,165,165)'
            }
        },
        lineStyle: {
            normal: {
                width: 5,
            }
        }
    }]
};

The problem is that

symbol: 'none',
        itemStyle: {
            normal: {
                color: 'rgb(165,165,165)'
            }
        },
        lineStyle: {
            normal: {
                width: 5,
            }
        }

is the same for all the series and is repeated 3 times.

I want to know if it is possible to extract it out, and make something like this?

defaullt_line_option ={
    symbol: 'none',
    itemStyle: {
        normal: {
            color: 'rgb(165,165,165)'
        }
    },
    lineStyle: {
        normal: {
            width: 5,
        }
    }
};

option = {
    series: [{
        name:'Others',
        type: 'line',
        data: [23.9627, 26.4315, 29.917, 27.5934, 26.8672],
        default_line_style,
    }, {
        name:'Apple',
        type: 'line',
        data: [18.1535, 18.5892, 13.9419, 22.9461, 23.9627],
        default_line_style,
    },{
        name:'HTC',
        type: 'line',
        data: [8.7137, 10.4564, 10.166, 6.2448, 4.6473],
        default_line_style
    }]
};

Update:

What if I just want to share it with only 2 series, not all of them? How can I do it?

Upvotes: 0

Views: 83

Answers (3)

Finrod
Finrod

Reputation: 2550

Yes, you can do it:

var default_line_option = {
    symbol: 'none',
    itemStyle: {
        normal: {
            color: 'rgb(165,165,165)'
        }
    },
    lineStyle: {
        normal: {
            width: 5,
        }
    }
};

var option = {
    series: [{
        name:'Others',
        type: 'line',
        data: [23.9627, 26.4315, 29.917, 27.5934, 26.8672],
        use_default_line_option: true
    }, {
        name:'Apple',
        type: 'line',
        data: [18.1535, 18.5892, 13.9419, 22.9461, 23.9627],
        use_default_line_option: true
    },{
        name:'HTC',
        type: 'line',
        data: [8.7137, 10.4564, 10.166, 6.2448, 4.6473],
        use_default_line_option: false
    }]
};

option.series = option.series.map(function(el) {
  // Add default options if needed
  if (el.use_default_line_option) {
    for (var attr in default_line_option) { el[attr] = default_line_option[attr]; }
  }
  // Remove use_default_line_option attributes
  delete el.use_default_line_option;
  return el;
});

JSFIDDLE

EDIT:

  • using map function to get a "one line" solution
  • use_default_line_option boolean to use default option or not

Upvotes: 2

void
void

Reputation: 36703

You create your non redundant JSON then just apply a little logic on it to achieve what you want.

defaullt_line_option ={
    symbol: 'none',
    itemStyle: {
        normal: {
            color: 'rgb(165,165,165)'
        }
    },
    lineStyle: {
        normal: {
            width: 5,
        }
    }
};

option = {
    series: [{
        name:'Others',
        type: 'line',
        data: [23.9627, 26.4315, 29.917, 27.5934, 26.8672],
        apply:true
    }, {
        name:'Apple',
        type: 'line',
        data: [18.1535, 18.5892, 13.9419, 22.9461, 23.9627],
        apply:true
    },{
        name:'HTC',
        type: 'line',
        data: [8.7137, 10.4564, 10.166, 6.2448, 4.6473]
    }]
};



option.series = option.series.map(function(el){
    var apply = el.hasOwnProperty("apply") && el.apply;
    delete el.apply;
    if(!apply)
       return el;

    for (var attrname in defaullt_line_option) { el[attrname] = defaullt_line_option[attrname]; }
    
   return el;
});

console.log(option);

UPDATE:

I have a apply key now, if it is present and is true then only the defaults will get applied, otherwise they wont. Dont forget to properly remove it afterwards.

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074495

Yes, you can have standard options you add in:

var standardOptions = {
    symbol: 'none',
    itemStyle: {
        normal: {
            color: 'rgb(165,165,165)'
        }
    },
    lineStyle: {
        normal: {
            width: 5,
            }
    }
};

And then just add them in with simple loop:

option.series.forEach(function(entry) {
    for (var name in standardOptions) {
        entry[name] = standardOptions[name];
    }
});

Note that that means the lineStyle and itemStyle objects will be shared by the various series entries.

Upvotes: 1

Related Questions