dc-js / dc.js

Multi-Dimensional charting built to work natively with crossfilter rendered with d3.js
Apache License 2.0
7.42k stars 1.8k forks source link

Composite Line chart X axis ticks not matching to Chart start and end #662

Open mylpk2004 opened 10 years ago

mylpk2004 commented 10 years ago

Please refer attached screen print. We have tried to achieve composite line chart for Ad data in our internal application.

compositelinechart

Can not post complete code this moment ...but seems if I try to draw just line charts it works but composite dont so.

Any quick solution or patch.

Chart Code as below :

// Chart 1 and chart 2

if ( i == 0) {
    compositeGroupArr[i] = eval('dc.lineChart(moveChart).group(groupArr[i], selectedArr['+i+']).title(function (d) { return ""; }).renderArea(true).colors(color['+i+'])');
}
else if( i == 1)
{
    compositeGroupArr[i] = eval('dc.lineChart(moveChart).group(groupArr[i], selectedArr['+i+']).title(function (d) { return ""; }).colors(color['+i+']).useRightYAxis(true)');
}

//Few settings 
if (validateDate == '1' && xAxisField == 'date' || xAxisField == 'time' ){                       

    xdate = eval("moveChart.x(d3.time.scale().domain([min, max])); moveChart.xUnits(d3.time.months);moveChart.round(d3.time.month.round).margins(graphMargins).height(height);");
}
else{
    xdate = eval("moveChart.x(d3.scale.ordinal().domain(OrdinalDomainArray));moveChart.xUnits(dc.units.ordinal).margins(graphMargins).height(height);");
}

//Properties of graph
tripVolume =    moveChart.width(graphWidth)
.transitionDuration(1000)
.dimension(XDimension)
.group(groupArr[0])
.xAxisLabel(xAxisField)
.yAxisLabel(label)
.rightYAxisLabel(labelRY)
.elasticY(true)
.elasticX(true)
.title(false)
.renderTitle(renderTitle)
.renderHorizontalGridLines(true)
//.renderVerticalGridLines(true)
.legend(dc.legend().x((graphWidth + 100)).y(4))
.brushOn(false)
.compose(compositeGroupArr)

moveChart.yAxis().tickFormat(function(d) {
var num = Number(d);
var FormatedNumber = getFormatedNumber(num);
return FormatedNumber;

})
//Right y axis
moveChart.rightYAxis().tickFormat(function(d) {
var num = Number(d);
var FormatedNumber = getFormatedNumber(num);
return FormatedNumber;

})
//moveChart.yAxis().tickValues([+d[yAxisFieldsBox]]);

moveChart.renderlet(function(chart){

    $("#dc_allinonediv-chart svg").attr("id" , "myId");
    $("#dc_allinonediv-chart svg").attr("xmlns" , "http://www.w3.org/2000/svg");
    $("#dc_allinonediv-chart svg").attr("xmlns:xlink" , "http://www.w3.org/1999/xlink");

    $("#myId g path.domain").attr("stroke", "#000000");
    //changing position of label on - axis      
    moveChart.selectAll("g .dc-tooltip path.xRef").style("stroke-opacity",0);
    moveChart.selectAll("g .dc-tooltip path.yRef").style("stroke-opacity",0);

    moveChart.selectAll("g.x text")
    // due to this property values are not seen on x-axis so commenting it
    //.attr("dx", "-14.8em")
    .attr("dy", "-0.10em")
    .attr("x", "-8")
    .attr('transform', "rotate(-55)")
    .style("text-anchor", "end")
.

});

Tried referring existing composite.html example but was not so successful.

ruhley commented 10 years ago

I am experiencing the same problem. I have narrowed it down to composite ordinal charts. I have used the line.html example.

Current Example

var chart = dc.lineChart("#test");
chart
    .width(768)
    .height(480)
    .x(d3.scale.linear().domain([0,20]))
    .interpolate('step-before')
    .renderArea(true)
    .brushOn(false)
    .renderDataPoints(true)
    .yAxisLabel("This is the Y Axis!")
    .dimension(runDimension)
    .group(speedSumGroup);

Ordinal chart = good

var chart = dc.lineChart("#test");
chart
    .width(768)
    .height(480)
    .x(d3.scale.ordinal())
    .xUnits(dc.units.ordinal)
    .interpolate('step-before')
    .renderArea(true)
    .brushOn(false)
    .renderDataPoints(true)
    .yAxisLabel("This is the Y Axis!")
    .dimension(runDimension)
    .group(speedSumGroup);

Composite chart = good

