'All Histogram get same rgb colour
i am trying draw multiple histogram with different colour scale of rgb colour in loop but first histogram colour scale applied to all remain histograms. after change first histogram rgb range using handles update both histogram, but second histogram handle change wont affect on range code like follow
rgb color array
let colorsMap = [
[165, 0, 38, 255],
[166, 1, 38, 255],
[168, 3, 38, 255],
[170, 5, 38, 255],
[172, 7, 38, 255],
[174, 9, 38, 255],
[176, 11, 38, 255],
[178, 13, 38, 255],
[180, 15, 38, 255],
[182, 16, 38, 255],
[184, 18, 38, 255],
[186, 20, 38, 255],
[188, 22, 38, 255],
[190, 24, 38, 255],
[192, 26, 38, 255],
[194, 28, 38, 255],
[196, 30, 38, 255],
[198, 32, 38, 255],
[200, 33, 38, 255],
[202, 35, 38, 255],
[204, 37, 38, 255],
[206, 39, 38, 255],
[208, 41, 38, 255],
[210, 43, 38, 255],
[212, 45, 38, 255],
[214, 47, 38, 255],
[215, 49, 39, 255],
[216, 51, 40, 255],
[217, 53, 41, 255],
[218, 56, 42, 255],
[220, 58, 43, 255],
[221, 61, 45, 255],
[222, 63, 46, 255],
[223, 65, 47, 255],
[224, 68, 48, 255],
[225, 70, 49, 255],
[226, 73, 50, 255],
[228, 75, 51, 255],
[229, 77, 52, 255],
[230, 80, 53, 255],
[231, 82, 54, 255],
[232, 85, 56, 255],
[233, 87, 57, 255],
[234, 89, 58, 255],
[236, 92, 59, 255],
[237, 94, 60, 255],
[238, 97, 61, 255],
[239, 99, 62, 255],
[240, 101, 63, 255],
[241, 104, 64, 255],
[242, 106, 65, 255],
[244, 109, 67, 255],
[244, 111, 68, 255],
[244, 114, 69, 255],
[245, 116, 70, 255],
[245, 119, 71, 255],
[245, 121, 72, 255],
[246, 124, 74, 255],
[246, 126, 75, 255],
[246, 129, 76, 255],
[247, 131, 77, 255],
[247, 134, 78, 255],
[247, 137, 79, 255],
[248, 139, 81, 255],
[248, 142, 82, 255],
[248, 144, 83, 255],
[249, 147, 84, 255],
[249, 149, 85, 255],
[250, 152, 86, 255],
[250, 154, 88, 255],
[250, 157, 89, 255],
[251, 159, 90, 255],
[251, 162, 91, 255],
[251, 165, 92, 255],
[252, 167, 94, 255],
[252, 170, 95, 255],
[252, 172, 96, 255],
[253, 174, 97, 255],
[253, 176, 99, 255],
[253, 178, 101, 255],
[253, 180, 102, 255],
[253, 182, 104, 255],
[253, 184, 106, 255],
[253, 186, 107, 255],
[253, 188, 109, 255],
[253, 190, 110, 255],
[253, 192, 112, 255],
[253, 194, 114, 255],
[253, 196, 115, 255],
[253, 198, 117, 255],
[253, 200, 119, 255],
[253, 202, 120, 255],
[253, 204, 122, 255],
[253, 206, 124, 255],
[253, 208, 125, 255],
[253, 210, 127, 255],
[253, 212, 129, 255],
[253, 214, 130, 255],
[253, 216, 132, 255],
[253, 218, 134, 255],
[253, 220, 135, 255],
[253, 222, 137, 255],
[254, 224, 139, 255],
[254, 225, 141, 255],
[254, 226, 143, 255],
[254, 227, 145, 255],
[254, 228, 147, 255],
[254, 230, 149, 255],
[254, 231, 151, 255],
[254, 232, 153, 255],
[254, 233, 155, 255],
[254, 234, 157, 255],
[254, 236, 159, 255],
[254, 237, 161, 255],
[254, 238, 163, 255],
[254, 239, 165, 255],
[254, 241, 167, 255],
[254, 242, 169, 255],
[254, 243, 171, 255],
[254, 244, 173, 255],
[254, 245, 175, 255],
[254, 247, 177, 255],
[254, 248, 179, 255],
[254, 249, 181, 255],
[254, 250, 183, 255],
[254, 251, 185, 255],
[254, 253, 187, 255],
[254, 254, 189, 255],
[254, 254, 189, 255],
[252, 254, 187, 255],
[251, 253, 185, 255],
[249, 252, 183, 255],
[248, 252, 181, 255],
[246, 251, 179, 255],
[245, 250, 177, 255],
[243, 250, 175, 255],
[242, 249, 173, 255],
[240, 249, 171, 255],
[239, 248, 169, 255],
[237, 247, 167, 255],
[236, 247, 165, 255],
[234, 246, 163, 255],
[233, 245, 161, 255],
[231, 245, 159, 255],
[230, 244, 157, 255],
[228, 244, 155, 255],
[227, 243, 153, 255],
[225, 242, 151, 255],
[224, 242, 149, 255],
[222, 241, 147, 255],
[221, 240, 145, 255],
[219, 240, 143, 255],
[218, 239, 141, 255],
[217, 239, 139, 255],
[215, 238, 137, 255],
[213, 237, 136, 255],
[211, 236, 135, 255],
[209, 235, 133, 255],
[207, 234, 132, 255],
[205, 233, 131, 255],
[203, 232, 129, 255],
[201, 232, 128, 255],
[199, 231, 127, 255],
[197, 230, 126, 255],
[195, 229, 124, 255],
[193, 228, 123, 255],
[191, 227, 122, 255],
[189, 226, 120, 255],
[187, 226, 119, 255],
[185, 225, 118, 255],
[183, 224, 117, 255],
[181, 223, 115, 255],
[179, 222, 114, 255],
[177, 221, 113, 255],
[175, 220, 111, 255],
[173, 220, 110, 255],
[171, 219, 109, 255],
[169, 218, 107, 255],
[167, 217, 106, 255],
[164, 216, 105, 255],
[162, 215, 105, 255],
[159, 214, 105, 255],
[157, 213, 105, 255],
[154, 212, 104, 255],
[152, 210, 104, 255],
[149, 209, 104, 255],
[147, 208, 103, 255],
[144, 207, 103, 255],
[142, 206, 103, 255],
[139, 205, 103, 255],
[137, 204, 102, 255],
[134, 203, 102, 255],
[132, 202, 102, 255],
[129, 201, 102, 255],
[127, 199, 101, 255],
[124, 198, 101, 255],
[122, 197, 101, 255],
[119, 196, 100, 255],
[117, 195, 100, 255],
[114, 194, 100, 255],
[112, 193, 100, 255],
[109, 192, 99, 255],
[107, 191, 99, 255],
[104, 190, 99, 255],
[102, 189, 99, 255],
[99, 187, 98, 255],
[96, 186, 97, 255],
[93, 184, 96, 255],
[90, 183, 96, 255],
[87, 181, 95, 255],
[84, 180, 94, 255],
[81, 178, 93, 255],
[78, 177, 93, 255],
[75, 175, 92, 255],
[72, 174, 91, 255],
[69, 173, 90, 255],
[66, 171, 90, 255],
[63, 170, 89, 255],
[60, 168, 88, 255],
[57, 167, 87, 255],
[54, 165, 87, 255],
[51, 164, 86, 255],
[48, 162, 85, 255],
[45, 161, 84, 255],
[42, 159, 84, 255],
[39, 158, 83, 255],
[36, 157, 82, 255],
[33, 155, 81, 255],
[30, 154, 81, 255],
[27, 152, 80, 255],
[25, 151, 79, 255],
[24, 149, 78, 255],
[23, 147, 77, 255],
[22, 145, 76, 255],
[21, 143, 75, 255],
[20, 141, 74, 255],
[19, 139, 73, 255],
[18, 137, 72, 255],
[17, 136, 71, 255],
[16, 134, 70, 255],
[15, 132, 69, 255],
[14, 130, 68, 255],
[13, 128, 67, 255],
[12, 126, 66, 255],
[11, 124, 65, 255],
[10, 122, 64, 255],
[9, 120, 63, 255],
[8, 119, 62, 255],
[7, 117, 61, 255],
[6, 115, 60, 255],
[5, 113, 59, 255],
[4, 111, 58, 255],
[3, 109, 57, 255],
[2, 107, 56, 255],
[1, 105, 55, 255],
[0, 104, 55, 255]
];
histogram min-max array
let results: [
{
max: "0.586"
min: "-0.1429"
statistics:
1:histogram: (2) [Array(255), Array(256)]
max: 0.5862068965517241
min: -0.3333333333333333
percentiles: (2) [-0.14285714285714285, 0.044534412955465584]
std: 0.041693440775719376
valid_percent: 56.69100747804611
},
{
max: "-0.177"
min: "-0.333"
statistics:
1:histogram: (2) [Array(255), Array(256)]
max: 0.5862068965517241
min: -0.3333333333333333
percentiles: (2) [-0.14285714285714285, 0.044534412955465584]
std: 0.041693440775719376
valid_percent: 56.69100747804611
},
]
passing to histogram component like
results.map((result) =>{
return (
<Histogram width = {180}
statistics={report.statistics}
colorMap={colorsMap}
initialMin={report.min}
initialMax={report.max}>);
})
Histogram component like follow
import React from 'react';
import PropTypes from 'prop-types';
import './Histogram.scss';
import d3, { color, fcumsum } from 'd3';
import { _ } from './gettext';
export default class HistogramCustom extends React.Component {
static defaultProps = {
width: 280,
colorMap: null,
onUpdate: null,
loading: false,
};
static propTypes = {
statistics: PropTypes.object.isRequired,
colorMap: PropTypes.array,
width: PropTypes.number,
onUpdate: PropTypes.func,
loading: PropTypes.bool
}
constructor(props) {
super(props);
// Colors in absence of a color map
this.defaultBandColors = [
'#ff0000',
'#00ff00',
'#0000ff',
'#ff8000',
'#ffff00',
'#00ff80',
'#00ffff',
'#0080ff',
];
this.reset();
}
reset = () => {
const minY = 0;
let maxY = 0;
let minX = 2147483647;
let maxX = -2147483646;
for (let i in this.props.statistics) {
const band = this.props.statistics[i];
minX = Math.min(minX, band.min);
maxX = Math.max(maxX, band.max);
// let xw = (this.props.min - maxY)/(this.props.max - maxY)
maxY = Math.max(maxY, Math.max(...band.histogram[0]));
}
this.rangeX = [minX, maxX];
this.rangeY = [minY, maxY];
const st = {
min: this.props.initialMin,
max: this.props.initialMax
};
if (!this.state) {
this.state = st;
} else {
this.setState(st);
}
}
redraw = () => {
let margin = { top: 5, right: 10, bottom: 15, left: 10 },
width = this.props.width - margin.left - margin.right,
height = 85 - margin.top - margin.bottom;
let hgContainer = document.getElementById('body')
// if (this.hgContainer.firstElementChild) {
// this.hgContainer.removeChild(this.hgContainer.firstElementChild);
// }
const svgContainer = d3.select(this.hgContainer)
.append("svg")
.attr('class', 'histogram-container')
.attr('x',function(d,i){
// get y coord
console.log(this)
})
.attr("width", width + margin.left + margin.right)
.attr("height", this.props.histogramUnavailable ? 30 : height + margin.top + margin.bottom);
if (this.props.colorMap) {
this.colorMapElem = svgContainer.append("defs")
.append("linearGradient")
.attr('id', 'linear')
.attr('x1', '0%')
.attr('y1', '0%')
.attr('x2', '100%')
.attr('y2', '0%');
this.updateColorMap(true);
}
let svg = svgContainer.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// add the x Axis
let x = d3.scale.linear()
.domain(this.rangeX)
.range([0, width]);
svg.append("g")
.attr("class", "x axis theme-fill-primary")
.attr("transform", "translate(0," + (height - 5) + ")")
.call(d3.svg.axis().scale(x).tickValues(this.rangeX).orient("bottom"));
// add the y Axis
// let mm = d3.min()
let y = d3.scale.linear()
.domain(this.rangeY)
.range([height, 0]);
for (let i in this.props.statistics) {
const band = this.props.statistics[i];
const data = band.histogram[0].map((e, i) => {
return [band.histogram[1][i], e];
});
// Make sure histogram starts and ends at 0
// to prevent oblique looking charts
data.unshift([data[0][0], 0]);
data.push([data[data.length - 1][0], 0]);
// Plot the area
svg.append('g')
.append("path")
.datum(data)
.attr("fill", !this.colorMapElem ? this.defaultBandColors[i - 1] : 'url(#linear)')
.attr("opacity", 1 / Object.keys(this.props.statistics).length)
.attr("d", d3.svg.line()
.x(function (d) { return x(d[0]); })
.y(function (d) { return y(d[1]); })
);
}
// Add sliders
this.maxDown = false;
this.minDown = false;
let maxPosX = null;
let minPosX = null;
const minXStart = ((this.state.min - this.rangeX[0]) / (this.rangeX[1] - this.rangeX[0])) * width;
const minLine = svg.append('g')
.append('line')
.attr('x1', minXStart)
.attr('y1', 0)
.attr('x2', minXStart)
.attr('y2', height)
.attr('class', 'theme-stroke-primary slider-line min')
.on("mousedown", function () { self.maxDown = false; self.minDown = true; })[0][0];
const maxXStart = ((this.state.max - this.rangeX[0]) / (this.rangeX[1] - this.rangeX[0])) * width;
const maxLine = svg.append('g')
.append('line')
.attr('x1', maxXStart)
.attr('y1', 0)
.attr('x2', maxXStart)
.attr('y2', height)
.attr('class', 'theme-stroke-primary slider-line max')
.on("mousedown", function () { self.minDown = false; self.maxDown = true; })[0][0];
const handleLeave = () => {
this.maxDown = this.minDown = false;
maxPosX = null;
minPosX = null;
};
const self = this;
const handleMoveMax = function () {
if (self.maxDown) {
const mouseX = (d3.mouse(this))[0];
if (!maxPosX) maxPosX = mouseX;
const deltaX = mouseX - maxPosX;
const prevX = parseInt(maxLine.getAttribute('x1'));
const newX = Math.max(Math.min(width, prevX + deltaX), parseInt(minLine.getAttribute('x1')));
maxPosX = mouseX;
maxLine.setAttribute('x1', newX);
maxLine.setAttribute('x2', newX);
if (prevX !== newX) {
self.setState({ max: (self.rangeX[0] + ((self.rangeX[1] - self.rangeX[0]) / width) * newX).toFixed(3) });
}
}
};
const handleMoveMin = function () {
if (self.minDown) {
console.log(d3)
console.log(d3.color)
console.log(d3.color.arguments)
const mouseX = (d3.mouse(this))[0];
if (!minPosX) minPosX = mouseX;
const deltaX = mouseX - minPosX;
const prevX = parseInt(minLine.getAttribute('x1'));
const newX = Math.max(0, Math.min(prevX + deltaX, parseInt(maxLine.getAttribute('x1'))));
minPosX = mouseX;
minLine.setAttribute('x1', newX);
minLine.setAttribute('x2', newX);
if (prevX !== newX) {
self.setState({ min: (self.rangeX[0] + ((self.rangeX[1] - self.rangeX[0]) / width) * newX).toFixed(3) });
}
}
};
svgContainer
.on("mousemove", function () {
handleMoveMax.apply(this);
handleMoveMin.apply(this);
})
.on("mouseup", handleLeave)
.on("mouseleave", handleLeave)
.on("mousedown", function () {
const mouseX = (d3.mouse(this))[0];
const maxBarX = parseInt(maxLine.getAttribute('x1')) + margin.right;
const minBarX = parseInt(minLine.getAttribute('x1')) + margin.right;
// Move bar closest to click
if (Math.abs(mouseX - maxBarX) < Math.abs(mouseX - minBarX)) {
self.maxDown = true;
maxPosX = parseInt(maxLine.getAttribute('x1')) + margin.right;
handleMoveMax.apply(this);
} else {
self.minDown = true;
minPosX = parseInt(minLine.getAttribute('x1')) + margin.right;
handleMoveMin.apply(this);
}
});
}
componentDidMount() {
this.redraw();
}
componentDidUpdate(prevProps, prevState) {
if (prevState.min !== this.state.min ||
prevState.max !== this.state.max ||
prevProps.colorMap !== this.props.colorMap ||
prevProps.statistics !== this.props.statistics) {
if (prevProps.statistics !== this.props.statistics) this.reset();
if (!this.maxDown && !this.minDown) this.redraw();
this.updateColorMap(prevProps.colorMap !== this.props.colorMap);
if (this.props.onUpdate !== undefined) this.props.onUpdate({ min: this.state.min, max: this.state.max });
}
}
updateColorMap = (recreate) => {
if (!this.colorMapElem) return;
if (recreate) {
this.colorMapElem.select("stop").remove();
this.props.colorMap.forEach((color, i) => {
this.colorMapElem.append("stop")
.attr('offset', `${(i / (this.props.colorMap.length - 1)) * 100.0}%`)
.attr('stop-color', `rgb(${color.join(",")})`);
});
}
const { min, max } = this.state;
const minPerc = Math.abs(min - this.rangeX[0]) / (this.rangeX[1] - this.rangeX[0]) * 100.0;
const maxPerc = Math.abs(max - this.rangeX[0]) / (this.rangeX[1] - this.rangeX[0]) * 100.0;
this.colorMapElem.attr('x1', `${minPerc}%`)
.attr('x2', `${maxPerc}%`);
}
output getting like
first histogram shows red colour
and second shows green but its same colour of histogram

Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|

