diff --git a/src/core-interfaces.ts b/src/core-interfaces.ts index df6c617a..d03c85d0 100644 --- a/src/core-interfaces.ts +++ b/src/core-interfaces.ts @@ -1173,6 +1173,14 @@ export interface OptsChartData { * @example [2000, 2010, 2020] */ values?: number[] + /** + * custom styles, e.g border + * @example [ + {border: {pt:'1', color:'ff0000'} }, + {border: {pt:'2', color:'000000'} } + ] + */ + styles?: object[] /** * Override `chartColors` */ diff --git a/src/gen-charts.ts b/src/gen-charts.ts index efe0c95e..1a97e54f 100644 --- a/src/gen-charts.ts +++ b/src/gen-charts.ts @@ -831,6 +831,7 @@ function makeChartType (chartType: CHART_NAME, data: IOptsChartData[], opts: ICh } ] */ + data.forEach(obj => { colorIndex++ strXml += '' @@ -900,7 +901,13 @@ function makeChartType (chartType: CHART_NAME, data: IOptsChartData[], opts: ICh if (opts.lineDataSymbolSize) strXml += `` // Defaults to "auto" otherwise (but this is usually too small, so there is a default) strXml += ' ' strXml += ` ${createColorElement(opts.chartColors[obj._dataIndex + 1 > opts.chartColors.length ? Math.floor(Math.random() * opts.chartColors.length) : obj._dataIndex])}` - strXml += ` ${createColorElement(opts.lineDataSymbolLineColor || seriesColor)}` + strXml += ` ` + strXml += ' ' + strXml += ` ${createColorElement(opts.lineDataSymbolLineColor || seriesColor)}` + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' strXml += ' ' strXml += ' ' strXml += '' @@ -988,7 +995,66 @@ function makeChartType (chartType: CHART_NAME, data: IOptsChartData[], opts: ICh // Option: `smooth` if (chartType === CHART_TYPE.LINE) strXml += '' - // 4: Close "SERIES" + /* EX: + data: [ + { + name: 'Project Status', + labels: ['Red', 'On Hold', 'Green', 'Unknown'], + values: [10, 20, 38, 2] + styles: [ + {border: {pt: 2, color: '#ff0000'}} + {} + {border: {pt: 2, color: '#00ff00'}} + {} + ] + } + ] + */ + // 4: data point "Styles" + if (obj.styles) { + obj.styles.forEach((style: any, idx) => { + if (style !== undefined && style !== null) { + const borderStyle = 'border' in style ? style.border : {} + if (chartType === CHART_TYPE.BAR) { + strXml += '' + strXml += ` ` + strXml += ' ' + strXml += ' ' + strXml += ` ${createColorElement(seriesColor)}` + strXml += ' ' + strXml += ` ` + strXml += ' ' + strXml += ` ${createColorElement(borderStyle && 'color' in borderStyle ? borderStyle.color : seriesColor)}` + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += '' + } else if (chartType === CHART_TYPE.LINE || chartType === CHART_TYPE.AREA) { + strXml += '' + strXml += ` ` + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ` ${createColorElement(seriesColor)}` + strXml += ' ' + strXml += ` ` + strXml += ' ' + strXml += ` ${createColorElement(borderStyle && 'color' in borderStyle ? borderStyle.color : seriesColor)}` + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += '' + } + } + }) + } + + // 5: Close "SERIES" strXml += '' }) @@ -1288,6 +1354,35 @@ function makeChartType (chartType: CHART_NAME, data: IOptsChartData[], opts: ICh // Option: `smooth` strXml += '' + if (obj.styles) { + obj.styles.forEach((style: any, idx) => { + if (style !== undefined && style !== null) { + const color = opts.chartColors[colorIndex % opts.chartColors.length] + const borderStyle = 'border' in style ? style.border : {} + + strXml += '' + strXml += ` ` + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ` ${createColorElement(color)}` + strXml += ' ' + strXml += ` ` + strXml += ' ' + strXml += ` ${createColorElement('color' in borderStyle ? borderStyle.color : color)}` + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += ' ' + strXml += '' + } + }) + } + // 4: Close "SERIES" strXml += '' }) @@ -1481,7 +1576,6 @@ function makeChartType (chartType: CHART_NAME, data: IOptsChartData[], opts: ICh case CHART_TYPE.PIE: // Use the same let name so code blocks from barChart are interchangeable optsChartData = data[0] - /* EX: data: [ { @@ -1520,16 +1614,25 @@ function makeChartType (chartType: CHART_NAME, data: IOptsChartData[], opts: ICh // 2: "Data Point" block for every data row optsChartData.labels[0].forEach((_label, idx) => { + const color = opts.chartColors[idx + 1 > opts.chartColors.length ? Math.floor(Math.random() * opts.chartColors.length) : idx] + + const style = optsChartData?.styles?.[idx] ?? {} + + const borderStyle = 'border' in style + ? style.border as {pt, color} + : opts.dataBorder ? opts.dataBorder : {} + + const explosion = 'pt' in borderStyle ? borderStyle.pt : 0 + strXml += '' strXml += ` ` + strXml += ` ` strXml += ' ' strXml += ' ' - strXml += `${createColorElement( - opts.chartColors[idx + 1 > opts.chartColors.length ? Math.floor(Math.random() * opts.chartColors.length) : idx] - )}` - if (opts.dataBorder) { - strXml += `${createColorElement( - opts.dataBorder.color + strXml += `${createColorElement(color)}` + if (borderStyle) { + strXml += `${createColorElement( + borderStyle.color )}` } strXml += createShadowElement(opts.shadow, DEF_SHAPE_SHADOW)