커스텀 렌더러(바)
커스텀 렌더러를 사용해서 가로방향의 바 형태를 표현할 수 있습니다.
"단위" 컬럼에 커스텀 렌더러를 적용해서 가로 방향으로 렌더러가 다른 컬럼에 넘어가 가서 표현되도록 구현한 예제입니다.
참고사항
- 커스텀렌더러를 사용한다는 것은 그리드의 기능을 사용하지 않고 직접 개발자분이 컨트롤을 한다는 의미입니다. 그렇기 때문에 기본적으로 기술지원영역은 아닙니다.
- 하지만 작성하신 코드가 문제가 되는 경우 반드시 실행가능한 소스 코드를 보내주셔야
기술지원
이 가능합니다. - 커스텀 렌더러는 view 용도로 개발되었으며, 입력용도로는 적합하지 않습니다.
- 외부 컴포넌트를 사용하여 전체를 그릴수있도록 고려해서 개발되지 않았기 때문에 행 높이보다 큰 영역을 그린다면 문제가 있을 수 있습니다.
//mineral 광물컬럼
gridView.registerCustomRenderer("mineral", {
initContent : function (dom) {
let css = dom.style;
css.display = "flex";
css.flexDirection = "row";
css.marginRight = "5px";
css.alignItems = "center";
const textSpan = this._textSpan = document.createElement("span");
css = textSpan.style;
css.flex = "1 1 20px";
const colorSpan = this._colorSpan = document.createElement("span");
colorSpan.classList.add("dot");
css = colorSpan.style;
css.flex = "0 0 10px";
dom.appendChild(this._textSpan);
dom.appendChild(this._colorSpan);
},
canClick : function() {
return true;
},
clearContent : function(dom) {
},
render : function(grid, model, width, height, info) {
const itemIndex = model.item.index
const mineral = grid.getValue(itemIndex, "mineral");
this._textSpan.textContent = mineral;
this._colorSpan.style.backgroundColor = colorCode[mineral];
},
click : function(event) {
}
});
//unit 단위컬럼
gridView.registerCustomRenderer("mineralBar", {
initContent : function (dom) {
this._dom = dom;
let css = dom.style;
css.display = "flex";
css.height = "21px";
css.alignItems = "center";
dom.style.removeProperty("overflow");
const svg = this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
css = svg.style;
css.position = "absolute";
dom.appendChild(svg);
const text = this.textSpan = document.createElement("span");
css = text.style;
css.flex = "1 1 20px";
css.position = "relative";
dom.appendChild(text);
},
canClick : function() {
return true;
},
clearContent : function(dom) {
dom.removeChild(this.svg);
},
render : function(grid, model, colWidth, height, info) {
const svg = this.svg;
const widths = grid._view.activeCellLayout._cellWidths;
let width = widths.reduce( (a, b) => a + b, 0);
width -= (grid.layoutByName("mineral").cellWidth + grid.layoutByName("합계").cellWidth);
svg.setAttribute("width", `${width}`);
svg.setAttribute("height", "16");
svg.setAttribute("viewBox", `0 0 ${width} 16`)
this.textSpan.textContent = model.value;
const ds = grid.getDataSource();
const mineral = ds.getValue(model.index.dataRow, "mineral")
const color = colorCode[mineral] || "silver";
const volume = ds.getValue(model.index.dataRow, "합계") || 0;
if (volume <= 0) {
this.svg.innerHTML = "";
} else if (volume <= 600000) {
let barWidth = (volume / 500000) * 0.7 * width;
this.svg.innerHTML = `<path d="M0 0 H${barWidth} A8 8 0 0 1 ${barWidth} 16 H0 Z" fill=${color} />`;
} else {
let barWidth = Math.min( 0.7 * width + (((volume - 500000) / 3000000) * width), width - 10);
let str = `
<defs>
<!-- 마스크 정의: 전체는 보이게, 번개 선은 가리기 -->
<mask id="mask-transparent-stroke">
<!-- 전체 흰색 (보임) -->
<rect width=${width} height="16" fill="white" />
<!-- 번개 선 부분은 검정색 (가려짐 = 투명) -->
<path d="M700 0 L695 5 L700 10 L695 15" stroke="black" stroke-width="2" fill="none" />
</mask>
</defs>
<path d="M0 0 H${barWidth} A8 8 0 0 1 ${barWidth} 16 H0 Z" fill=${color} mask="url(#mask-transparent-stroke)"/>`;
this.svg.innerHTML = str;
}
},
click : function(event) {
}
});
gridView.columnByName("mineral").renderer = "mineral";
gridView.columnByName("unit").renderer = "mineralBar";