var chart = dc.compositeChart("#test");
chart
    .width(768)
    .height(480)
    .x(d3.scale.linear().domain([0,20]))
    .brushOn(false)
    .yAxisLabel("This is the Y Axis!")
    .dimension(runDimension)
    .group(speedSumGroup)
    .compose([
      dc.lineChart(chart)
      .interpolate('step-before')
      .renderArea(true)
      .renderDataPoints(true)
      .dimension(runDimension)
      .group(speedSumGroup)
    ]);

Composite AND ordinal = broken

var chart = dc.compositeChart("#test");
chart
    .width(768)
    .height(480)
    .x(d3.scale.ordinal())
    .xUnits(dc.units.ordinal)
    .brushOn(false)
    .yAxisLabel("This is the Y Axis!")
    .dimension(runDimension)
    .group(speedSumGroup)
    .compose([
      dc.lineChart(chart)
      .interpolate('step-before')
      .renderArea(true)
      .renderDataPoints(true)
      .dimension(runDimension)
      .group(speedSumGroup)
    ]);
ghost commented 9 years ago

This will be resolved in 2-3 months ?

gordonwoodhull commented 9 years ago

We're a volunteer project here. Patches are certainly welcome!

KoenDeMol commented 9 years ago

The problem is that composite charts doe not calculate the rangebands. There are 2 completely different ways on handling the gaps in d3, which I think should change.

A workarround for now is to add " ._rangeBandPadding(1) " when creating a compositeChart, so the rangeband is set manually.

So this would become:

var chart = dc.compositeChart("#test");
chart
    .width(768)
    .height(480)
    .x(d3.scale.ordinal())
    .xUnits(dc.units.ordinal)
    .brushOn(false)
    .yAxisLabel("This is the Y Axis!")
    .dimension(runDimension)
    .group(speedSumGroup)
     ._rangeBandPadding(1)
    .compose([
      dc.lineChart(chart)
      .interpolate('step-before')
      .renderArea(true)
      .renderDataPoints(true)
      .dimension(runDimension)
      .group(speedSumGroup)
    ]);

I know this is dirty, but for now the quickest way to solve your problem...

KoenDeMol commented 9 years ago

Ow .. and in addition .. since the bar width of a barChart is being calculated based on this padding you might have to correct this as well. If you are adding a barChart to the composite, just manually set the gap size for this barChart ( .gap(value) ) to fix the very small bars. And then again, this gap is not equally spread on left and right, so the bars are not centered anymore. Ufffff ... this code needs some reviewing ... For now, just make small gaps ;-)

gordonwoodhull commented 9 years ago

Also here:

http://stackoverflow.com/questions/33267147/dc-js-composite-chart-align-points-of-line-chart-in-center-of-bars

and here: http://stackoverflow.com/questions/30426356/align-points-in-centre-of-bars-dc-js-composite-chart

gordonwoodhull commented 9 years ago

The workaround proposed in the two SO answers (with fixed fiddles) is to set

        ._rangeBandPadding(1)

on the composite chart, and

        .gap(1)
        .centerBar(true)

on the child chart. Yes, this is range bands on the composite chart and classic gaps on the child chart. I'm not going to guess why this works.

ghost commented 8 years ago

How can we address this where we have two line charts are composed as composite chart?

RobertAnderson1870 commented 7 years ago

I have just run into this issue. Are there any updates?

At issue for me is that I have a series of 4 charts (1 scatterPlot, 2 lineCharts and 1 compositeChart) arranged vertically on the page. Each chart shares the same x-axis (time scale). The data on the compositeChart is misaligned when compared against corresponding data on the other charts. The work-arounds listed above don't work for me.

RobertAnderson1870 commented 7 years ago

Additionally, the y-Axis is also misaligned on the same compositeChart I mentioned previously.

gordonwoodhull commented 7 years ago

Can you create a fiddle demonstrating the problem?

RobertAnderson1870 commented 7 years ago

Sorry it took so long to respond back with a fiddle. In the fiddle, I've shown the first two charts in my page that sit one above the other (same x-axis). Didn't seem to make sense to get all 11 of my page's dc charts into the fiddle :-)

Not sure why the vertical and horizontal grid lines don't render in the fiddle, but the end point of the zeroline on the second chart should align exactly with the symbol on the chart above...as you will see, clearly it does not. Without the gridlines, it is also harder to see that the horiztontal zero line is also slighty below where zero should be.

https://jsfiddle.net/rander1870/409yoLbv/28/

I hope this helps in being able to offer some guidance. Much appreciated!